APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Bicepを使ってAzure Container Appsで無料のマネージド証明書を導入

はじめに

2023年7月14日現在まだプレビューですが、Azure Container Appsでは無料のマネージド証明書を利用することができます。

learn.microsoft.com

Azure PortalやCLIで導入する方法は記載されていますが、せっかくなのでIaCでできないかな、Bicepでできたらいいなということで、リファレンス等とにらめっこして試してみました。

リファレンスを見るとそれっぽい項目はあったのでこれならできるのでは?と思って始めましたが、プレビューということもあり、ちょっと手間取ったところがありまます。今回は、どうすればBicepで無料のマネージド証明書を導入できるか、その手順について説明したいと思います。

最初に行った手順

Azure Portal/CLIの手順やリファレンス情報を参照すると以下のようなことを行う必要があるようです。

  1. Azure Container Apps Environment
  2. カスタムドメイン情報をつけてApplicationを登録
  3. DNS上にCNAME/TXTを登録する(今回はCNAMEによる検証で行います)
  4. マネージド証明書情報の登録

CNAMEにはApplicationを作成すると生成されるURLを登録するので、上記の順序で行えばできるのではと考えました。

resource application 'Microsoft.App/containerApps@2023-04-01-preview' = {
  name: appName
  location: location
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${managedIdentity.id}': {}
    }
  }
  properties: {
    managedEnvironmentId: environment.id
    configuration: {
      ingress: {
        external: true
        targetPort: 80
        // この部分がカスタムドメイン登録情報
        customDomains: [
          {
            name: '${cname}.${dnsZoneName}'
            bindingType: 'SniEnabled'   // マネージド証明書の利用を宣言
            certificateId: certificate.id   // マネージド証明書のID
          }        
        ]
      }
〜〜以下省略

さてここで早速問題発生です。customDomainsに登録するCNAMEのホスト名を登録するのですが、DNS側にCNAMEやTXTが登録されていないとこのBicep登録は失敗します。また certificateId にまだ登録していないマネージド証明書のIDを指定しなければなりません。しかし、CNAMEに登録するURLはApplicatioinを登録しないとわからない(と思っていた)し、CNAMEが登録できないとマネージド証明書登録もできないようなので、上記の順序では登録できないことがわかりました。

試行錯誤、そして気づいたこと

いろいろ情報を探していたところ、まずCustomDomain指定なしでアプリケーションを作成し、DNSへのCNAME/TXT登録、マネージド証明書登録を行って、あらためてCustomDomain付きでApplicationを更新するというやり方を見かけました。 たしかにできそうですが、Applicationを2度登録するのがどうも面倒だし、Bicepファイルが複雑になるのがいまひとつでした。

そんなときに気づきました。

アプリケーションのURLって本当にApplicationをデプロイしないとわからないのか? 実はenvironmentの情報からわかるのではないか。

ApplicationのURLは実は <application.name>.<environment.properties.defaultDomain> となります。 applicatoin.nameはApplicationデプロイ時にこちらで指定するものですし、environmentまでは普通にデプロイできます。

ということは Applicatioinデプロイ前にDNSにCNAME/TXTは登録することができます。

そしてマネージド証明書証明書です。 登録用のBicepファイルを見ていると、実はApplication登録がなくてもデプロイできるんじゃないか。あらためてBicepファイルをみると以下のような内容なのでできそうです。

resource environment 'Microsoft.App/managedEnvironments@2023-04-01-preview' existing = {
  name: environmentName
}

resource certificate 'Microsoft.App/managedEnvironments/managedCertificates@2023-04-01-preview' = {
  name: '${environment.name}-certificate'
  location: location
  parent: environment
  properties: {
    domainControlValidation: 'CNAME'
    subjectName: '${cname}.${dnsZoneName}'
  }
  tags: tags
}

ちなみに、certificateのname '${environment.name}-certificate' ですが、この内容じゃないと登録に失敗します(たぶん。何度か別の名前で登録して失敗し、リファレンスに載っていたこの名前にしたら成功したので何らかの制約があるのではと予想してます)

ということで順序を以下のようにしました。

  1. Azure Container Apps Environment
  2. DNS上にCNAME/TXTを登録する(今回はCNAMEによる検証を選択肢ています)
  3. マネージド証明書情報の登録
  4. Applicationにカスタムドメインの登録

変更点はApplicationの登録を最後にする、というだけです。Application登録も先程の内容そのままで。

実際やってみると・・・・登録成功!!! 無事独自ドメインでhttps接続できることができした。

DNSへの登録はどうしたか

今回独自ドメインはAzure DNSを利用していたので、CNAME/TXTもBicepで登録できるようにしています。 必ずしもAzure DNSである必要はありませんが、レコード登録内容の参考になると思いますので掲載しておきます。 ここが正しくないとBicep登録時にエラーになりますので間違えないようにしましょう。

resource zone 'Microsoft.Network/dnsZones@2018-05-01' existing = {
  name: zoneName
}

resource txtRecord 'Microsoft.Network/dnsZones/TXT@2018-05-01' = {
  name: 'asuid.${cname}'
  parent: zone
  properties: {
    TTL: 3600
    TXTRecords: [
      {
        value: [
          environment.properties.customDomainConfiguration.customDomainVerificationId
        ]
      }
    ]
  }
}

resource cnameRecord 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = {
  parent: zone
  name: cname
  properties: {
    CNAMERecord: {
      cname: '${appName}.${environment.properties.defaultDomain}'
    }
    TTL: 3600
  }
}

まとめ

今回実施したのはあくまでもひとつの例で、他のやり方もあるかもしれません。またまだプレビュー段階であり、今後変更があるかもしれません。 ですが、Azure Container Appsのマネージド証明書は便利なもので早く活用しいたい機能でもあります。

Bicepの例ではありますが、ここで紹介した内容がなにかのご参考になれば幸いです。

こういう解決策をみつけ、組織内で共有していくのも立派なPlatform Engineer / Platform Engineeriingの要素の1つだと思います。 小さいことかもしれませんが、今後もいろいろ情報を公開していきたいと思いますのでぜひ今後も本ブログをよろしくお願いいたします。