はじめに
CloudFormationのテンプレートエラーに気づくのは、実際にスタックをデプロイしてからということがよくあります。本記事では、CloudFormationテンプレートの静的解析ツールであるcfn-lintを使用して、デプロイ前にテンプレートエラーを検出する方法について紹介します。
環境
cfn-lintをインストールします。
pip install cfn-lint
1. エラー検出用のテンプレート検証
簡単なLambdaを構築するテスト用のCloudFormationテンプレートを準備します。
意図的にいくつかのエラー箇所を含めた以下のCloudFormationテンプレートをtemplate.yamlとして保存します。
▼問題箇所3点
-
Runtime: python3.7
⇒古いバージョンを指定 -
Timeout: 1000
⇒タイムアウトの時間を15分以上に設定 - testLambdaFunctionに対する
AWS::IAM::Role
の記載なし
AWSTemplateFormatVersion: "2010-09-09"
Resources:
testLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: test-python-function
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': 'test hello world!'
}
Runtime: python3.7 # 古いランタイムバージョンを指定
MemorySize: 128
Timeout: 1000 # タイムアウトの上限を超過
# AWS::IAM::Roleの記載なし
2. cfn-lintでテンプレートを検証
以下のコマンドで作成したテンプレートを検証してみます。
cfn-lint template.yaml
コマンドを実行すると下記の内容をが表示されます。
E1010 'LambdaExecutionRole' is not one of ['MyLambdaFunction']
template.yaml:9:7
E2531 Runtime 'python3.7' was deprecated on '2023-12-04'. Creation was disabled on '2024-01-09' and update on '2025-02-28'. Please consider updating to 'python3.12'
template.yaml:17:7
E3034 1000 is greater than the maximum of 900
template.yaml:19:7
IAMロールがアタッチされていない事、ランタイム、タイムアウトの問題を指摘してくれています。これら3点を修正し再度テンプレートの検証を行います。
3. エラーの修正
3.1 ランタイムの更新
Runtime: python3.12 # 最新バージョンに更新
3.2 タイムアウトの修正
Timeout: 300 # 5分に設定
3.3 IAMロールの追加
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
修正後の完全なテンプレートは次の通りです。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
testLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: test-python-function
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': 'test hello world!'
}
Runtime: python3.12
MemorySize: 128
Timeout: 300
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
修正後のテンプレートを再度検証します
cfn-lint template.yaml
上記のコマンドを実行すると、今度はエラーや警告が表示されなくなったことを確認できました。
参考