Jason Haley

Ramblings from an Independent Consultant

Talk: Securing Your Web Application in Azure with a WAF

Last night I spoke at the Boston Azure User Group. The slides are available here: Securing Your Web Application in Azure with a WAF

As I mentioned last night, this is the first edition of the talk, I plan on giving it to my user group next month (October) and again at the Boston Code Camp in November – so if you have any feedback please let me know I’d love to improve the content.

I want to work more demos into the presentation next time … and of course get them all to work (1 demo didn’t work last night).

Here are some of the useful links mentioned last night:

Next time for the demos I’m going to look at using the OWASP Juice Shop webapp

Talk: Design Azure Web Apps and Mobile Apps

Wednesday and Thursday of this week (Sept 27 – 28) I helped out with the second round of 70-534 Architecting Azure Solutions Event in NYC (the Boston event was Sept 14 - 15).  Microsoft is organizing these events in many cities currently in the mid-west and east coast.

My talk was on Web and Mobile Apps.  There were about 40 – 50 people in the room and around 200 on the simulcast.

BTW: if you are interested in having an event streamed you should check out Nelco Media.

One of the links I mentioned for people who are studying for the exam: Exam prep for Architecting Microsoft Azure Solutions, 70-534 it has the exam OD’s linked to the corresponding landing area in the Azure documents.

My presentation can be downloaded on github here and here are links to the labs for the Web Apps and the Mobile Apps

Azure Help: Traffic Manager–PowerShell Script to Add Traffic Manager Probe IP Addresses

If you are using Traffic Manager to route traffic between two data centers and the endpoints are inside of a VNET, you’ll need to add network security group rules for Traffic Manager’s probe IP Addresses or your endpoints will always show as degraded.


Once you think of the purpose of the probe … then it makes total sense why the endpoint shows as being “Degraded” – if traffic manager can’t get to the endpoint then it can’t make a decision of whether it should send traffic to it or not.

So in order to fix the, you need to add the Traffic Manager probe IP Addresses to the inbound NSG rules of you VNET.  That is simple to do in the portal (or via PowerShell) but – there are 23 of them!  Who really wants to manually enter 23 of them? … and don’t forget there are 2 data centers, so that is really 46 of them.

I certainly don’t enjoy entering that many NSG rules (even though it is easy) – so I created a script to do it.

In my case, I had east and west coast data center locations.  You’ll need to plug in your subscription, resource groups, nsg names and maybe change the probe port and the number to start the priority at (I have 150 – 173).

You should also verify the IP Addresses have not changed from the listing on this page: https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs under the question “What are the IP addresses from which the health checks originate?” about 3/4 the way down the page.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/TrafficManager/AddTrafficManagerProbeRules.ps1

#Verify latest Probe IP Addresses at https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs

$subscriptionId = "YourSubscriptionId"
$resourceGroupEast = "EastCoastResourceGroup"
$resourceGroupWest = "WestCostResourceGroup"
$nsgEast = "EastCoastNSG"
$nsgWest = "WestCoastNSG"
$probePort = 80 
$rulePriorityStart = 150
$rulePriority = $rulePriorityStart

