skip to Main Content

I have a bicep template that creates several container apps. They shall have a custom sub domain in my private DNS zone. However, I have the problem that this leads to a circular dependency: To add the CName and verification TXT record to the DNS zone, I need the FQDN and verification from the container app. On the other hand, the deployment of the container app validates the existance of these records and fails if they are not there.

A workaround I currently use involves a boolean template parameter that must be false on the first run:

param register_custom_domains bool = false

resource container_app 'Microsoft.App/containerapps@2022-03-01' = {
  // ...
  properties: {
    configuration: {
      ingress: {
        customDomains: register_custom_domains ? [
          {
            name: 'name'
            certificateId: certifcate.id
            bindingType: 'SniEnabled'
          }
        ] : null 
      }
    }
  }
}

But this naturally requires to deploy twice. Is there a better way?

2

Answers


  1. Chosen as BEST ANSWER

    There is a solution that works in one pass. It is based on the fact that the verification string is the same for the container app environment and the individual containers. And since the containers will get an default domain name that is composed of the container name and the container environments defaultDomain, the CNAME and TXT records can be created before the containers.

    Here is a step-by-step description to register the container app named my_container as subdomain.my-domain.com:

    1. Create container app environment with SSL certificate:
    resource container_environment 'Microsoft.App/managedEnvironments@2022-06-01-preview' = {
      name: 'cae'
      // ...
    
      resource ssl_certificate 'certificates@2022-03-01' = {
        name: 'my-certificate'
        // ...
      }
    }
    
    1. Create CNAME and TXT records in DNS zone. In my case, since the DNS zone is in another resource group, I had to use a module but this is omitted here.
    resource dns_zone 'Microsoft.Network/dnsZones@2018-05-01' existing = {
      name: 'my-domain.com'
    
      resource cname 'CNAME@2018-05-01' = {
        name: 'subdomain'
        properties: {
          TTL: 3600
          CNAMERecord: {
            cname: '${container_name}.${container_environment.properties.defaultDomain}'
          }
        }
      }
      resource verification 'TXT@2018-05-01' = {
        name: 'asuid.subdomain'
        properties: {
          TTL: 3600
          TXTRecords: [
            {
              value: [container_environment.properties.customDomainConfiguration.customDomainVerificationId]
            }
          ]
        }
      }
    }
    
    1. Create container with custom domain. Here is is important to specify the dependsOn because the bicep compiler cannot know that the domain records are required.
    resource container_app 'Microsoft.App/containerapps@2022-03-01' = {
      dependsOn: [extend_dns_zone_module]
      name: 'my_container'
      properties: {
        // ...
        configuration: {
          // ...
          ingress: {
            // ...
            customDomains: [
              {
                name: 'subdomain.my-domain.com'
                certificateId: container_environment::ssl_certificate.id
                bindingType: 'SniEnabled'
              } 
            ]
          }
       }
    }
    

  2. I will tell you how I have it configured which may help you.

    I have a container app environment which has a custom DNS suffix of "apps.example.com" (not really, use your own here 🙂 and I’ve got a Let’s Encrypt TLS certificate for "*.apps.example.com"

    You will need to configure your DNS for

    • *.apps.example.com. to the IP address for the environment
    • asuid.apps.example.com to the value it gives you

    This still needs to be done two stage unfortunately – but this is only once, ever.

    Then I deploy my container apps into this container app environment and they get the above custom suffix, so instead of some wild random name it will have the one you give it, and also you don’t need to sort out DNS or certificates on a per-app basis as they all pick up the wildcard.

    So if I deploy the Microsoft Quickstart example site "my-container-app" then it appears as my-container-app.apps.example.com, fully secured with my Let’s Encrypt wildcard certificate.

    I actually have three environments, dev.example.com, test.example.com and apps.example.com so we can progress through our pipeline on independent environments keeping the container app name consistent. Three Let’s Encrypt certificates cost the same as one 🙂

    Hope that helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search