ちょっと話題の記事

GitHub ActionsでのTerraformの設定ファイルのCIを試してみた

2019.01.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、かたいなかです。

先日、GitHub ActionsでTerraformの設定ファイルのCIを行うためのアクションの実装が、Terraform公式から提供されているのを発見しました。プルリクのオープン時にterraform plan等の処理を実行し、プルリクにコメントとして結果を出力するものです。

そこで早速、Getting Startedを参考に、試してみましたのでその内容をブログにまとめます。

GitHub Actionsで実行する処理の概要

今回は以下のような処理が行われるようにしていきます。

  1. Pull Requestに関するイベント時に処理を開始
  2. プルリクがオープンされた時と、後からプルリクのブランチにプッシュされた時以外のイベントをフィルタする
  3. terraform fmt 実行
  4. terraform init 実行
  5. terraform validate 実行
  6. terraform plan 実行

さらに、処理終了後プルリクエストに処理の結果に応じたコメントが追加されるようにします。例えばterraform planまで処理が成功したときは、以下のように、terraform planの結果がコメントとして付くようにします。

実際にやってみる

事前準備

事前準備として以下を先に行っておきます。

使用するコードの準備

GitHub Actionsの設定ファイル

GitHub Actionsの設定ファイルは以下のようなものです。

.github/main.workflow

# Pull Requestに関するイベント時に処理を開始
workflow "Terraform" {
  resolves = "terraform-plan"
  on = "pull_request"
}

# プルリクがオープンされた時と、
# 後からプルリクのブランチにプッシュされた時以外のイベントをフィルタする
action "filter-to-pr-open-synced" {
  uses = "actions/bin/filter@master"
  args = "action 'opened|synchronize'"
}

# terraform fmt を実行
action "terraform-fmt" {
  uses = "hashicorp/terraform-github-actions/fmt@v0.1.1"
  needs = "filter-to-pr-open-synced"
  secrets = ["GITHUB_TOKEN"]
  env = {
    TF_ACTION_WORKING_DIR = "."
  }
}

# terraform init を実行
action "terraform-init" {
  uses = "hashicorp/terraform-github-actions/init@v0.1.1"
  needs = "terraform-fmt"
  secrets = ["GITHUB_TOKEN", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
  env = {
    TF_ACTION_WORKING_DIR = "."
  }
}

# terraform validate を実行
action "terraform-validate" {
  uses = "hashicorp/terraform-github-actions/validate@v0.1.1"
  needs = "terraform-init"
  secrets = ["GITHUB_TOKEN"]
  env = {
    TF_ACTION_WORKING_DIR = "."
  }
}

# terraform plan を実行
action "terraform-plan" {
  uses = "hashicorp/terraform-github-actions/plan@v0.1.1"
  needs = "terraform-validate"
  secrets = ["GITHUB_TOKEN", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
  env = {
    TF_ACTION_WORKING_DIR = "."
    # If you're using Terraform workspaces, set this to the workspace name.
    TF_ACTION_WORKSPACE = "default"
  }
}

ほぼ、Terraformの公式ドキュメントでの案内通りですが、secretsにAWSのアクセスキーを追加しています。

Terraformの設定ファイル

また、今回使用するTerraformの設定ファイルは以下です。

example.tf

# BackendとしてS3を使用する設定
terraform {
  required_version = "~> 0.11"

  backend "s3" {
    bucket = "<Terraformのbackendとして使用するバケット>"
    key    = "<tfstateを保存するキー>"
    region = "<バケットがあるリージョン>"
  }
}

# AWS Provider
provider "aws" {
  version = "~> 1.54"
  region  = "ap-northeast-1"
}

# EC2インスタンスを立ち上げる
resource "aws_instance" "web" {
  ami           = "ami-0a2de1c3b415889d2"
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld"
  }
}

設定内容はEC2のインスタンスを1台立ち上げるというものです。

GitHubのプライベートリポジトリにプッシュ

プライベートリポジトリにプッシュします。

パブリックリポジトリではGitHub ActionsによるTerraformの実行はしないようにしましょう。GitHub Actionsで、悪意のあるTerraformファイルに対して`terraform plan`が実行されると、アクセスキーがログ等に出力され、誰でも見られるようになってしまうおそれがあります。

GitHubにアクセスキーを登録

GitHubのリポジトリ上で Settings > Secrets と選択し、Secretsの設定画面を開きます。そして、事前に発行しておいたAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYを登録します。

GitHub Actions

ここまでの状態で、PR Openによって、Terraformのfmtplanなどの一連の処理が実行されるようになっています。 失敗パターンも含めて実際に動作を見てみましょう。

最後まで処理が成功する時

プルリクをオープンしてしばらくすると、一連の処理が成功し、terraform planの出力がコメントとして追加されました。

途中で処理が失敗する時

今回はterraform fmtで失敗するようなプルリクで試します。

処理失敗後、プルリクにterraform fmtの出力がコメントとして追加されました。

terraform validateなど、他の部分で失敗した際も同様で、失敗した部分の出力がプルリクにコメントとして出力されます。

まとめ

Terraform GitHub Actionsを使用した、GitHub ActionsでのTerraformの設定ファイルのCIを試してみました。

CIツールにログとして出力されるだけでなく、Pull Requestにコメントとしてterraform planの結果が出力されることで、レビューの質も上がりそうです。また、ドキュメントに従って進めただけで、Terraformの設定ファイルをチェックする処理を簡単に実装できる手軽さも魅力だと感じました。

今後Terraformを使用する機会に遭遇した際には採用を検討してみてはいかがでしょうか。

参考資料