AWS CDK で AWS App Runner をデプロイする
概要
AWS App Runner を AWS CDK でデプロイしてみました。App Runner 用の L2 Construct はまだリリースされていないため CDK の恩恵は少なめですが、L1 で作成しました(α版はあるようですが)。コンテナイメージのビルドも CDK でおこない、cdk-docker-image-deployment を使って ECR リポジトリへのプッシュを同時におこないます。
準備
src/app/ 配下に Dockerfile をおき、通常の Web サーバーが起動するコンテナイメージがビルドできる状態にしておきます。
CDK プロジェクトに cdk-docker-image-deployment をインストールしておきます。
npm install --save cdk-docker-image-deployment
CDK 定義
const cpu = 256;
const memory = 512;
const containerPort = 8080;
const repository = new ecr.Repository(this, "Repository", {
emptyOnDelete: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
const imageDeployment = new imagedeploy.DockerImageDeployment(this, "ImageDeployment", {
source: imagedeploy.Source.directory("src/app"),
destination: imagedeploy.Destination.ecr(repository, {tag: "latest"}),
});
const accessRole = new iam.Role(this, "AccessRole", {
assumedBy: new iam.ServicePrincipal("build.apprunner.amazonaws.com"),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSAppRunnerServicePolicyForECRAccess"),
],
});
const instanceRole = new iam.Role(this, "InstanceRole", {
assumedBy: new iam.ServicePrincipal("tasks.apprunner.amazonaws.com"),
});
const autoScalingConfiguration = new apprunner.CfnAutoScalingConfiguration(this, "AutoScalingConfiguration", {
maxSize: 1,
});
const service = new apprunner.CfnService(this, "AppRunner", {
autoScalingConfigurationArn: autoScalingConfiguration.attrAutoScalingConfigurationArn,
instanceConfiguration: {
cpu: String(cpu),
instanceRoleArn: instanceRole.roleArn,
memory: String(memory),
},
sourceConfiguration: {
authenticationConfiguration: {
accessRoleArn: accessRole.roleArn,
},
autoDeploymentsEnabled: true,
imageRepository: {
imageConfiguration: {
port: String(containerPort),
runtimeEnvironmentVariables: [],
runtimeEnvironmentSecrets: [],
},
imageIdentifier: repository.repositoryUriForTag("latest"),
imageRepositoryType: "ECR",
},
},
});
service.node.addDependency(imageDeployment);
注意点ですが、更新デプロイ時にコンテナイメージの更新とリソースの設定変更が同時に発生した場合、イメージの更新を検出して App Runner がデプロイシーケンスを開始するため、リソースの設定変更が状態不正でエラーになってしまうようでした。App Runner はソースやコンテナのビルドパイプラインの機能もあるので、CDK でビルドまでするのはあまり相性が良くないかもしれません。
カスタムドメイン
これで払い出された URL (https://xxxxxxxx.ap-northeast-1.apprunner.com
) でアクセスできるようになりますが、独自のドメインでサービスするにはカスタムドメインの設定も必要です。
CloudFormation で App Runner のカスタムドメインの設定には現状対応していなかったため、以下のようにカスタムリソースで作成しました。この方法では、ドメイン名をあとから変更して更新することはできません。
参考) #129 CloudFormation/CDK Custom Domain Support For AppRunner
new cdk.custom_resources.AwsCustomResource(this, "CustomResource", {
logRetention: logs.RetentionDays.ONE_DAY,
onCreate: {
service: "AppRunner",
action: "AssociateCustomDomain",
parameters: {
ServiceArn: service.attrServiceArn,
DomainName: domainName,
},
physicalResourceId: cdk.custom_resources.PhysicalResourceId.of("AppRunner"),
},
onDelete: {
service: "AppRunner",
action: "DisassociateCustomDomain",
parameters: {
ServiceArn: service.attrServiceArn,
DomainName: domainName,
},
physicalResourceId: cdk.custom_resources.PhysicalResourceId.of("AppRunner"),
},
policy: cdk.custom_resources.AwsCustomResourcePolicy.fromSdkCalls({
resources: cdk.custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE,
}),
});
デプロイ後、ドメイン検証のため、App Runner のサービス > 「カスタムドメイン」タブから「DNS の設定」を参照し、手順に従って表示された内容の CNAME レコードを DNS サーバーに登録します。正しく設定できていれば、自動でサーバー証明書の作成がおこなわれ、ステータスが「アクティブ」になります。同様に、App Runner への CNAME または ALIAS レコードを追加して完了です。
Discussion