こんにちは、稲葉です。
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ファイルの情報を取得できずなかなかうまくいきませんでした。
次はこのプリセットを使えるようにしたいです。