My Note

自己理解のためのブログ

TerraformのCI環境をGitHubとCodePipeline/CodeBuildで構築する

やったこと

Terraformのコーディングに集中するため、複数人で作業するためにTerraformの実行環境(CI)をAWSに構築してみました。 構成は、GitHubソースコード管理、CodePipelineとCodeBuildでTerraformのplanとapplyを実行するようにした。

環境

  • GitHub
  • CodePipeline
    • CodeBuild
      • hashicorp/terraform:0.11.14 コンテナ

CodePipelineのフロー

AWSのCodePipelineを用いてterraformのコードをデプロイするために、以下のフローにした。

ステップ 処理内容
Source GitHubからソースコード取得
Plan terraform planを実行
Approve planの結果を見てapplyを実行するかを承認
Apply terraform applyを実行

■ CodePipelineのフロー

f:id:yhidetoshi:20190621222358p:plain

CodeBuildでの処理内容を定義する

■ Planのステップで実行 ( buildspec-plan.yml )

version: 0.2

 env:
  parameter-store:
    AWS_ACCESS_KEY_ID: "access_key_id_example"
    AWS_SECRET_ACCESS_KEY: "secret_access_key_example"
    AWS_ENV: "env"

 phases:
  install:
    commands:
      - echo "Nothing to do with post_build phase"
  pre_build:
    commands:
      - export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
  build:
    commands:
      - terraform init -no-color
      - terraform workspace select ${AWS_ENV} || terraform workspace new ${AWS_ENV}
      - terraform plan -no-color
  post_build:
    commands:
      - echo "terraform plan completed on `date`"

■ Applyのステップで実行 ( buildspec-apply.yml )

version: 0.2

 env:
  parameter-store:
    AWS_ACCESS_KEY_ID: "access_key_id_example"
    AWS_SECRET_ACCESS_KEY: "secret_access_key_example"
    AWS_ENV: "env"

 phases:
  install:
    commands:
      - echo "Nothing to do with post_build phase"
  pre_build:
    commands:
      - export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
  build:
    commands:
      - terraform init -no-color
      - terraform workspace select ${AWS_ENV} || terraform workspace new ${AWS_ENV}
      - terraform apply -auto-approve -no-color
  post_build:
    commands:
      - echo "terraform apply completed on `date`"

ssmパラメータでAPIの鍵情報を管理する

CodeBuildでTerraformを実行するためにAWSAPI-Keyが必要となる。buildspec.ymlに平文で定義するのはセキュリティ的に問題があるため今回はSSMパラメータで管理した。 SSMパラメータの管理をAnsibleで行う。方法は以前に作成したブログを参照。

yhidetoshi.hatenablog.com

  • buildspec-{plan,apply}.ymlでSSMパラメータから値を取得する
    • CodeBuildのIAMロールでSSMReadOnlyの権限を付与する必要あり

■ buildspec.ymlの一部抜粋 ( AWSのか鍵情報をセット )

  parameter-store:
    AWS_ACCESS_KEY_ID: "access_key_id_example"
    AWS_SECRET_ACCESS_KEY: "secret_access_key_example"
    AWS_ENV: "env"
Key Value
access_key_id_example aws_access_key_idの値
secret_access_key_example aws_secret_access_key
env 例 {dev,stg,prod}

tfstate-fileの保存先をS3に設定する

  • 参考

www.terraform.io

  • s3-backend.tf
    • 東京リージョンに暗号化オプション有効で保存する場合
terraform {
  required_version = ">= 0.11.0"

   backend "s3" {
    bucket  = "保存するS3のバケット名"
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
  }
}