github actions(w/z composite) + setup-terraform

# tl;dr

- この記事は[terraform Advent Calendar 2021](https://qiita.com/advent-calendar/2021/terraform)の2日目です
- GitHub Actions で terraform を CI する
- ディレクトリ分割している時にワークフローが同じ形になりがち（こぴぺ）
- composite action で共通のアクションを使いまわして楽がしたい
- 複数ディレクトリも一度に回したい
- そんな actions.yml

# 注意

- （今のところ現職では）actions から apply はしてないので書いてない
- 一応動いてるけど、無保証です
- コードの手直し、質問等歓迎

# ワークフローファイル

composite action として、 .github/actions/ の下にわかりやすい名前のディレクトリ/action.yml として置いておくことで、ワークフローから呼び出すファイルが作れる。
ドキュメントがあほみたいにわかりにくい（まだちょいちょい更新されてるみたい？）けど、プライベートリポジトリで動作確認済。

```　.github/actions/terraform/action.yml
name: "setup-terraform"
description: 'terraform ci. fmt,init,validate,plan. not in apply'

inputs:
  terraform_version:
    description: 'use terraform version'
    required: false
    default: 1.0.x
  secrets_github_token:
    description: 'secrets.GITHUB_TOKEN'
    required: true
    default: ""
  working-directory:
    description: 'matrix.dir'
    required: true
    default: ""

runs:
  using: "composite"
  steps:

    - uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: ${{ inputs.terraform_version }}

    - id: fmt
      run: terraform fmt -check -diff
      shell: bash
      working-directory: ${{ inputs.working-directory }}

    - id: init
      run: terraform init -no-color
      shell: bash
      working-directory: ${{ inputs.working-directory }}

    - id: validate
      run: terraform validate -no-color
      shell: bash
      working-directory: ${{ inputs.working-directory }}

    - id: plan
      run: terraform plan -no-color -detailed-exitcode
      shell: bash
      working-directory: ${{ inputs.working-directory }}

    # 通知等するならここで。

```

呼び出す側のワークフロー

```　.github/workflows/pr.yml
name: terraform

on:
  # 手動で再実行できるのでつけておくと便利
  workflow_dispatch:
  # 厳格な時間では動かないので過信しない。あと当然UTC
  schedule:
    - cron: '0 0 * * SUN'
  # パスを指定するとプルリクで更新対象の時に実行される（逆にこれらのファイルが更新されないPRでは実行されない）
  # 自分自身を含めておくのもポイント
  pull_request:
    paths:
    - ".github/workflows/pr.yml"
    - "terraform/dir1/*.tf"
    - "terraform/dir2/*.tf"

jobs:
  on-pull-request:
    runs-on: ubuntu-latest

    # composite 内の run に continue-on-error が付けられないので外で
    continue-on-error: true
    strategy:
      # matrix のジョブのどれかがエラーになっても他のジョブをキャンセルしない（false）
      fail-fast: false
      # よくあるマトリックスはOSとかバージョンとか付けて動かすけど、terraform の場合は
      # ↑のpathsで指定したファイルのディレクトリをリストしておくことで、複数同時に処理できる
      # 実行順序は保証されないことには注意
      matrix:
        dir:
        - "terraform/dir1"
        - "terraform/dir2"

    steps:
    - uses: actions/checkout@master

    # このクレデンシャルは terraform 用。必要なものに置き換えること。いらなければ削除
    - uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id:     ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region:            ap-northeast-1

    # composite action 呼び出し。./ がないと見失って実行できないので注意
    - uses: ./.github/actions/terraform
      with:
        terraform_version: 1.0.x
        secrets_github_token: ${{ secrets.GITHUB_TOKEN }}
        working-directory: ${{ matrix.dir }}
      if: always()
```

# まとめ

- とはいえコメントちゃんと書いたのでコードのとおりってことでひとつ
- GitHub Actions が新しくなって（v2になって）それなりに経つけどだいたいやりたいことができるようになっていいよね
- [setup-terraform](https://github.com/hashicorp/setup-terraform) 自体はしばらく更新されてなくてアレだけど、HashiCorp の org の配下だしどこの誰が作ってるのかわからないワークフローを使うよりはマシかなとか
- terraform の管理について、ディレクトリやリポジトリの分割、CI/CD の回し方その他にもいろいろあると思うので、そういった話は [slack](https://t.co/rlNg75MmHK?amp=1) に持ち込んでくれるとうれしいです