
CodePipeline で簡単 Terraform CI/CD パイプラインの実装
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
今回は、CodeCommit への push をトリガーに CodeBuild で terraform apply する CodePipeline を作成してみたいと思います。ざっくり環境は以下のとおりです。
環境
- Terraform Backend
- S3
- DynamoDB
- CodeCommit
- CodeBuild
- CodePipeline
Terraform Backend の作成
今回は CI/CD パイプラインを使って Terraform を管理しますので、tfstate ファイルは共有可能な場所に保存する必要があります。また、このパイプラインは複数人が利用することが想定されるため、git push のタイミングによっては、同時に terraform apply が動作し tfstate に競合が発生してしまう可能性があります。
これらの課題は Terraform の Backend 機能を利用することで簡単に以下のような設定を行うことが出来ます。
- tfstate の保存先に S3 を利用
- DynamoDB を利用した State Locking の実装
それでは Backend で利用する S3 バケット、および DynamoDB テーブルを作成します。
S3 バケットの作成
- S3 管理コンソールを開き
Create Bucketをクリック - S3 バケット名を入力、リージョンを選択して[次へ]をクリック
- バージョニングとデフォルト暗号化を有効にして[次へ]をクリック
Block all public accessを選択して[次へ]をクリックし、バケットを作成
DynamoDB テーブルの作成
- DynamoDB 管理コンソールを開き、
Create tableをクリック - 任意のテーブル名を指定。例えば
terraform-state-lockのように指定します - 図のように、主キーとして
LockIDを指定し、Use default settingsにチェックして作成
Terraform 設定ファイル
Terraform ブロックの Backend 設定で、先ほど作成したバケット名およびテーブル名を指定します。
terraform {
required_version = ">= 0.12.0"
backend "s3" {
encrypt = true
bucket = "terraform-tfstate" <-- S3 バケット名
dynamodb_table = "terraform-state-lock" <-- DynamoDB テーブル名
key = "terraform.tfstate"
region = "ap-northeast-1"
}
}
provider "aws" {
region = "ap-northeast-1"
version = "~> 2.45"
}
CodeCommit 作成
- CodeCommit 管理コンソールから、
Create repositoryをクリック - リポジトリ名を入力し、
Createで作成します。作成後にリポジトリに移動します。 Create fileをクリック
4. readme.md のようなサンプルファイルを作成し、Commit changes をクリック
5. 今回は develop ブランチを使いたいので、左のメニューから Branches を開き Create branch をクリック
6. ブランチ名に develop を入力、from に master を指定し、Create branch をクリックしてブランチを作成
CI/CD パイプライン
CodePipeline 作成
- CodePipeline 管理コンソールから
Create pipelineをクリック - パイプライン名を入力し、
New service roleを選択してNextを選択
3. ソースプロバイダーに AWS CodeCommit を選択。先ほど作成したリポジトリと、develop ブランチを指定
4. 検出オプションは Amazon CloudWatch Events (recommended) を選択して Next を選択
5. ビルドプロバイダーに AWS CodeBuild を選択
6. Create Project をクリックし、ビルドプロジェクトを作成(別のウィンドウが起動します)
7. プロジェクト名を入力
8. [Environment Image]で Managed imageを選択し、以下のように選択
- Operating system:
Amazon Linux2 - Runtime:
Standard - Image:
aws/codebuild/amazonlinux2-x86_64-standard:2.0 - Image version:
Always use the latest image for this runtime version - Environment type:
Linux
9. [Privileged] の下にあるチェックボックスにチェックを入れ、New service role を選択
10. Buildspec のセクションは、Use a buildsped file を選択
11. Log セクションで、CloudWatch logs にチェックを入れ Continue to CodepiPeline をクリック
12. 元のウィンドウに戻り、[Environment variables] で以下の環境変数を設定し Next
- キー名:
TF_VERSION - 値:
0.12.19 - タイプ:
Plaintext
13. CodeDeploy は不要ですので、Skip deploy stage をクリック。
14. Create pipeline でパイプラインを作成
CodeBuild 用の IAM ロール設定
- IAM 管理コンソールを開き、[Roles]から先ほど CodeBuild 設定のなかで作成した IAM ロールを検索し、IAM ロール名をクリック
- [Permissions]タブを開き、[Attach policies]をクリック
- ビルド対象のリソース管理に必要なポリシーをアタッチ。(今回は
AdministratorAccessをアタッチしましたが、必要に応じて必要な権原に絞り込んでください)
CI/CD パイプラインの検証
CodeCommit への Git 接続設定
CodeCommit への接続は、IAM ユーザを作成して SSH や HTTPS で接続できます。設定方法等については、以下の記事を参照ください。
構成ファイルの準備
先ほど作成した config.tf を含めて、以下のファイルを準備します。
- config.tf
- buildspec.yml
- s3.tf (今回は S3 バケットの作成で動作確認します)
buildspec.yml では、Terraform のダウンロード、インストールを行います。バージョンの指定は CodePipeline 設定のなかで CodeBuild 向けの環境変数として設定した TF_VERSION で指定します。pre_build 内の terraform init や terraform plan でエラーがあった場合は、build は実行されずエラー終了します。今回は特に承認処理等を入れていないので、terraform plan が正常処理されると、そのまま terraform apply まで実行されます。(ローカル環境で事前に terraform plan を行い、変更、削除されるリソースを確認してください)
version: 0.2
phases:
install:
runtime-versions:
docker: 18
commands:
- yum install unzip -y
- wget https://releases.hashicorp.com/terraform/"$TF_VERSION"/terraform_"$TF_VERSION"_linux_amd64.zip
- unzip terraform_"$TF_VERSION"_linux_amd64.zip
- mv terraform /usr/local/bin/
pre_build:
commands:
- terraform init -input=false -no-color
- terraform plan -input=false -no-color
build:
commands:
- terraform apply -input=false -auto-approve -no-color
post_build:
commands:
- echo terraform apply completed on `date`
S3 バケットを 1 つ作成するだけの簡単な tf ファイルとしました。
resource "aws_s3_bucket" "cm-terraform-000" {
bucket = "cm-terraform-000"
acl = "private"
}
CodeCommit リポジトリへの push
CodeCommit リポジトリの develop ブランチに push します。
marumo.atsushi@:~/Project/terraform-cicd (develop) $ ls -l total 32 -rw-r--r-- 1 marumo.atsushi staff 607 1 21 08:51 buildspec.yml -rw-r--r-- 1 marumo.atsushi staff 314 1 21 08:51 config.tf -rw-r--r-- 1 marumo.atsushi staff 6 1 21 08:46 readme.md -rw-r--r-- 1 marumo.atsushi staff 192 1 21 08:51 s3.tf $ git add . $ git commit -m "Initial commit" [develop 8b78804] Initial commit 3 files changed, 48 insertions(+) create mode 100644 buildspec.yml create mode 100644 config.tf create mode 100644 s3.tf $ git push Warning: Permanently added 'git-codecommit.ap-northeast-1.amazonaws.com,52.119.218.16' (RSA) to the list of known hosts. Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 883 bytes | 883.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0) To ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-cicd ea86283..8b78804 develop -> develop
しばらくすると CodePipeline が動作し、CodeBuild が実行されます。
もしエラーになっている場合は、ビルドプロジェクトの [Details] をクリックし、ビルド実行時の Tail ログを確認しながらトラブルシューティングしてください。
S3 バケットも正常に作成されていますね。
検証は以上です。
さいごに
Code シリーズを使った簡単な Terraform CI/CD パイプラインを作成してみました。今回は単に terraform apply を実行する単純なパイプラインでしたので、次は Terraform workspace と絡めて、環境によっては terraform apply 前に承認プロセスを必要とするようなパイプラインを検討してみたいと思います。
以上!大阪オフィスの丸毛(@marumo1981)でした!






















