こんにちは、稲葉です。
Amazon CodeCatalystでTerraformを使用する方法を学習したのでご紹介いたします。
構築する環境
Amazon CodeCatalystで以下のようなパイプラインを作成します。
featureブランチからにpushされたとき、検証環境にリソースを作成するようにします。
mainブランチからにpushされたとき、本番環境にリソースを作成するようにします。
本記事では以下のようなVPCを作成します。
検証環境には検証VPCを作成し、本番環境には本番VPCを作成します。
また、検証VPCと本番VPCは同一AWSアカウントに作成しています。
Terraformコード
Terraformコードは以下のようになります。
.
├── environments # 環境管理ディレクトリ
│ ├── stg # 検証環境用ディレクトリ
│ │ ├── stg.tfbackend # tfstateの管理場所を指定するファイル
│ │ └── stg.tfvars # 変数に指定するパラメータを定義するファイル
│ └── prd # 本番環境用ディレクトリ
│ ├── prd.tfbackend # tfstateの管理場所を指定するファイル
│ └── prd.tfvars # 変数に指定するパラメータを定義するファイル
└─── main.tf # リソースを定義するファイル
main.tf
Terraformで作成するリソースを定義します。
terraform {
backend s3 {}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.57.0"
}
}
}
provider "aws"{
region = "ap-northeast-1"
}
variable name_prefix {}
variable vpc {}
variable public_subnet_1a {}
variable private_subnet_1a {}
variable public_subnet_1c {}
variable private_subnet_1c {}
# VPC
resource aws_vpc vpc {
cidr_block = lookup(var.vpc, "cidr_block")
instance_tenancy = lookup(var.vpc, "instance_tenancy")
enable_dns_support = lookup(var.vpc, "enable_dns_support")
enable_dns_hostnames = lookup(var.vpc, "enable_dns_hostnames")
tags = {
Name = format("%s-%s",var.name_prefix, lookup(var.vpc, "name_tag"))
}
}
# パブリックサブネット AZ-1a
resource aws_subnet public_subnet_1a {
vpc_id = aws_vpc.vpc.id
cidr_block = lookup(var.public_subnet_1a, "cidr_block")
availability_zone = lookup(var.public_subnet_1a, "availability_zone")
tags = {
Name = format("%s-%s",var.name_prefix, lookup(var.public_subnet_1a, "name_tag"))
}
}
# プライベートサブネット AZ-1a
resource aws_subnet private_subnet_1a {
vpc_id = aws_vpc.vpc.id
cidr_block = lookup(var.private_subnet_1a, "cidr_block")
availability_zone = lookup(var.private_subnet_1a, "availability_zone")
tags = {
Name = format("%s-%s",var.name_prefix, lookup(var.private_subnet_1a, "name_tag"))
}
}
# パブリックサブネット AZ-1c
resource aws_subnet public_subnet_1c {
vpc_id = aws_vpc.vpc.id
cidr_block = lookup(var.public_subnet_1c, "cidr_block")
availability_zone = lookup(var.public_subnet_1c, "availability_zone")
tags = {
Name = format("%s-%s",var.name_prefix, lookup(var.public_subnet_1c, "name_tag"))
}
}
# プライベートサブネット AZ-1c
resource aws_subnet _private_subnet_1c {
vpc_id = aws_vpc.vpc.id
cidr_block = lookup(var.private_subnet_1c, "cidr_block")
availability_zone = lookup(var.private_subnet_1c, "availability_zone")
tags = {
Name = format("%s-%s",var.name_prefix,lookup(var.private_subnet_1c, "name_tag"))
}
}
environments/stg/stg.tfbackend
Terraformの状態を管理するファイル(tfstate)をどのように管理するかを定義します。
検証環境と本番環境のそれぞれで別のtfstateを作成し、このファイルでは検証環境のtfstateを担当します。
bucket = <tfstateを置くS3バケット名>
key = <tfstateを置くS3バケットのキー>
region = "ap-northeast-1"
environments/stg/stg.tfvars
検証環境のパラメータを定義します。
name_prefix = "stg-codecatalyst-test"
vpc = {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
name_tag = "vpc"
}
public_subnet_1a = {
cidr_block = "10.1.0.0/24"
availability_zone = "ap-northeast-1a"
name_tag = "public-subnet-1a"
}
private_subnet_1a = {
cidr_block = "10.1.2.0/24"
availability_zone = "ap-northeast-1a"
name_tag = "privatec-subnet-1a"
}
public_subnet_1c = {
cidr_block = "10.1.1.0/24"
availability_zone = "ap-northeast-1c"
name_tag = "public-subnet-1c"
}
private_subnet_1c = {
cidr_block = "10.1.3.0/24"
availability_zone = "ap-northeast-1c"
name_tag = "private-subnet-1c"
}
environments/prd/prd.tfbackend
Terraformの状態を管理するファイル(tfstate)をどのように管理するかを定義します。
検証環境と本番環境のそれぞれで別のtfstateを作成し、このファイルでは本番環境のtfstateを担当します。
bucket = <tfstateを置くS3バケット名>
key = <tfstateを置くS3バケットのキー>
region = "ap-northeast-1"
environments/prd/prd.tfvars
本番環境のパラメータを定義します。
name_prefix = "prd-codecatalyst-test"
vpc = {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
name_tag = "vpc"
}
public_subnet_1a = {
cidr_block = "10.0.0.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-1a"
name_tag = "public-subnet-1a"
}
private_subnet_1a = {
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-1a"
name_tag = "privatec-subnet-1a"
}
public_subnet_1c = {
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "ap-northeast-1c"
name_tag = "public-subnet-1c"
}
private_subnet_1c = {
cidr_block = "10.0.3.0/24"
availability_zone = "ap-northeast-1c"
name_tag = "privatec-subnet-1c"
}
パイプラインの設定
Terraformの事前準備
事前にTerraformの状態を管理するファイル(tfstate)を管理するためのS3バケットが必要になります。
検証環境と本番環境用に2つS3バケットを作成します。
その後下記ファイルそれぞれで、作成したバケット名をbucketに、キーをkeyに指定します。
- environments/stg/stg.tfbackend
- environments/prd/prd.tfbackend
Amazon CodeCatalystの事前準備
Amazon CodeCatalystの利用には下記のような事前準備が必要です。
- AWS Builders IDの取得
- Amazon CodeCatalyst Spaceの作成
- Amazon CodeCatalyst用IAM Roleの作成
本記事では、事前準備は終了済みであることを前提としています。
参考記事


