見出し画像

GitHub Actionsでプルリク作成時にterraform planの結果を自動コメントさせてみたよ

こんにちは、すずきです。

都内の縦移動の不便さに20年以上怒りを感じ続けていたので、車買っちゃいました(買ったのはBIGなところじゃないよ)。

昔ドイツで参加した車体系の学会で、VWの発表が心に残っていたんですよね。発表していた(SPY×FAMILYのお父さんみたいにスタイリッシュな)VW技術者の思想がしっかりしていて、この人が設計している車に乗ってみたいな〜という感じでゴルフ(※車名)に手を出しちゃいました。これで毎日等々力渓谷に行けるね。

本当は車の話で一記事書きたいくらいなのですが自重

ところで、最近、アプリケーションのインフラ改修でTerraformを活用しています。

PRレビューでレビュワーにterraform planを実行してもらう手間がなかなか面倒だったので、GitHub Actionsのワークフローでterraform planの結果をコメントとして自動投稿する仕組みをつくりました。


ワークフローの概要

このワークフロー(.github/workflows/infrastructure-checks.yml)は、master向けのPRが作成もしくは更新されるたびに実行されます。

以下がワークフローの中身です。

name: 'Infrastructure Checks'
on:
  pull_request:
    branches:
      - master
    types: [opened, synchronize]

jobs:
  terraform:
    name: 'Terraform Checks'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        # stg, prodは未使用のため一旦コメントアウト
        # directory: ['environments/dev', 'environments/stg', 'environments/prod']
        directory: ['environments/dev']
    defaults:
      run:
        working-directory: ${{ matrix.directory }}
    steps:
      - name: Checkout
        uses: actions/checkout@v2

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

      - name: Setup 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: Terraform Format
        id: fmt
        run: terraform fmt -check

      - name: Check if directory is not empty
        id: check
        run: |
          if [ "$(ls -A .)" ]; then
            echo "Directory is not empty"
          else
            echo "Directory is empty"
            exit 1
          fi

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color
        continue-on-error: true

      - name: Comment PR
        uses: actions/github-script@v3
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outputs.stdout }}\`
            #### Terraform Initialization ⚙️\`${{ steps.init.outputs.stdout }}\`
            #### Terraform Plan 📖\`${{ steps.plan.outputs.stdout }}\``;
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Terraform checks in directory '${{ matrix.directory }}'\n` + output
            })

ワークフローの詳細

  1. Checkout: リポジトリをチェックアウトする(コードをGitHubの実行環境にダウンロードする)。

  2. Setup Terraform: ワークフローがTerraformコマンドを使用できるようにする。

  3. Setup AWS Credentials: AWSの認証情報をセットアップする。TerraformがAWSのリソースを管理できる。

  4. Terraform Format: Terraformのフォーマットをチェックする。フォーマットが一貫していることで、コードの可読性と保守性が向上する。

  5. Check if directory is not empty: ディレクトリenvironments/devが空でないことを確認する。

  6. Terraform Init: Terraformを初期化する。Terraformが後続のステップでリソースを管理できるようになる。

  7. Terraform Plan: terraform planを実行する。変更内容がPRにコメントとして投稿される。

  8. Comment PR: Terraformの各ステップの結果をPRにコメントとして投稿する。

補足

PR作成後のプッシュで変更が生じた場合にもワークフローが実行されるようにするために、typesにsynchronizeを追加しています。

on:
  pull_request:
    branches:
      - master
    types: [opened, synchronize]

また、環境ごとの構成(dev, stg, prodなど)についてそれぞれTerraformチェックを行いたい場合は、strategy.matrixを使用して各ディレクトリを列挙します。

  terraform:
    name: 'Terraform Checks'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        directory: ['environments/dev', 'environments/stg', 'environments/prod']
      run:
        working-directory: ${{ matrix.directory }}

ステップ3で設定しているAWSの認証情報(AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEY)は、IAMユーザーの作成後にGitHub Secretsに登録します。

  1. GitHubで対象のリポジトリに移動する。

  2. リポジトリのメインページの右上にある「Settings」(設定)タブをクリックする。

  3. 左側のメニューから「Secrets」を選択する。

  4. 「New repository secret」ボタンをクリックする。

  5. 「Name」フィールドにシークレットの名前を入力する。

  6. 「Value」フィールドにシークレットの値を入力する。

  7. 「Add secret」ボタンをクリックしてシークレットを保存する。

また、IAMユーザーにアタッチするIAMポリシーは、Terraformで管理するリソースにあわせて設定します。
terraform planは読み取り専用の操作となるので、もしEC2のリソースを管理するのであれば、AmazonEC2ReadOnlyAccessのようなマネージドポリシーをアタッチします。

コメントの中身

PRを作成、または更新すると、以下のようなコメントが一緒に投稿されるようになります。

コメントの一部

採用情報

エンジニア募集中です。今の弊社ならある程度やりたい放題できます。


この記事が気に入ったらサポートをしてみませんか?