Automation • Azure

Using Bicep automation to build Azure Traffic Manager profiles

Brett Borschel • Apr 10, 2022 • 3 min read

← Back to blog

Migrating on-prem virtual machines to the cloud is a delicate dance and one that may take a few tries to get right. Application downtime while migrating up and failing back can be in short supply, so it's important to automate as many processes as possible to prevent mistakes and longer RTO.

Azure Traffic Manager uses DNS to direct client requests to the appropriate service endpoint based on a traffic-routing method. Because it uses DNS for multi-endpoint load balancing, we can use it during a cloud migration to point traffic at on-prem web servers until the migration is scheduled, then enable the Azure endpoints to immediately forward traffic to the new cloud server — without waiting for DNS TTL caching to expire on any hosts.

This sounds great, but how will it scale? If you're only moving a handful of servers, the transition is manageable. But with a large project using SRM, an entire data center might be migrated at once. This is where Bicep automation comes in.

The setup

The project I had required me to create approximately 50 Traffic Manager Profiles and be able to quickly fail back and forth between on-prem and cloud addresses. I accomplished this with a for loop that feeds a template resource with an array of variable objects.

First, define global parameters and the per-profile variable array:

// Global Variables
param globalVariables object = {
  onpremTargetStatus: 'Enabled'
  azureTargetStatus: 'Disabled'
  trafficRoutingMethod: 'Priority'
  environmentTag: 'UAT'
}

// Variable object list to create Traffic Manager Profiles
var profiles = [
  {
    profileName: 'website1-uat-domain-com'
    dnsConfigRelativeName: 'website1-uat.domain.com'
    onpremTargetIP: '1.1.1.1'
    azureTargetIP: '2.2.2.2'
    applicationTag: 'webApp1'
  }
  {
    profileName: 'website2-uat-domain-com'
    dnsConfigRelativeName: 'website2-uat.domain.com'
    onpremTargetIP: '3.3.3.3'
    azureTargetIP: '4.4.4.4'
    applicationTag: 'webApp2'
  }
  {
    profileName: 'website3-uat-domain-com'
    dnsConfigRelativeName: 'website3-uat.domain.com'
    onpremTargetIP: '5.5.5.5'
    azureTargetIP: '6.6.6.6'
    applicationTag: 'webApp3'
  }
]

Then create all the Traffic Manager Profile resources in a single loop:

resource trafficManagerProfile 'Microsoft.Network/trafficManagerProfiles@2018-08-01' = [for profile in profiles: {
  name: profile.profileName
  location: 'global'
  tags: {
    App: profile.applicationTag
    Env: globalVariables.environmentTag
  }
  properties: {
    profileStatus: 'Enabled'
    trafficRoutingMethod: globalVariables.trafficRoutingMethod
    dnsConfig: {
      relativeName: profile.dnsConfigRelativeName
      ttl: 35
    }
    monitorConfig: {
      protocol: 'HTTP'
      port: 80
      path: '/'
      intervalInSeconds: 30
      timeoutInSeconds: 5
      toleratedNumberOfFailures: 3
    }
    endpoints: [
      {
        name: 'OnPrem-Endpoint'
        type: 'Microsoft.Network/TrafficManagerProfiles/ExternalEndpoints'
        properties: {
          target: profile.onpremTargetIP
          endpointStatus: globalVariables.onpremTargetStatus
          endpointLocation: 'westus'
          weight: 100
          priority: 1
        }
      }
      {
        name: 'Azure-Endpoint'
        type: 'Microsoft.Network/TrafficManagerProfiles/ExternalEndpoints'
        properties: {
          target: profile.azureTargetIP
          endpointStatus: globalVariables.azureTargetStatus
          endpointLocation: 'westus'
          weight: 100
          priority: 2
        }
      }
    ]
  }
}]

Running the migration

On the first run, the script creates all Azure resources still pointing traffic at the on-prem public IPs. When it's time to kick off migration, run it a second time with the endpoints flipped:

param globalVariables object = {
  onpremTargetStatus: 'Disabled'
  azureTargetStatus: 'Enabled'
}

The complete version of this script is available on GitHub.

Additional reading