こんにちは、君。インフラの自動化という、エキサイティングな領域へようこそ。
「手元のPCから`terraform apply`を打つたびに、冷や汗をかく」——そんな経験はありませんか? 誰かが同時に実行してステートを壊さないか、実行結果がチームに共有されているか、そんな不安から君を解放するのが、GitHub Actionsによる「IaCのCI/CD化」です。
今日は、現代のクラウドインフラ運用において「これだけは外せない」と言い切れる、Terraform(またはOpenTofu)をGitHub Actionsで安全・確実に運用するための黄金パターンを伝授します。
これをマスターすれば、君のチームのインフラ運用は劇的に楽になり、そして何より「プロの仕事」へと進化しますよ。
—
1. なぜ「自分のPC」からTerraformを卒業すべきなのか?
まず、基礎の基礎ですが、なぜ自動化が必要なのかを理解しておきましょう。
1. ステートの整合性: 複数人で同時に実行すると、インフラの設計図(State)が壊れるリスクがあります。
2. 透明性: 「誰が、いつ、何を、なぜ変更したか」がプルリクエスト(PR)にすべて残るようになります。
3. 安全な承認フロー: 誰かがコードを書き、別の誰かがその影響(plan結果)を確認して承認する。この「四つの目」が事故を防ぎます。
では、さっそくこの理想的な環境を構築していきましょう。
—
2. 事前準備:バックエンドと認証の設計
Terraformを自動化する前に、2つの重要な準備があります。
① ステートロックの有効化
Terraformの実行状態を管理する「tfstateファイル」は、S3などのクラウドストレージに置きます。この際、DynamoDBを用いたステートロックを必ず有効にしてください。GitHub Actionsが複数走っても、同時に書き込まないように「鍵」をかける仕組みです。
② OIDCによるセキュアな接続
GitHub ActionsからAWSやGoogle Cloudを操作する際、アクセスキーを直接埋め込むのは「初心者」のやり方です。
OIDC(OpenID Connect)を使いましょう。パスワードなしで、GitHub Actionsに一時的な権限を貸し出す、最も安全で現代的な手法です。
—
3. 実践:最強のGitHub Actionsワークフロー
ここからは、実際に私が現場で導入しているコードをベースに、構成を解説します。
目指すのは、「PRを作ると自動でPlan結果がコメントされ、マージされるとApplyされる」フローです。
`.github/workflows/terraform.yml` として作成してください。
name: “Terraform/OpenTofu CI/CD”
on:
push:
branches: [ “main” ] # mainブランチへのマージでApply
pull_request:
branches: [ “main” ] # PR作成・更新でPlan
permissions:
id-token: write # OIDC認証のために必要
contents: read # コードの読み取り
pull-requests: write # PRにコメントを書き込むために必要
jobs:
terraform:
name: “Terraform Workflow”
runs-on: ubuntu-latest
# 同じタイミングで複数のワークフローが走らないよう制御(ステートロック回避の補助)
concurrency:
group: terraform-${{ github.ref }}
cancel-in-progress: false
steps:
# 1. コードのチェックアウト
- name: Checkout
uses: actions/checkout@v4
# 2. OIDCを利用したAWS認証(例)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
aws-region: ap-northeast-1
# 3. Terraform/OpenTofuのセットアップ
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.0
# 4. 初期化
- name: Terraform Init
run: terraform init
# 5. Plan実行(PR時のみ)
- name: Terraform Plan
id: plan
if: github.event_name == ‘pull_request’
run: terraform plan -no-color -input=false
continue-on-error: true
# 6. Plan結果をPRにコメントとして投稿(ここが現場で喜ばれるポイント!)
- name: Update Pull Request
uses: actions/github-script@v7
if: github.event_name == ‘pull_request’
env:
PLAN: “terraform\n${{ steps.plan.outputs.stdout }}”
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `
Terraform Plan 📖 \`${{ steps.plan.outcome }}\`
詳細な実行結果を表示
\`\`\`hcl
${process.env.PLAN}
\`\`\`
Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\“;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
# 7. Apply実行(mainブランチへのプッシュ時のみ)
- name: Terraform Apply
if: github.ref == ‘refs/heads/main’ && github.event_name == ‘push’
run: terraform apply -auto-approve -input=false
—
4. この設計の「極限のこだわり」ポイント
このコードには、ただ動くだけではない、現場の知恵が詰まっています。
Plan結果の可視化
PRの画面上で、インフラがどう変わるのかが「折りたたみメニュー」で表示されます。わざわざActionsのログを見に行く必要はありません。レビューする同僚への最高のおもてなしです。
`concurrency` による多重実行防止
Terraformにはステートロックがありますが、CI側でも「同じブランチでの多重実行」を抑制することで、無駄なエラーや競合を未然に防いでいます。
`continue-on-error: true` の活用
Planが失敗しても、あえてステップを続行させています。これは、なぜ失敗したのかというエラーログをPRのコメントとして残すためです。
—
5. さらに一段上の運用へ:承認フロー(Environment)
もし「mainにマージされたら即適用」が怖い場合は、GitHubの “Environments” 機能を使いましょう。
1. GitHubリポジトリの `Settings` > `Environments` で「production」を作成。
2. `Required reviewers` をオンにして、承認者を指名。
3. ワークフローのApplyジョブに `environment: production` を追記。
これで、マージされた後、指定した人の「承認ボタン」を押すまでApplyが待機されるようになります。これがエンタープライズレベルの「守り」の設計です。
—
最後に
インフラをコードで管理し、それをCI/CDで運用することは、最初は少し難しく感じるかもしれません。しかし、一度この「型」を作ってしまえば、手作業によるミスや恐怖心は過去のものになります。
まずは、このワークフローをコピーして、小さなリソースから試してみてください。
もし分からないことがあれば、いつでも聞いてくださいね。君が自信を持って `git push` できる日を楽しみにしています。
さあ、最高の自動化ライフを始めましょう!