😁

pulumi x Azure x containerApp でカスタムドメインを設定する方法

2025/01/05に公開

結論

合計2回に分けてpulumi upをする必要がある。

前提条件

すでにpulumiでcontainerAppを作成済み、且つ、デフォルトURLにアクセスして問題なくアプリにアクセスできる状態。

以下、カスタムドメインをcontainerAppに設定する手順

1. pulumi up 1回目

SSL証明書なしのカスタムドメインをcontainerAppに設定する。
⚠️ManagedCertificateのリソースはこの時はまだ作成しない‼️

// 省略:managedEnvとかresourceGroupを作っておく。

const containerApp = new app.ContainerApp('example-container-app', {
  resourceGroupName: resourceGroup.name,
  location: resourceGroup.location,
  managedEnvironmentId: managedEnv.id, // managedEnvとかは事前に作っておくこと

  configuration: {
    ingress: {
      external: true,
      targetPort: 80,
      customDomains: [
         {
            name: 'www.example-app.com',
            bindingType: 'Disabled' 👈️ここでDisabledを指定すること!(証明書なしでカスタムドメインの設定を可能にする。)⚠️ManagedCertificateのリソースはこの時はまだ作成しない‼️
         }
      ],
    },
  },
  template: {
    containers: [
      {
        name: 'example-app',
        image: 'exampleImage',
      },
    ],
  },
})

上記のコードをpulumi upします。

するとこういうエラーが出るはず

error: Code="InvalidCustomHostNameValidation" Message="A TXT record pointing from asuid.www.example-app.com to EG6D174AD7BAF3CE171FB953EG6D174AD7BAF3CE171FB953EG6D174AD7BAF3CE171FB953 was not found."

これはcontainerAppがwww.example-app.comというカスタムドメインの所有者の認証ができてないから発生しているエラーです。

2. TXTレコードを追加してドメインの所有権を確認する

なので自分がドメインを取得したDNSプロバイダー(お名前.comなど)のDNS設定画面を開き、
asuid.www.example-app.comというホストに対してTXTレコードを追加しましょう。
例:

しばらくすると設定するとTXTレコードが伝播します。
以下のコマンドで伝播しているか確認しましょう

slookup -type=txt asuid.www.example-app.com

こんな感じでTXTレコードに設定した値が表示されればOKです。

Non-authoritative answer:
asuid.www.example-app.com    text = "EG6D174AD7BAF3CE171FB953EG6D174AD7BAF3CE171FB953EG6D174AD7BAF3CE171FB953"

これでcontainerAppがあなたのカスタムドメインを認証できている状態になりました。

そこでpulumiのコードを以下の用に修正して、カスタムドメインにSSL証明書を発行しましょう

3. pulumi up 2回目

カスタムドメインのSSL証明書を発行し、それをcontainerAppのカスタムドメインに設定する。

// 追加:カスタムドメインのSSL証明書発行
const managedCert = new app.ManagedCertificate('managedCertificate', {
   environmentName: managedEnv.name,
   location: resourceGroup.location,
   managedCertificateName: `example-app-managed-cert`,
   properties: {
     subjectName: 'www.example-app.com',
     domainControlValidation: 'CNAME',
   },
   resourceGroupName: resourceGroup.name,
})

const containerApp = new app.ContainerApp('example-container-app', {
  resourceGroupName: resourceGroup.name,
  location: resourceGroup.location,
  managedEnvironmentId: managedEnv.id, // managedEnvとかは事前に作っておくこと

  configuration: {
    ingress: {
      external: true,
      targetPort: 80,
      customDomains: [
         {
            name: 'www.example-app.com',
            bindingType: 'SniEnabled', 👈️ 追加:ここでSniEnabledを指定すること!
          certificateId: managedCert.id, 
         }
      ],
    },
  },
  template: {
    containers: [
      {
        name: containerAppName,
        image: apacheImage.imageName,
      },
    ],
  },
})

// containerAppのURLを出力
export const containerAppUrl = pulumi.interpolate`https://${containerApp.configuration.apply(
  (c: any) => c?.ingress?.fqdn
)}`

上記をpulumi upすると成功し、containerAppのURLが出力されるはずです。

Outputs:
    containerAppUrl: "https://example-app28cdf8c0.snowyboy-1231231.japaneast.azurecontainerapps.io"

4. CNAMEレコードをDNS設定で追加する

最後にお名前.comなどのDNSプロバイダーのDNS設定画面で、
上で出力されたcontainerAppUrl向けのCNAMEレコードを作成しましょう。

⚠️通常数分ですが、反映されるまでに時間がかかる場合があります。

これで www.example-app.com にアクセスすれば、httpsでcontainerAppにアクセスできるはずです!
IaCサイコー\(^o^)/

Discussion