Amazon CodeCatalyst で Terraform を使用する

こんにちは、稲葉です。
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の作成

本記事では、事前準備は終了済みであることを前提としています。

参考記事

Amazon CodeCatalystを使ってblueprintでアプリを作るまで - Qiita
CodeCatalyst挑戦の経緯仕事の案件とは全く関係ない趣味の範囲&自主学習用にWebアプリを作っております。今までは作ったものをローカルで動作させて、DBもSQLiteで…みたいな感じで作…
Amazon CodeCatalyst で AWS Lambda の CI/CD 環境を構築する
2023年4月にGAとなった「CodeCatalyst」を触ってみたので、それについてお話ししようと思います。

パイプラインの作成

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

タイトルとURLをコピーしました