★★★ 上級

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 workflowComposite actionContainer / JS action
場所.github/workflows/*.ymlaction.yml + steps:独立リポジトリ + Dockerfile / JS
呼び出し方uses: with workflow_calluses: in stepsuses: 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

マトリクスで 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 の運用基盤がひととおり完成。ホームから興味のあるトピックを行き来して、ぜひご自身のプロジェクトで手を動かしてみてください。