GitHub Actionsでsetup-terraformを試す

2020.05.13

初夏の訪れとともに, terraform-github-actionssetup-terraformに変わりましたがいかがお過ごしでしょうか.

ActionsでTerraformをデプロイする方法がより便利になったので今回は, setup-terraformを利用したワークフローを定義して, AWSにデプロイしたいとおもいます.

Difference between terraform-github-actions and setup-terraform

まずは従来利用していたterraform-github-actionsとsetup-terraformの違いについて記載していきます.
大まかに言えば, 下記が相違点になります.

  • terraform-github-actionsは実行するコマンドまでActionsで提供していた
  • setup-terraformはCIを実行するコンテナでのTerraformのセットアップまでが範囲で, コマンドについてはユーザが実行する必要がある

言葉だけでは伝わらない気持ちもあるので, 直接どのようにワークフローを定義しているかを比較していきます.
まずは, terraform-github-actionsを利用した場合のワークフローになります.

on:
  push:
    branches: [ master ]
jobs:
  apply:
    name: terraform apply
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1.0.0
      - name: terraform init
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.20
          tf_actions_subcommand: 'init'
          tf_actions_working_dir: './'
          tf_actions_comment: true
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - name: terraform apply
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.20
          tf_actions_subcommand: 'apply'
          tf_actions_working_dir: './'
          tf_actions_comment: true
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

initやapplyのタイミングで都度設定を渡す必要があり, 若干冗長になっていますね.
それに対してsetup-terraformは初期設定部分だけを行うので設定がシンプルになります.
また、configure-aws-credentialsを利用することで処理を分離でき, より一層可読性が上がった気がします.

name: terraform apply
on:
  push:
    branches: [ master ]
jobs:
  apply:
    name: terraform apply
    runs-on: ubuntu-latest
    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: us-east-2

      - name: terraform setup
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 0.12.24
      - id: init
        run: terraform init
      - id: apply
        run: terraform apply -auto-approve -no-color

Define Workflow

先ほど出た内容と重複するのですが, Actionsのワークフローの中身について書いていきます.
まずGitHub Actionsでデプロイするにあたり, IAM Userが必要になるので作成します.

IAM_USER_NAME=<IAM_USER_NAME>

aws iam --region us-east-1 create-user \
  --user-name $IAM_USER_NAME

{
  "User": {
      "Path": "/",
      "UserName": "<IAM_USER_NAME>",
      "UserId": "xxxxxxxxxxxxxxxxx",
      "Arn": "arn:aws:iam::123456789012:user/sandcastle",
      "CreateDate": "2020-05-13T02:23:56Z"
  }
}

aws iam --region us-east-1 create-access-key \
  --user-name $IAM_USER_NAME

{
    "AccessKey": {
        "UserName": "<IAM_USER_NAME>",
        "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxx",
        "Status": "Active",
        "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "CreateDate": "2020-05-13T02:24:09Z"
    }
}

aws iam --region us-east-1 attach-user-policy \
  --user-name $IAM_USER_NAME \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

上記コマンドでIAM Userとアクセスキーを作成したら, GitHub Secretsに登録します.
登録方法はドキュメントをご参照ください. 登録するのは, 「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」です.

次にワークフローを定義します.

.github/workflow/apply.tf

name: terraform apply
on:
  push:
    branches: [ master ]
jobs:
  apply:
    name: terraform apply
    runs-on: ubuntu-latest
    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: us-east-2

      - name: terraform setup
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 0.12.24
      - id: init
        run: terraform init
      - id: apply
        run: terraform apply -auto-approve -no-color

このワークフローではmasterブランチにcommitが走ったタイミングでterraformをapplyしてくれます.実際はplanとかで差分の確認はした方が良いかとは思います.
今回は検証が目的なのでとりあえず直接applyします.

Run workflow

実際にワークフローを実行してみます.
ここもシンプルにECSクラスタを作成するだけにしています.

main.tf

main.tf

terraform {
  required_version = ">= 0.12"
  backend "s3" {
    bucket = "YOUR TF STATE BUCKET"
    key    = "terraform.tfstate"
    region = "us-east-1"
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_ecs_cluster" "sandcastle" {
  name = "sandcastle"
  capacity_providers = [
    "FARGATE",
    "FARGATE_SPOT",
  ]
}

この内容を書いたらリポジトリにpushします.
リポジトリにpushすると, Actionsで下記のようなログが流れてデプロイができたことを確認できます.

Run terraform apply -auto-approve -no-color
/home/runner/work/_temp/xxxxxx-xxxx-xxxx-xxxx-xxxxxxx/terraform-bin apply -auto-approve -no-color
aws_ecs_cluster.sandcastle: Creating...
aws_ecs_cluster.sandcastle: Still creating... [10s elapsed]
aws_ecs_cluster.sandcastle: Creation complete after 11s [id=arn:aws:ecs:us-east-1:***:cluster/xxxxxxxx]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

簡単でかつ手早くデプロイができました.

さいごに

setup-terraformで可読性が上がり, より柔軟に対応できるようになりました.
もしまだ変更してない方はご利用をご検討ください.