パイプラインの作成
AWSコンソールのAmazon CodeCatalystから作成したSpaceを選択し、”Go to Amazon CodeCatalyst”ボタンを押すことで、CodeCatalystを使用できます。
プロジェクトの作成
まずAmazon CodeCatalystプロジェクトを作成します。
Start from scratchを選択して作成してください。
リポジトリの作成
その後リポジトリを作成します。
開発環境へアクセス、コードのリポジトリ登録
リポジトリにアクセスできる開発環境の設定を行います。
Code -> Dev Environments -> Create Dev Environment -> AWS Cloud9で開発環境を作ります。
AWS Cloud9に入れたら、リポジトリ名と同じフォルダにTerraformのコードを作成します。
その後リポジトリにPushします。
$ cd projects/<リポジトリ名と同じフォルダ>
$ git add main.tf
$ git add environments/*
$ git commit -m "first commit"
$ git push
デプロイ先の設定
次にデプロイ先の設定をします。
CI/CD -> Environments -> Create environment で設定を行います。
本番環境と検証環境のデプロイ先を設定しました。
IAM RoleはAWSコンソールのAmazon CodeCatalystスペースメニューで、IAM roles available to CodeCatalystを探し、登録されているIAM Roleを選択してください。
Workflowの作成
Terraform用のWorkflowを2つ作成します。
CI/CD -> Workflows -> Create workflow で設定を行います。
featureブランチからにpushされたときのWorkflow
検証環境用のWorkflowを作成します。
Triggerをクリックし、下記のようにトリガーの設定を行います。
その後、Workflowページの左上のActionをクリックし、Buildを追加します。
下記のようにBuildの設定をします。
- Inputsタブ
- Sources: WorkflowSource
- Configuration
- Compute type: EC2
- Environment: stg
Shell commandsに以下のコードを貼り付けます。
下記コードでTerraformがインストールされて検証環境にVPCがデプロイされます。
- Run: wget https://releases.hashicorp.com/terraform/1.8.5/terraform_1.8.5_linux_amd64.zip
- Run: yum install unzip -y
- Run: unzip terraform_1.8.5_linux_amd64.zip
- Run: mv terraform /usr/local/bin/
- Run: terraform -version
- Run: terraform init -backend-config="environments/stg/stg.tfbackend" -reconfigure
- Run: terraform plan -var-file="environments/stg/stg.tfvars"
- Run: terraform apply -var-file="environments/stg/stg.tfvars" -auto-approve
貼り付け後、commitを押して保存します。
mainブランチからにpushされたときのWorkflow
本番環境にリソースを作成するようにします。
Triggerの設定は、mainブランチへのpush時を設定します。
その後のBuildの設定は、下記のように行います。
- Inputsタブ
- Sources: WorkflowSource
- Configuration
- Compute type: EC2
- Environment: prd
Shell commandsには以下のコードを貼り付けます。
下記コードで本番環境にVPCがデプロイされます。
- Run: wget https://releases.hashicorp.com/terraform/1.8.5/terraform_1.8.5_linux_amd64.zip
- Run: yum install unzip -y
- Run: unzip terraform_1.8.5_linux_amd64.zip
- Run: mv terraform /usr/local/bin/
- Run: terraform -version
- Run: terraform init -backend-config="environments/prd/prd.tfbackend" -reconfigure
- Run: terraform plan -var-file="environments/prd/prd.tfvars"
- Run: terraform apply -var-file="environments/prd/prd.tfvars" -auto-approve
本来は承認フェーズを挟んでからデプロイする方法があるのですが、本記事では省きます。
貼り付け後、commitを押して保存します。
パイプラインを走らせる
Code -> Dev Environments で開発環境にアクセスします。
開発環境と本番環境をそれぞれpushして、VPCがデプロイされるか確認します。
Readmeファイルなどを変更してpushすると、VPCがデプロイされるか確認します。
$ git add README.md
$ git commit -m "更新: README.md"
$ git push
$ git branch feature/test
$ git checkout feature/test
$ git add README.md
$ git commit -m "更新: README.md"
$ git push --set-upstream origin feature/test
上記のコマンドを打つことで、Workflowが2つ走ると思います。
開発環境と本番環境の2つVPCが作成されていれば完了です。
最後に
Amazon CodeCatalystでTerraformを使ってみましたが、Amazon CodeCatalystの情報が少なく難しかったです。
今回できなかったことなのですが、
Amazon CodeCatalystにはTerraform用のプリセットがあります。
使ってみたのですが、tfvarsファイルの情報を取得できずなかなかうまくいきませんでした。
次はこのプリセットを使えるようにしたいです。