CloudFormationを極限まで自動化せよ:GitHub Actionsによる「鉄壁」のCI/CDパイプライン設計
インフラをコードで管理する(IaC)時代において、CloudFormation(以下CFn)を手動でポチポチとコンソールから叩いているようでは、エンジニアとしての死を意味する。
真のSREは、インフラのデプロイを「儀式」から「日常の呼吸」へと変える。今日は、GitHub ActionsとOIDC、そして静的解析を組み合わせた、「失敗を許容せず、変更を即座に安全に反映させる」ための極限のパイプライン構築について、その核心を論じる。
—
1. なぜ「CI/CDなしのインフラ」は負債となるのか
多くの現場では、デプロイのたびに「手動確認」という名のボトルネックが発生する。これは単なる効率の問題ではない。「冪等性が保証されない環境」は、障害発生時の復旧時間を指数関数的に増大させる。
CI/CDを導入する真の目的は、「速さ」ではない。「状態の確定」だ。Gitリポジトリを唯一の正(Single Source of Truth)とし、パイプラインを通さない変更を一切拒絶する環境こそが、大規模インフラを安定稼働させる唯一の解である。
—
2. OIDCによる「脱・長期認証情報」の教義
多くのエンジニアが犯す最大の過ちは、GitHub Secretsに`AWS_ACCESS_KEY_ID`をベタ書きすることだ。これはセキュリティの観点から即刻廃止すべきである。
GitHub ActionsとAWSをOIDC(OpenID Connect)で連携させ、IAMロールに一時的なセッションを払い出す設計に切り替えろ。これにより、認証情報の漏洩リスクをゼロに抑え、かつ権限の最小化を極限まで突き詰められる。
Terraform/CFn用 IAM Roleの信頼ポリシー設定
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Principal”: { “Federated”: “arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com” },
“Action”: “sts:AssumeRoleWithWebIdentity”,
“Condition”: {
“StringEquals”: {
“token.actions.githubusercontent.com:aud”: “sts.amazonaws.com”,
“token.actions.githubusercontent.com:sub”: “repo:your-org/your-repo:ref:refs/heads/main”
}
}
}
]
}
解説: `sub`条件でブランチを指定することで、悪意あるPRが他ブランチから紛れ込んでも、権限を奪取されることはない。
—
3. プルリクエスト駆動の「門番」を構築する
デプロイ前のテストを自動化しないのは、ブレーキの壊れた車で高速道路を走るようなものだ。`cfn-lint`と`checkov`を使い、構文チェックとセキュリティスキャンをPRの必須要件(Required Status Checks)にする。
`.github/workflows/deploy.yml` の深淵
name: CloudFormation CI/CD Pipeline
on:
pull_request:
paths: [‘infra/’]
push:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Linting
run: |
# 構文チェック: 致命的な誤りをパイプライン開始時に弾く
cfn-lint infra/template.yaml
- name: Security Scan
# checkovによるCISベンチマーク準拠チェック
run: checkov -d infra/ –framework cloudformation
deploy:
needs: lint-and-test
if: github.ref == ‘refs/heads/main’
runs-on: ubuntu-latest
permissions:
id-token: write # OIDCのために必須
contents: read
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- name: Deploy Stack
run: |
# ChangeSetを利用した安全なデプロイ
# 冪等性を担保するため、スタック更新時の影響範囲を可視化する
aws cloudformation deploy \
–template-file infra/template.yaml \
–stack-name production-stack \
–capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
–no-fail-on-empty-changeset
—
4. エキスパートの視点:パフォーマンスと冪等性の最適化
単に動かすだけなら上記で十分だが、我々が目指すのはその先だ。
1. ChangeSetの活用: `aws cloudformation deploy`は内部でChangeSetを作成するが、大規模スタックではタイムアウトやリソースの競合が発生する。`–no-fail-on-empty-changeset`は必須だが、それ以上に「スタックの分割」を検討すべきだ。マイクロサービス同様、インフラも疎結合に保て。
2. ドリフト検知の自動化: 定期的に `aws cloudformation detect-stack-drift` を叩くCronワークフローを別に用意し、手動変更を検知してSlackに通知せよ。CI/CDパイプラインを「守護神」にするのだ。
3. メモリ消費と高速化: 大規模なテンプレートの場合、CI上でのLint処理でメモリを喰うことがある。GitHub Actionsの`runs-on: ubuntu-latest`ではなく、セルフホストランナーを特定の高スペックインスタンスで動かすことで、検証フェーズの時間を数秒単位で短縮できる。
結論
インフラ構築の自動化は、ツールを入れたら終わりという安易なものではない。「人間が介在する余地をどれだけ排除できるか」、そして「失敗したときにどれだけ早く、安全に自動復旧できるか」。
この視点を持ってパイプラインを設計した時、君のインフラは初めて「堅牢」と呼ばれる資格を得る。さあ、今すぐコードを書き、手動オペレーションを歴史の彼方へ葬り去るがいい。