TerraformのCI環境をGitHubとCodePipeline/CodeBuildで構築する
やったこと
Terraformのコーディングに集中するため、複数人で作業するためにTerraformの実行環境(CI)をAWSに構築してみました。 構成は、GitHubでソースコード管理、CodePipelineとCodeBuildでTerraformのplanとapplyを実行するようにした。
環境
- GitHub
- CodePipeline
- CodeBuild
hashicorp/terraform:0.11.14
コンテナ
- CodeBuild
CodePipelineのフロー
AWSのCodePipelineを用いてterraformのコードをデプロイするために、以下のフローにした。
ステップ | 処理内容 |
---|---|
Source | GitHubからソースコード取得 |
Plan | terraform planを実行 |
Approve | planの結果を見てapplyを実行するかを承認 |
Apply | terraform applyを実行 |
■ CodePipelineのフロー
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を実行するためにAWSのAPI-Keyが必要となる。buildspec.ymlに平文で定義するのはセキュリティ的に問題があるため今回はSSMパラメータで管理した。 SSMパラメータの管理をAnsibleで行う。方法は以前に作成したブログを参照。
- buildspec-{plan,apply}.ymlでSSMパラメータから値を取得する
- CodeBuildのIAMロールで
SSMReadOnly
の権限を付与する必要あり
- CodeBuildのIAMロールで
■ 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に設定する
- 参考
- s3-backend.tf
- 東京リージョンに暗号化オプション有効で保存する場合
terraform { required_version = ">= 0.11.0" backend "s3" { bucket = "保存するS3のバケット名" region = "ap-northeast-1" key = "terraform.tfstate" encrypt = true } }