👽

【AWS】CodeBuildでterraformにCICDを組む

2023/08/08に公開

初めに

terraform v1.5.0で importブロックなるものが追加された。これがものすごくいい機能で
従来だと

  • terraform importコマンドを使用していた
  • importをするにはリソースを1つずつチマチマimportしていた
  • tfファイルに記述する際にtfstateファイルに書かれた内容を見ながら記述していた
  • import結果が予測しずらい

これがimportブロックが出来た事で

  • コード内で完結するようになった
  • 複数のリソースをimport出来るようになった
  • tfファイルは自動で作られる
  • import結果を予測できる

様になったのでimport絡みの作業がすごく楽になる

今回やる事

以前CI/CDを組む際に作ったCodeBuildとロールとポリシーをimportブロックを使ってterraform管理下にする。

importブロックを用いてterraform管理下にする

id と toだけ書けばOK

参考:https://developer.hashicorp.com/terraform/language/import
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/codebuild_project#import
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role#import
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy#import

imports.tf の作成

#CodeBuild
import {
  to = aws_codebuild_project.terraform_apply
  id = "terraform-apply"
}

import {
  to = aws_codebuild_project.terraform_dryrun
  id = "terraform-dryrun"
}

#ロール
import {
  to = aws_iam_role.terraform_plan
  id = "codebuild-s-service-role"
}

import {
  to = aws_iam_role.terraform_plan
  id = "codebuild-t-service-role"
}

#ポリシー
import {
  to = aws_iam_policy.terraform_apply
  id = "arn:aws:iam::${userID}:policy/service-role/CodeBuildBasePolicy-terraform-apply-ap-northeast-1"
}

import {
  to = aws_iam_policy.terraform_dryrun
  id = "arn:aws:iam::${userID}:policy/service-role/CodeBuildBasePolicy-terraform-dryrun-ap-northeast-1"
}

concurrent_build_limitを修正する

CodeBuildの同時ビルド制限を設定していなとconcurrent_build_limitの値が0になりPlanがこける。
importブロックを使った時のバグっぽいので一旦 "1" に設定する。

tfファイルを作る

まずはGUIを参照し、codebuild.tfを作成する以下のコマンドを実行

terraform init
terraform plan -generate-config-out="codebuild.tf"

公開したくない情報をCodeBuildの環境変数に指定してそれをshellに渡す

環境変数をCodeBuildに設定

  • CodeBuild → 対象プロジェクトを選択 → 編集 → 環境 の "環境変数" から設定

環境変数を渡すようにコードを修正

scripts/dryrun.sh の修正

#!/bin/sh
set -ex
terraform init -var USERID=${userID} -input=false -no-color -backend-config="key=terraform.tfstate" -backend-config="bucket=zukkie-terraform-state"
terraform plan -no-color -var USERID=${userID}

scripts/apply.sh の修正

#!/bin/sh
set -ex
terraform init -var USERID=${userID} -input=false -no-color -backend-config="key=terraform.tfstate" -backend-config="bucket=zukkie-terraform-state"
terraform apply -auto-approve -no-color -var USERID=${userID}

variable.tf の作成

variable "USERID" {}

codebuild.tfの修正

  • userID には作成した環境変数を使うのでuserIDの数字を ${USERID}に変更する
  • ignore_changes を作成した環境変数を消さない様にする

importの実施

codebuild.tfが出来たら以下のコマンドでimportを実行

terraform apply
※USERIDを手入力

GUI上とterraformに差分がない事を確認する

terraform Planで差分がなければ無事terraform管理下になっている。

terraform plan
※USERIDを手入力

CI/CDでもうまくいくことを確認

PRを作ってマージして確認

最終的なコード

https://github.com/zukizukizuki/aws-terraform/tree/0f4d80efcc70919ea1bd80f7ed2962e53c9f1c7c

追記 ※2023/8/1

Terraform v1.5.4 時点では import ブロックの id には文字列しか指定できません。
Variableを使用すると以下のエラーが出ます。
※Local Value , リソースの attribute でも同様

Error: Unsuitable value type

  on imports.tf line 26, in import:
  26:   id = "arn:aws:iam::${var.USERID}:policy/service-role/CodeBuildBasePolicy-terraform-apply-ap-northeast-1"

Unsuitable value: value must be known

Error: Variables not allowed

  on imports.tf line 26, in import:
  26:   id = "arn:aws:iam::${var.USERID}:policy/service-role/CodeBuildBasePolicy-terraform-apply-ap-northeast-1"

Variables may not be used here.
GitHubで編集を提案

Discussion