GitHub ActionsでTerraformを実行する

# 概要
GitHub ActionsでTerraformを実行する為の方法を紹介した記事になります。

# 対象読者

以下のような前提知識がある方が対象となります。

- [Terraform](https://www.terraform.io/) の基礎的な知識を持っている
- [GitHub Actions](https://github.co.jp/features/actions) の基礎的な知識を持っている

# 方針

PR作成時に以下を実施します。

- 全ての `.tf` ファイルに対して `terraform fmt` を実行（差分があった場合はCIを失敗させる）
- `terraform init` の実行（差分があった場合はCIを失敗させる）
- `terraform validate` の実行（差分があった場合はCIを失敗させる）
- `terraform plan` の実行（差分があった場合はCIを失敗させる）

`terraform apply` までやっているケースもありますが、個人的には以下の理由で `terraform apply` は実施しておりません。

1. 各環境（dev,stg,prod etc）の差異がそれなりに大きいケースがありこのような環境では `dev` で `terraform apply` が成功したけど `stg` では失敗したという事がそれなりの頻度で起こる為
2. 本番環境に対して `terraform apply` を行うタイミングがCIの実行時とは限らないから

今後、色々と事情が変わって `terraform apply` を行うという方針に変わるかもしれません、その場合はこの記事に情報を追加します。

# 注意点

「GitHub Actions Terraform」 で検索を行うと [terraform-github-actions](https://github.com/hashicorp/terraform-github-actions/) を使っている記事が見つかる場合があります。

`hashicorp/terraform-github-actions` は現在推奨されておらず現在は [setup-terraform](https://github.com/hashicorp/setup-terraform) が公式で推奨されているやり方ですので今から利用するなら [setup-terraform](https://github.com/hashicorp/setup-terraform) を使いましょう。

# 設定ファイルの内容

以下がGitHub Actionsの設定ファイルになります。

```yml:.github/workflows/ci-master.yml
name: ci-master

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  terraform:
    name: Terraform
    runs-on: ubuntu-latest

    defaults:
      run:
        shell: bash
    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: configure AWS credentials
      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

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: 0.12.25

    - name: Terraform Format
      run: terraform fmt -recursive -check

    - name: Terraform stg/10-acm
      working-directory: ./providers/aws/environments/stg/10-acm
      run: |
        terraform init
        terraform validate
        terraform plan

    - name: Terraform stg/20-frontend
      working-directory: ./providers/aws/environments/stg/20-frontend
      run: |
        terraform init
        terraform validate
        terraform plan

    - name: Terraform prod/10-acm
      working-directory: ./providers/aws/environments/prod/10-acm
      run: |
        terraform init
        terraform validate
        terraform plan

    - name: Terraform prod/10-github
      working-directory: ./providers/aws/environments/prod/10-github
      run: |
        terraform init
        terraform validate
        terraform plan

    - name: Terraform prod/20-frontend
      working-directory: ./providers/aws/environments/prod/20-frontend
      run: |
        terraform init
        terraform validate
        terraform plan
```

やっている事を簡単にまとめると以下のようになります。

- `aws-actions/configure-aws-credentials@v1` でAWSのアクセスキー等を設定
- `Setup Terraform` で利用するTerraformのバージョンを指定
- `terraform fmt -recursive -check` でプロジェクト全体にFormatterをかける（もし差分があったらエラー）
- `tfstate` が存在するディレクトリで `terraform init`, `terraform validate`, `terraform plan` を実行

他に必要なサブコマンドがあれば追記すればOKです。

- （例1） `terraform workspace` を利用している場合は `terraform workspace select [workspace名]` を追加する
- （例2） `terraform apply` を実行したい場合は `terraform apply -auto-approve` を追加する

ちなみに実行ディレクトリ毎に同じ事が何度も書かれているのですが `strategy.matrix` を使えば重複する記述を削除出来るかもしれません。

https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategy

# おわりに

Terraform開発元のHashiCorp社公式である [setup-terraform](https://github.com/hashicorp/setup-terraform) を使えば簡単にGitHub ActionsでTerraformを実行出来ます。

今CircleCIから色々なプロジェクトをGitHub Actionsに移行しています。また情報が分かったら記事にしようと思います。

最後まで読んで頂きありがとうございました。