CloudFormation LinterをGitHub Actionsから実行してテンプレートのミスを検知する
CloudFormation テンプレートを書いているとスペルミスやパラメータミスなどの間違いをしばしば引き起こします。Cloud Formation Linter である cfn-python-lint
を活用することで未然にミスを検知できます。
cfn-python-lint とは
AWS が提供している CloudFormation Linter です。テンプレートの typo やパラメータ不足など CloudFormation テンプレートに誤りがないかを検知できます。
https://github.com/aws-cloudformation/cfn-python-lint
VSCode や JetBrains などの IDE の拡張機能も提供されており、テンプレートを書きながらミスに気付くことができます。また、IDE の場合だと上書きを有効にすることで整形もしてくれるのでかなり便利です。
参考: Linterを使ってCloudFormationの間違いに爆速で気づく | DevelopersIO
GitHub Actions から Linter を実行する意義
CloudFormation テンプレートを作成・更新する人全員に cfn-python-lint
を使って事前にチェック・整形してくれるのが理想です。しかし、オープンソースとして公開している場合、全員が同じ環境を整えることは難しいです。そのため、GitHub で開発している場合、Pull Request(PR)作成時に Linter を実行することで検知できるしくみが必要となります。
GitHub Actions であれば、簡単に cfn-python-lint
を実行できるうえ、下図のように間違えた箇所を GitHub 上のソースコードにアノテーションしてくれるので修正が容易になります。
GitHub Actions のワークフロー作成
ここからは実際に GitHub Actions の設定に入ります。サンプルコードと Linter が動いている PR はこちらになります。
https://github.com/ohsawa0515/ecs-gpu-optimized-ami-auto-update/pull/1
# .github/workflows/cfn-lint.yml
name: "Cloudformation Linter"
on:
pull_request:
types: [synchronize, opened]
paths:
- "**.yml"
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install cfn-lint
run: |
python -m pip install --upgrade pip
pip install cfn-lint
- name: Add problem matcher
run: echo "::add-matcher::.github/cfn-lint.json"
- name: Lint by cfn-lint
run: cfn-lint *.yml -f parseable
やっていることはシンプルで pip で cfn-python-lint
をインストールして、cfn-lint *.yml -f parseable
で Linter を実行しています。-f parseable
オプションを渡すことで、指摘項目を1行にしてくれるため、後述の Problem Matcher においてパースしやすくなります。
# -f parseable なし
# 1つの指摘項目に対して2行に分かれるためパースが若干面倒
W2001 Parameter Foo not used.
cloudformation_template.yml:29:3
E3012 Property Resources/CodeBuild/Properties/TimeoutInMinutes should be of type Integer
cloudformation_template.yml:105:7
# -f parseable あり
# 1つの指摘項目に対して1行かつ「:」でセパレートされるのでパースしやすい
cloudformation_template.yml:29:3:29:6:W2001:Parameter Foo not used.
cloudformation_template.yml:105:7:105:23:E3012:Property Resources/CodeBuild/Properties/TimeoutInMinutes should be of type Integer
Problem Matcher の設定
以下のファイルを追加します。regexp
は cfn-lint *.yml -f parseable
の出力結果をパースするための正規表現です。
# .github/cfn-lint.json
{
"problemMatcher": [
{
"owner": "cfn-lint",
"pattern": [
{
"regexp": "^(\\S+):(\\d+):(\\d+):(\\d+):(\\d+):([EWI]\\d+:.+)$",
"file": 1,
"line": 2,
"column": 3,
"message": 6
}
]
}
]
}
ワークフローファイル(.github/workflows/cfn-lint.yml
)で以下の記載を入れれば完了です。
- name: Add problem matcher
run: echo "::add-matcher::.github/cfn-lint.json"
Discussion