AWS CloudFormationファイルサイズ制限によるエラーの解決策
概要
こんにちは、今年からインフラ担当になったマシューです。
先週、AWS CFNのファイルサイズ制限で認証に失敗し、それを解決しました。
この記事はCFNテンプレートのファイルサイズ制限と解決案についてまとめます。
- AWS CFNとは
- エラー:ファイルサイズ制限で認証失敗
- 解決案1:構文を簡略化
- 解決案2:リソース定義を別のテンプレートに移行
- まとめ
AWS CFN (CloudFormation)とは
Cloudでのインフラが拡張すると、リソースを逐一セットアップするのは結構時間がかかります。そのため、AWSではリソースをモデル化する、CloudFormation(CFN)というサービスを提供しています。CloudFormationを使う際、テンプレート(定義)に必要なリソースと変数を記述して、AWSにアップロードすると、CFNは記述した内容の通りリソースをデプロイします。
一つのテンプレートによってデプロイしたリソースは、同じリソース群「スタック」(Stack)に属します。テンプレートを変更した場合、スタックもリソースも自動的にその変更を反映します。
このようにインフラをコード化することは Infrastructure as Code(IaC)とも言います。
(他のIaCツール:AWS CDK, Terraform)
エラー:ファイルサイズ制限で認証失敗
まずは、awscliを使ってローカルでテンプレートを検証します。
aws cloudformation validate-template
--template-body file:///Users/mathew/myapp/stack1.yaml
ファイルサイズが50Kbを超えると、検証に失敗します。
...at 'templateBody' failed to satisfy constraint:
Member must have length less than or equal to 51200
AWSのサイトで解決案はテンプレートをS3にアップロードすることでファイルサイズ検証を避けられます。以下はS3を使わずに二つの解決案です。
解決案1:構文を簡略化
テンプレートを簡略化して、文字数を減らし、ファイルサイズを縮小することができます。
例えば、以下のように環境変数の構文を簡略化していきます。
# 元の冗長な構文
Secrets:
- Name: NODE_ENV
ValueFrom: !Join
- ""
- - !Ref SecretsArn
- ":NODE_ENV::"
- Name: PG_ENDPOINT
ValueFrom: !Join
- ""
- - !Ref PG_ENDPOINT
- ":LOG_LEVEL::"
# 簡略化した構文
Secrets:
- Name: NODE_ENV
ValueFrom:
Fn::Sub: "${SecretsArn}:NODE_ENV::"
- Name: PG_ENDPOINT
ValueFrom:
Fn::Sub: "${SecretsArn}:PG_ENDPOINT::"
ところで、テンプレートはYAMLファイルなので、プログラム言語のようにforeach/mapの構文はないです。一応ChatGPTにも聞いてみましたが、ほとんど実行できないスクリプトを返すことです。💦
解決案2:リソース定義を別のテンプレートに移行
大きなテンプレートを縮小するもう一つの方法は、別のテンプレートにリソースを移行することです。
リソース間に依存関係がある場合は、親スタックはOutputsとして子スタックとリソースを共有できます。
Outputs:
S3BucketNameDBbackup:
Value: !Ref S3BucketName
Export:
Name: S3BucketName
子スタックが利用する時 !ImportValue
の組み込み関数を利用します。
Statement:
- Resource:
- !Sub
- "arn:aws:s3:::${s3_bucket_name}"
- s3_bucket_name: !ImportValue S3BucketName
もちろん、依存関係のループができないので、親スタックを先にAWSで作成しないと子スタックを作成できません。
まとめ
- AWS CFNはIaCツールであり、Cloudリソースをコード化できる
- CFNのテンプレートのファイルサイズ制限は50Kb
- ファイルサイズ制限を解決するには、S3にアップロードとファイルを縮小する二つの解決策がある
Discussion