Terraform PlanのCIを作成

## はじめに
今回はTerraform PlanをチェックするCIを作成します。
実装するとインフラの変更点をPlanの結果から確認できます。

#### 記事の概要
GitHubActionsでTerraform PlanのCIを作成します。
dev・prepareディレクトリで作成するリソースを検証します。

#### 想定読者
- GitHubActionsでPlanを検証するCIを作成したい方

#### 前回の記事
- https://qiita.com/bkend_2/items/0d2b2f68c008c7cbe030

## 追加するディレクトリ構成
dev・prepareディレクトリ用でファイルを作成します。
```bash
.github
└── workflows
    ├── dev_plan.yml # devディレクトリにPlanのCIを追加
    └── prepare_plan.yml # prepareディレクトリにPlanのCIを追加
```

<details><summary>全体のディレクトリ構成</summary>

```bash
.
.github
└── workflows
│   ├── dev_plan.yml # devディレクトリにPlanのCIを追加
│   └── prepare_plan.yml # prepareディレクトリにPlanのCIを追加
├── envs 
│   ├── dev # develop環境
│   │   ├── backend.tf # tfstateを管理
│   │   ├── main.tf # module呼び出し
│   │   ├── provider.tf # providerブロック
│   │   ├── terraform.tfvars # 変数を入力
│   │   └── variables.tf # 変数
│   ├── prd # production環境
│   └── stg # staging環境
├── modules
│   ├── network # ネットワーク
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── oidc # OIDC
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── prepare_tfstate # prepareのtfstateを管理するS3
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── tfstate # devのtfstateを管理するS3
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
└── prepare # 共通リソース作成
    ├── backend.tf
    ├── main.tf
    ├── provider.tf
    ├── terraform.tfvars
    └── variables.tf
```
各ディレクトリの詳細は、過去の記事から確認できます。
</details>

## Terraformのコードと解説

認証には[前回の記事](https://qiita.com/bkend_2/items/0d2b2f68c008c7cbe030)で作成したOIDCを使用します。


#### .github/workflows/dev_plan.yml
```yml:.github/workflows/dev_plan.yml
name: dev plan

on:
  push:
    branches:
      - feature/*
      - hotfix/*
  pull_request:
    branches:
      - feature/*
      - hotfix/*

permissions:
  id-token: write
  contents: read

jobs:
  terraform_dev_plan:
    name: terraform - dev - plan
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.3.9

      - name: AWS OIDC credential
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT }}:role/${{ secrets.OIDC_ROLE }}
          aws-region: ap-northeast-1

      - name: Terraform Init
        run: terraform init -upgrade
        working-directory: ./envs/dev

      - name: Terraform fmt
        run: terraform fmt -check

      - name: Terraform Validate
        run: terraform validate -no-color

      - name: terraform refresh
        run: terraform refresh -no-color -lock=false -var="env=dev"
        working-directory: ./envs/dev

      - name: Terraform Plan
        run: |
          terraform plan \
          -no-color \
          -lock=false \
          -var="env=dev"
        working-directory: ./envs/dev
```

<details><summary>コードの詳細</summary>

```bash
Terraform Init : Terraformの初期化
Terraform fmt : コードのフォーマットをチェック
Terraform Validate : コードの検証
terraform refresh : Terraformの状態を最新のリソース状態に更新
Terraform Plan : リソースの変更を表示
```
</details>

prepareディレクトリに対してもTerraform PlanのCIを追加します。
<details><summary>.github/workflows/prepare_plan.yml</summary>

```yml:.github/workflows/prepare_plan.yml
name: prepare plan

on:
  push:
    branches:
      - feature/*
      - hotfix/*
  pull_request:
    branches:
      - feature/*
      - hotfix/*

permissions:
  id-token: write
  contents: read

jobs:
  terraform_prepare_plan:
    name: terraform - prepare - plan
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.3.9

      - name: AWS OIDC credential
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT }}:role/${{ secrets.OIDC_ROLE }}
          aws-region: ap-northeast-1

      - name: Terraform Init
        run: terraform init -upgrade
        working-directory: ./prepare

      - name: Terraform fmt
        run: terraform fmt -check

      - name: Terraform Validate
        run: terraform validate -no-color

      - name: terraform refresh
        run: |
          terraform refresh -no-color \
          -var="account_id=${{ secrets.AWS_ACCOUNT }}" \
          -var="user_name=${{ secrets.USER_NAME }}" \
          -var="repository_name=${{ secrets.REPOSITORY_NAME }}"
        working-directory: ./prepare

      - name: Terraform Plan
        run: |
          terraform plan -no-color \
          -var="account_id=${{ secrets.AWS_ACCOUNT }}" \
          -var="user_name=${{ secrets.USER_NAME }}" \
          -var="repository_name=${{ secrets.REPOSITORY_NAME }}"
        working-directory: ./prepare

```

</details>

## 動作確認
AWSリソースを追加するときに差分が発生するか検証してみました。
動作確認のためVPCを作成してみます。
![スクリーンショット 2023-09-16 18.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2148800/db92444d-3461-b2a3-7409-872ca0eca065.png)
CIの結果を見るとVPCが作成されます。
コードが正しく作動しています。

## おわりに
今回はTerraform PlanをチェックするCIを作成しました。
差分が発生しているかCIの結果をみて判断できます。

次回はPlanの結果をプルリクの中から確認したいと思います。

今回作成したgithubのリポジトリ : https://github.com/hikobend/terraform-qiita
ブランチ : https://github.com/hikobend/terraform-qiita/pull/7

## 今後作成予定の記事
- Terraform Planの結果をプルリクから確認
- セキュリティグループの作成