13. Reusable workflows / Composite actions
同じ Terraform CI/CD ロジックを複数のリポジトリで使い回す仕組み。「Reusable workflow」「Composite action」「Container action」の使い分け。
DRY 化したい場面
Terraform の CI/CD は checkout → setup-terraform → fmt → init → validate → plan → comment → apply という定型処理。これを 10 リポジトリで個別にコピペすると、改善が 10 倍大変になります。
3 つの再利用方法
| Reusable workflow | Composite action | Container / JS action | |
|---|---|---|---|
| 場所 | .github/workflows/*.yml | action.yml + steps: | 独立リポジトリ + Dockerfile / JS |
| 呼び出し方 | uses: with workflow_call | uses: in steps | uses: in steps |
| job 単位の再利用 | ○ | × | × |
| 複数 step まとめ | ○ | ○ | 制限あり |
| ランナー指定 | 呼び出され側で指定 | 呼び出し側で指定 | 呼び出し側で指定 |
| secrets の継承 | 明示が必要 | 自動継承(呼び出し側のスコープ) | 自動継承 |
Reusable workflow
「ワークフロー全体(jobs を含めて)」を 1 単位として共有。workflow_call トリガで定義。
共有側: your-org/shared/.github/workflows/terraform-plan.yml
name: Terraform Plan (reusable)
on:
workflow_call:
inputs:
working-directory:
type: string
required: true
tf-version:
type: string
default: "1.14.9"
aws-region:
type: string
default: "ap-northeast-1"
secrets:
AWS_ROLE_ARN:
required: true
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
plan:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ inputs.tf-version }}
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ inputs.aws-region }}
- run: terraform fmt -check -recursive
- run: terraform init -input=false
- run: terraform validate -no-color
- run: terraform plan -no-color -input=false -out=tfplan
- uses: marocchino/sticky-pull-request-comment@v2
with:
header: terraform-plan-${{ inputs.working-directory }}
message: |
#### Plan: `${{ inputs.working-directory }}`
(omit; see workflow log)
呼び出し側: 各リポジトリの .github/workflows/terraform.yml
name: Terraform
on:
pull_request:
paths: ["envs/dev/**", "envs/stg/**"]
jobs:
plan-dev:
uses: your-org/shared/.github/workflows/terraform-plan.yml@v1
with:
working-directory: envs/dev
secrets:
AWS_ROLE_ARN: ${{ secrets.DEV_TF_ROLE_ARN }}
plan-stg:
uses: your-org/shared/.github/workflows/terraform-plan.yml@v1
with:
working-directory: envs/stg
secrets:
AWS_ROLE_ARN: ${{ secrets.STG_TF_ROLE_ARN }}
Composite action
「複数 step を 1 つの uses: にまとめる」軽量ラッパ。job 単位ではなく step 単位 の再利用。
定義: your-org/shared/.github/actions/tf-init/action.yml
name: "Terraform setup & init"
description: "Setup Terraform CLI and run terraform init"
inputs:
tf-version:
required: false
default: "1.14.9"
working-directory:
required: true
runs:
using: "composite"
steps:
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ inputs.tf-version }}
- shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
terraform init -input=false
terraform validate -no-color
呼び出し側
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ap-northeast-1
# 複数 step が 1 行に
- uses: your-org/shared/.github/actions/tf-init@v1
with:
working-directory: envs/dev
- run: terraform plan -no-color
working-directory: envs/dev
組織内 共有リポジトリ
共有 workflow / action は専用リポジトリにまとめます。
your-org/shared/
├── .github/
│ ├── workflows/
│ │ ├── terraform-plan.yml # reusable workflow
│ │ ├── terraform-apply.yml
│ │ └── docker-build-push.yml
│ └── actions/
│ ├── tf-init/ # composite
│ │ └── action.yml
│ └── slack-notify/
│ └── action.yml
└── README.md
呼び出しは tag 固定 (@v1) を必須に。module versioning と同じ理由で、main 直参照は本番事故の温床。
運用 Tips
- Pin to SHA: 高セキュリティ要件なら tag ではなく commit SHA で固定(
uses: actions/checkout@a1b2c3d)。Renovate が SHA 自動更新を支援 - 権限の最小化:
permissions:を job ごとに必要最小限に書く - secrets: inherit: Reusable workflow で 全 secrets を渡したい時は
secrets: inherit(呼び出し側が同じ org の場合) - マトリクスとの組み合わせ: 環境ごとに plan を並列実行
- テスト: Reusable workflow / composite も
workflow_dispatchで手動テスト経路を作る
マトリクスで 3 環境並列 plan
jobs:
plan:
strategy:
fail-fast: false
matrix:
env: [dev, stg, prd]
uses: your-org/shared/.github/workflows/terraform-plan.yml@v1
with:
working-directory: envs/${{ matrix.env }}
secrets: inherit
最終回お疲れさまでした
これで GitHub × Terraform の運用基盤がひととおり完成。ホームから興味のあるトピックを行き来して、ぜひご自身のプロジェクトで手を動かしてみてください。