CDKでApp Runnerにカスタムドメインを設定することはできない
↑を見てもカスタムドメインを設定することはできなそう...
実際にGitHubにissueがあり、2024年1月現在、AppRunnerのカスタムドメインはCloudFormationはサポートされていないっぽい。
しかし、APIはサポートされている。↓
→ カスタムリソースで設定できる!
どういうことか、説明します。
カスタムリソースとは
カスタムリソースはCloudFormationが用意してくれている機能。以下は公式の引用
カスタムリソースを使用すると、テンプレートにカスタムのプロビジョニングロジックを記述し、ユーザーがスタックを作成、更新(カスタムリソースを変更した場合)、削除するたびに AWS CloudFormation がそれを実行します。たとえば、AWS CloudFormation のリソースタイプとして使用できないリソースを含める必要があるとします。それらのリソースは、カスタム リソースを使用して含めることができます。この方法により、すべての関連リソースを 1 つのスタックで管理できます。
- 要は、CloudFormationが対応していないリソースの作成に使えるってことらしい。
- CloudFormationやCDKのL2コンストラクタでは設定ができないが、SDKやAPIからは設定できることを設定。
- そのリソースが作成・更新・削除されるときに指定した Lambda 関数を実行して、何らかの操作ができる。
- CDKのL2コンストラクタは、CloudFormationのリソースに対応するL1コンストラクタで設定できるすべての項目に対応しているとは限らない。そのため、L2コンストラクタを使いつつもL2コンストラクタではできないことをカスタムリソースで補うということはよく行われる。
今回、App Runnerを作成するために`@aws-cdk/aws-apprunner-alpha`(L2コンストラクタ)を使用している。ここでカスタムドメインはサポートされていないが、APIはサポートされているのでカスタムリソースで実現する。
実装
カスタムリソースをインポート
import * as cr from 'aws-cdk-lib/custom-resources'
application-stack.ts
new cr.AwsCustomResource(this, 'customDomain', {
onCreate: {
//AppRunnerを指定
service: 'AppRunner',
//APIを指定
action: 'associateCustomDomain',
parameters: {
DomainName: 'testtest.example.com',
//AppRUnnerのARN
ServiceArn: service.serviceArn
},
physicalResourceId: cr.PhysicalResourceId.of('customDomainCreate')
},
onDelete: {
service: 'AppRunner',
action: 'disassociateCustomDomain',
parameters: {
DomainName: 'testtest.example.com',
ServiceArn: service.serviceArn
},
physicalResourceId: cr.PhysicalResourceId.of('customDomainDelete')
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: [service.serviceArn]
})
})
-
service
はL2コンストラクタで作成されたAppRunnerを指しています。 -
AwsCustomResource
を使用します。 -
onCreate
には作成時、onDelete
にはリソース削除時に実行されるアクションを記述します。今回はonCreateにassociateCustomDomain
、onDeleteにdisassociateCustomDomain
を指定します。 -
policy
には、onCreate
およびonDelete
アクションにおいてAppRunnerサービスに対して必要な権限を与えています。
上記をデプロイすれば、指定したドメインをAppRunnerに設定することができます。 ただ、マネコンで確認するとわかるのですが、指定のCNAMEレコードをDNSに登録しないとドメインの所有確認がされないので、実際にそのドメインで使えるようにはなりません。なので最後にDNSにCNAMEレコードを追加して完了です。