🛠️

AWS CodeBuild と GitHub で実現する Terraform CI/CD 入門

2023/10/26に公開

想定読者

AWS CodeBuild と GitHub による Terraform の CI/CD 実装例を紹介します。

  • Terraform の CI/CD ワークフローを実装したい人
  • AWS CodeBuild の具体的な使用例をみたい人

構成図

構成図

CodeBuild のビルドプロジェクトを 2 つ作成します。
それぞれプルリクエスト作成/更新とマージに対応します。

GitHub Actionsについて

GitHub Actions を利用すると CI/CD に関連するリソースが GitHub に閉じるため、よりシンプルに利用できます。筆者の参画する案件では GitHub Enterprise(いわゆるオンプレ版)が提供されていますが、GitHub Actions を利用するためにセルフホストランナーを用意する必要がありました。インフラを自前で用意することを嫌ったため、チームの AWS アカウントで CodeBuild を利用することとしました。基本的な概念は同じため、参考にしてください。

tfnotify

Terraform の plan/apply 結果を GitHub や Slack に通知してくれるツールです。

https://github.com/mercari/tfnotify

事前準備

リポジトリ

GitHub にて新規にリポジトリを作成します。
プライベートリポジトリで問題ありません。

アクセストークン

アクセストークン

GitHub にて 個人のアクセストークンを払い出します。
tfnotify が GitHub に通知をするために利用します。
Settings > Developer Settings > Personal access tokens > Tokens (classic) より作成できます。
権限は repo:status public_repo のみで大丈夫です。

アクセストークン

IAM

Terraform 実行に必要な権限を付与した IAM ロールを作成します。
本記事では IAM ポリシー AmazonS3FullAccess を利用します。
信頼関係では CodeBuild を許可しましょう。

IAMロール
IAMロール
IAMロール

S3

Terraform のバックエンド用 S3 バケットを作成します。
デフォルト値から変える設定はありません。

S3バケット

構築

サンプルコードはこちら。

https://github.com/teradatky/ci-codebuild-terraform-sample

GitHub

サンプルコードを参考に、CI/CD 用のコードをプッシュします。
Terraform コードの main.tf は後続の CI/CD ワークフロー体験で使うため、プッシュしないでください。

CodeBuild が plan 時に利用する buildspec_plan.yml は以下です。
apply を行う buildspec_apply.yml については、リポジトリを確認してください。

buildspec_plan.yml
version: 0.2

env:
  variables:
    TFDIR: "environments"
    TFNCONF: "codebuild/tfnotify.yml"
    TITLE: "Terraform Plan"
    MSG: "Plan detail via tfnotify"

phases:
  install:
    commands:
      # terraform
      - curl -sL https://releases.hashicorp.com/terraform/1.6.2/terraform_1.6.2_linux_amd64.zip > terraform.zip
      - unzip terraform.zip
      - cp terraform /usr/local/bin
      # tfnotify
      - curl -sL https://github.com/mercari/tfnotify/releases/download/v0.8.0/tfnotify_linux_amd64.tar.gz > tfnotify.tar.gz
      - tar -zxvf tfnotify.tar.gz
      - cp tfnotify /usr/local/bin
  pre_build:
    commands:
      - terraform -chdir="${TFDIR}" init -no-color
  build:
    commands:
      - |
        PLAN=$(terraform -chdir="${TFDIR}" plan -no-color 2>&1)
        echo "${PLAN}" | tfnotify --config "${TFNCONF}" plan --title "${TITLE}" --message "${MSG}"

tfnotify 用の設定ファイルは以下です。
こちらは plan と apply を 1 ファイルにまとめられます。

tfnotify.yml
---
ci: codebuild
notifier:
  github:
    token: $GITHUB_TOKEN
    repository:
      owner: "teradatky"
      name: "ci-codebuild-terraform-20231026"
terraform:
  plan:
    template: |
      {{ .Title }} <sup>[CI link]( {{ .Link }} )</sup>
      {{ .Message }}
      {{if .Result}}
      <pre><code>{{ .Result }}
      </pre></code>
      {{end}}
      <details><summary>Details (Click me)</summary>

      <pre><code>{{ .Body }}
      </pre></code></details>
  apply:
    template: |
      {{ .Title }} <sup>[CI link]( {{ .Link }} )</sup>
      {{ .Message }}
      {{if .Result}}
      <pre><code>{{ .Result }}
      </pre></code>
      {{end}}
      <details><summary>Details (Click me)</summary>

      <pre><code>{{ .Body }}
      </pre></code></details>

CodeBuild

ビルドプロジェクトを 2 つ作成します。
以下に plan 用ビルドプロジェクトを作成するスクリーンショットを載せています。
apply 用のリソースのスクリーンショットは省略しますが、同様に作成します。

CodeBuild
CodeBuild

CodeBuild

CodeBuild
CodeBuild

CodeBuild

CodeBuild
CodeBuild

2 つのビルドプロジェクトが作成できました。

CodeBuild

CI/CD ワークフロー

実際に Terraform コードを記載し CI/CD ワークフローを回します。
今回は S3 バケットを作成します。 main.tf に以下を記載してプッシュします。

main.tf
resource "aws_s3_bucket" "my_bucket" {
  bucket = "ci-codebuild-terraform-20231026-my-bucket"
}

プルリクエストを作成し、マージするまでの流れを記載します。
実際のプルリクエストはこちらから確認できます。

https://github.com/teradatky/ci-codebuild-terraform-sample/pull/2

プルリクエストを作成しました。

PullRequest

PullRequest

すると tfnotify により plan 結果が通知されます。
レビュアーはこの結果を確認することで、マージ可否を簡単に判断できるようになります。

PullRequest

terraform initterraform plan で失敗していないことが checks からも分かります。

PullRequest

レビュアーから Approve されたらマージしましょう。

PullRequest

マージ後 terraform apply の結果が通知されます。

PullRequest

以上、CI/CD ワークフローの一例でした。

まとめ

CodeBuild を使うことで、Terraform の CI/CD が実現できました。
プルリクエストをベースとすることで、作業ミスや認識齟齬をグッと減らすことができます。
また tfnotify は plan や apply 結果が プルリクエスト内で確認できるため、レビュー負荷が軽減されます。
CI/CD を未経験の方はぜひ試してみて欲しいです。

GitHubで編集を提案

Discussion