Coder Perfect

As a child resource, add Azure Traffic Manager endpoints to the main bicep template.

Problem

I’m trying to add a new Traffic Manager Profile to my main.bicep file using the Network/trafficManagerProfiles.bicep module. This is effective.

The main.bicep file creates many Function Apps, each with its own little module that is called similarly to this.

module functionAppModule 'Web/functions.bicep' = {
  dependsOn: [
    appServicePlanModule
    webApiStorageAccount
  ]
  name: 'functionAppModule'
  params: {
    environmentName: environmentName
    systemName: systemName
    azureRegion: azureRegion
    appServicePlanId: appServicePlanModule.outputs.id
  }
}

Now I’m attempting to add the essential endpoints of my web applications (Azure Functions) to the Traffic Manager Profile utilizing the endpoints attribute.

This would necessitate adding an option to this file that accepts an array of objects containing all information about my App Services, or resolving them over here (by retrieving the instances with the existing keyword). Because all of those resources are already available/referenced in the main.bicep file, this doesn’t seem like the best approach to go about it.

This is how the Traffic Manager Profile module currently looks:

param systemName string
@allowed([
  'dev'
  'test'
  'acc'
  'prod'
])
param environmentName string
param relativeLiveEndpoint string = '/api/Live'

var trafficManagerProfileName = '${systemName}${environmentName}'

resource trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2018-08-01' = {
  name: trafficManagerProfileName
  location: 'global'
  properties: {
    allowedEndpointRecordTypes: [
      'DomainName'
    ]
    dnsConfig: {
      relativeName: trafficManagerProfileName
      ttl: 60
    }
    profileStatus: 'Enabled'
    trafficRoutingMethod: 'Performance'
    monitorConfig: {
      profileMonitorStatus: 'Online'
      protocol: 'HTTPS'
      port: 443
      path: relativeLiveEndpoint
      timeoutInSeconds: 10
      intervalInSeconds: 30
      toleratedNumberOfFailures: 3
    }
    endpoints: [
      {
        id: 'the resource id'
        name: 'the resource name'
        type: 'the resource type'
        properties: {
          endpointStatus: 'Enabled'
          endpointMonitorStatus: 'Online'
          targetResourceId: 'the resource id'
          target: 'mysite.azurewebsites.net'
          endpointLocation: 'West Europe'
          weight: 1
          priority: 1
        }
      }
      // All other app services
    ]
  }
}

Endpoints can also be established via a child resource in ARM templates (something like Microsoft.Network/trafficmanagerprofiles/endpoints), according to some answers on Stack Overflow, but this doesn’t appear to be available in Bicep (or just isn’t available in the autocomplete).

What I’d like to accomplish in my main.bicep file is something like this, so that I can reference all of the App Services I wish to add.

var trafficManagerProfileEndpoints 'Microsoft.Network/trafficmanagerprofiles/endpoints@2050-01-01` = {
  name: '${trafficManagerProfile.Name}/endpoints'
  endpoints: [ 
    // All of my endpoints
  ]
}

When compared to Microsoft’s offerings, it’s somewhat similar. For configuration options in an App Service, see web/sites/config@2020-12-01.

Any thoughts on this?

Asked by Jan_V

Solution #1

I just skimmed through your question quickly, so excuse me if I’m missing something, but it appears that you need to designate your web app as a resource again, but this time as existing. This gives you access to all of the props you require from your app service.

This blog describes how to make advantage of Bicep’s existing resources: https://hexmaster.nl/posts/bicep-existing/

Answered by Eduard Keilholz

Solution #2

This is feasible with Bicep ARM, but the Microsoft.Network/trafficManagerProfiles api lacks types for endpoints, hence a warning will be generated even if the setup goes smoothly.

If you don’t include the endpoints attribute while creating a traffic manager profile:

resource trafficManager 'Microsoft.Network/trafficmanagerprofiles@2018-08-01' = {
  name: '<name>'
  location: 'global'
  properties: {
    profileStatus: 'Enabled'
    trafficRoutingMethod: '<trafficRoutingMethod>'
    dnsConfig: {
      ...
    }
    monitorConfig: {
      ...
    }    
  }
}

After that, you may add endpoints like this:

// Azure endpoints: cloud service, app service, app service slots, public ip
resource trafficManagerAzureEndpoint 'Microsoft.Network/trafficManagerProfiles/azureEndpoints@2018-08-01' = {
  name: '${trafficManagerName}/${name}'
  properties: {
    ...
  }
}

// External endpoint
resource trafficManagerExternalEndpoint 'Microsoft.Network/trafficManagerProfiles/externalEndpoints@2018-08-01' = {
  name: '${trafficManagerName}/${name}'
  properties: {
    ...
  }
}

// Nested endpoints
resource trafficManagerNestedEndpoint 'Microsoft.Network/trafficManagerProfiles/nestedEndpoints@2018-08-01' = {
  name: '${trafficManagerName}/${name}'
  properties: {
    ...
  }
}

Answered by Thomas

Post is based on https://stackoverflow.com/questions/70102291/add-azure-traffic-manager-endpoints-in-main-bicep-template-as-child-resource