$trafficManagerProbeIPs = @("",`
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `


Set-AzureRmContext -SubscriptionId $subscriptionId

$groupEast = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupEast `
     -Name $nsgEast
$groupWest = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupWest `
     -Name $nsgWest

For($i=0; $i -lt $trafficManagerProbeIPs.Length; $i++) {
    $ruleName = "Inbound-TMProbe" + $i.ToString() + "-Https-Allow"

    $rulePriority = $rulePriorityStart + $i

    $groupEast | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort

    $groupWest | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort
$groupEast | Set-AzureRmNetworkSecurityGroup
$groupWest | Set-AzureRmNetworkSecurityGroup

This script has saved me a lot of time.


Traffic Manager routing methods

Traffic Manager Frequently Asked Questions (FAQ)

Manage network security groups using PowerShell

Create network security groups using PowerShell

Add/Set/Remove NSG rules in ARM mode Azure Powershell

Azure Help: WebApps–Copying and Exporting Connection Strings and App Settings

When you create a WebApp in Azure’s App Service, you get a couple of important features with Application Settings:

  1. The ability for your developers not know the production app settings or connection strings values … or just the option to develop with settings that are not used once deployed (such as working with a local database)
  2. The ability to override values in the web.config that is deployed with the application

The first item is important for security reasons.  It makes it possible to control access to the production credentials.  The second item is really useful for changing settings for different environments – such as a staging db for a staging slot and a production db for the production slot.

I am a big fan of using Application Settings in my WebApps.

If you are not familiar with them, just look for the Application Settings menu item in your Web App (shown below).  The App settings and Connection strings sections are what I want to discuss below.


I’ve included some reference links at the bottom of this entry for you to learn more (if you are interested).

Problem 1:  Get a list of all the App Settings and/or Connection Strings of a deployed WebApp

The Azure portal will allow you to view all the settings, but sometimes you need the values for several app settings and/or connection strings – so viewing the values in the portal isn’t enough.

To solve this problem, I have created a PowerShell script that exports the values to two csv files (if I want both AppSettings and ConnectionString).  Usually it is just the AppSettings that I need, but you never know.

The source code can be found here:https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/ExportConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$webAppsource = "<source web app name>"
$slotSource = "<source slot>"

$appSettingsFileName = "appSettings.csv"
$connectionStringsFileName = "connectionStrings.csv"


Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
   -Name $webAppsource -Slot $slotSource

# Create csv files if file names are set
If ($appSettingsFileName -ne "") {
    $webAppsource.SiteConfig.AppSettings | Select-Object -Property Name, Value | `
       Export-Csv -Path $appSettingsFileName -NoTypeInformation

If ($connectionStringsFileName -ne "") {
    $webAppsource.SiteConfig.ConnectionStrings | Select-Object -Property Name, Type, `
ConnectionString | Export-Csv -Path $connectionStringsFileName -NoTypeInformation }

The generated csv files look like this:


Problem 2:  Copy all the App Settings and/or Connection Strings to another WebApp

Once in awhile I need to move WebApps from one place to another or lately I’ve been upgrading clients from ASEv1 instances to ASEv2 instances – which means a new build of an environment (not an upgrade).  ASE stands for App Service Environment.

If I already have the values of the AppSettings and ConnectionStrings in a deployed WebApp … it would be nice to copy the values to the new one and not have to enter them one-by-one.

The important thing to note: AppSettings and ConnectionStrings are not in source control (unless you have complete ARM templates stored … which you wouldn’t want your secrets in – so that complicates matters) … so deploying the latest code to the new WebApp is only part of the solution of spinning up a new environment.

To solve this problem, I have created a PowerShell script that will copy over all the AppSettings and/or ConnectionStrings of one WebApp to another WebApp.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/CopyConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$resourceGroupTarget = "<target resource group>"

$webAppsource = "<source web app name>"
$webAppTarget = "<target web app name>"

$slotSource = "<source slot>"
$slotTarget = "<target slot>"


Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
    -Name $webAppsource -Slot $slotSource

# Get reference to the source Connection Strings
$connectionStringsSource = $webAppSource.SiteConfig.ConnectionStrings

# Create Hash variable for Connection Strings
$connectionStringsTarget = @{}

# Copy over all Existing Connection Strings to the Hash
ForEach($connStringSource in $connectionStringsSource) {
    $connectionStringsTarget[$connStringSource.Name] = `
         @{ Type = $connStringSource.Type.ToString(); `
            Value = $connStringSource.ConnectionString }

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
    -Slot $slotTarget -ConnectionStrings $connectionStringsTarget

# Get reference to the source app settings
$appSettingsSource = $webAppSource.SiteConfig.AppSettings

# Create Hash variable for App Settings
$appSettingsTarget = @{}

# Copy over all Existing App Settings to the Hash
ForEach ($appSettingSource in $appSettingsSource) {
    $appSettingsTarget[$appSettingSource.Name] = $appSettingSource.Value

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
   -Slot $slotTarget -AppSettings $appSettingsTarget

These two scripts save me a lot of time due to the reality of there being several AppSettings that I need to work with (when I need to work with them).


Using App Settings in Azure Web Apps

Windows Azure Web Sites: How Application Strings and Connection Strings Work

Azure App Service Web Config Vs Application Settings

Easily Manage Azure Web App Connection Strings using PowerShell

Using Powershell to manage Azure Web App Deployment Slots

Azure Help Series

Today I’m starting a new series of blog entries – Azure Help.  There are many people who do “Tips and Tricks” and “Lessons Learned”, which I like and find useful – the idea with this series is the same, but I needed to come up with a unique name.

I want to cover real scenarios and lessons I’ve learned the past 5 or so years in using Azure on a day to day basis.

Entry List

This is a list of the blog entries I have for Azure Help.

Idea List

This is a list of ideas that I’m planning future entries about:

  • WebApps – Maintenance and Logging
  • Cloud Services – Using VSTS Release Management to Change ConfigurationSettings
  • VSTS - Add and Remove NSG to Publish a Release to VNet in Azure

Source Code

AzureHelp - a repo for code used in these Azure Help entries.


Do you have a suggestion for future a future entry?  If so, feel free to email or tweet me your idea … as long as it makes sense, chances are good it will make it on the list Smile

Ways to get involved in the local tech community (5 of 5)

Help grow the community

The local tech community is made of the people in it and the value they provide for each other.  The community isn’t just user group leaders, speakers and volunteers.  In fact, the majority of the community are individuals trying to learn, teach, socialize and help others.

With that in mind, here are some ways for you to help grow and make the community stronger (ie. more valuable) for everyone.

Attend User Groups and Be Part of the Group

I think it is obvious, but by attending user groups you have a chance to personally interact with others in the community. 
Most groups have some networking/socializing time before or after the main event.  Use this time to talk to at least one new person you don’t know.  If you already know everyone there then maybe you could bring someone with you next time and introduce them.  The idea is the more people know each other in the community the more value everyone gets from it.

Once the main presentation starts, ask questions, be present.  Often times, if you have a question – chances are someone else would also like to know … so go ahead and ask.  The more interactive the group is the more value people will get from it.  Sometimes the small tangent a speaker takes to answer a question is the most valuable part of the talk.

Provide Feedback to Leaders and Speakers

For any event or presentation, I think everyone can provide value by providing honest feedback on the event.  For the leaders/organizers it will help with planning future events.  For speakers, honest feedback is always hard to come by and I don’t know a single speaker who wouldn’t like to get some feedback on their presentation.
If you don’t feel comfortable giving feedback, try suggesting topics or speakers for future events that you would be interested in.

Continue the Conversation

Once a user group meeting is over, you can still carry on the conversation.  Meetup.com provides the ability to add comments to the event, you can also use social media (like twitter, Instagram, etc.) or event write a blog post to keep the conversation about an event going.

Help Spread the Word

Growing a community takes time and effort.  The more people that can help spread the word about the group, the bigger the pool of possible attendees … and the bigger the community.
Personally, I use twitter a lot for ‘spreading the word’ – though I have my doubts on how effective this really is.  Another thing I do is email people and mention groups, topics and people to them.  This helps me spread the word to some people who may not be in the know but may be interested.

Ways to get involved in the local tech community (4 of 5)

Start your own user group

If you want to become a leader in the local tech community, the best way is to start your own group and help actively grow the local community.  There are many challenges you’ll need to face to start a group, but if you really want to be a leader – you will need to take on those challenges and make it happen.  I would say at half of running a group requires a skillset similar to event planning and the other half is constantly communicating with the community in order to get speakers and get people interested in attending the group. 

If you are new to what it takes to create a group, you’ll notice there is an order to the items below and some have a (suggested) time along with them. These are the things I find useful, results may vary.

Pick a topic

The very first thing you should do is come up with a topic the group should focus on.  The broader the topic, the more flexibility you will have when it comes to finding speakers.

Last year, I started an Azure user group to meet north of Boston.  I’d been attending Bill Wilder’s Azure group that meets downtown Boston for years (Boston Azure Cloud User Group) but I sometimes find it hard to make it into the city in the evenings to attend … which got me thinking that I was probably not the only person that would like to have an Azure user group meeting that was north of Boston. 

The point being – I picked Azure as the topic even though there was already an Azure user group downtown Boston, I guessed there would be enough people in the tech community north of Boston to grow a new Azure user group without cannibalizing the membership from Bill’s group.

Get a plan for the group communications

Once you have a topic for a group you want to get started – the next thing you will need is a way to communicate about the group’s events.  When it comes to social media, different people use different services … which means the more you can utilize to get your group communications out the more people will find your group.

  • meetup.com – I suggest starting a meetup.com account (I know an account is not cheap – but meetup really does help people find your group)
  • website – In the past, I’ve always gotten the group’s domain name and created a website – but at the moment I’ve just stuck with using meetup.com.  The website may work for you, but I still haven’t set one up for my new group.
  • twitter account – I use twitter to get the word out. I have a twitter account for the group but I also use my own account to broadcast news about the group’s events.
  • facebook – some people setup facebook sites for groups.  I don’t currently have one for my group, but it may work for yours.
  • github – github can be a good location to publish meeting files and provide another channel for people to discover your group
  • slack – some groups also use slack.  Slack provides a nice way to have conversations outside of the actual event … which can really add value to the community

Find a location

One of the biggest challenges for holding a group can be finding the location to hold it. 

If you work for a company that has meeting space that would be a good spot to hold your group – I would recommend asking your employer if you could hold the group at your company.

If you don’t work for a large company or maybe don’t work in the city you want to hold the meeting (for instance I live about 20 minutes away from where I hold my group due to more technology companies being in the Burlington area than the Salem area), I would suggest the following:

  • If your group is related to Microsoft technologies – and there is an office in the location you want to hold the group – I’d check there first.  In my experience, Microsoft is one of the companies in the Boston area that are the friendliest to user groups.
  • If your group is related to another company’s technology – check with their local office
  • If your group is general and you just need to find a location – look where other user groups in the area are meeting and see if one of those would work for you
  • Other options are: universities (though they may require insurance), shared office spaces (like WeWork), consulting firms that may be related to the technology. 

Warning – some people will charge your money for using their space.

Find sponsors

Unless you have corporate sponsorship or are independently wealthy, it is good to have some sponsors to help pick up the tab for things like pizza and soda. 

Find help

Unless you know people who already interested in helping you with the group, finding additional help may at first be a family and friends sort of help.  Once the group gets going, you will more likely find people to help you with the group.

Within 4 weeks of the first meeting

Once you pick a date for the first meeting, there are a few things you will need to do.

Find a speaker

You’ll need to find a speaker for the meeting … this of course could be you or some other expert that you know in the community.  If you want the group to start off with a bang, I would suggest getting someone who is already known in the local community to speak at the first meeting and ask them to help you get the word out about the event.

Reserve the room

Make sure you have a room big enough and ask for it to be setup in a manner that will work for your group. 

For example: round tables are NOT a good setup if there is going to be a person presenting in the front of the room.  Class room setup (with tables) is often the best for technology related user groups.

Don’t for get AV needs make sure there will be some sort of a podium or seat in front of the room for your presenter and a projector.  Sometimes an audio mic is good too – especially if sound doesn’t travel in the facility.

Get the word out about your group and the upcoming meeting

Use your communication channels to spread the word about the event and get people interested in attending.

Within 2 weeks of the first meeting

At the point of 2 weeks from the event - to save your sanity – it is best to do a status check in order to make sure things are going as planned.

Check in with speaker

Make sure there will still be a speaker there and see if there are any special needs that should be prepared for

Check in with facilities

Verify you still have the room reserved.  Things get messed up all the time, you want to know a couple of weeks out if you need to reschedule – you don’t want to show up to a locked building the night of your event.

Get the word out about your group and the upcoming meeting (repeat as needed)

Use your communication channels to spread the word about the event and get people interested in attending.

Within 24 hours of the first meeting

Now the day is finally here, you need a check list to make sure the event goes well.  Here are a few things, I’m sure you’ll find others.

Get a reminder communication out

Remind people of the event and to update their RSVPs so you will have an idea of how many to prepare for

Order food and drinks ahead of time

I typically order food around 1pm for a 6pm meeting, this helps the pizza place fit my order in and not have to hurry.

Don’t forget plates, cups, napkins, etc.when it comes to getting food for groups, it is easy to focus on ordering the food – but don’t forget the other things needed to eat that food!