はじめに
こんばんは。
今回は以下の本を読んで勉強中です。
今までの記事はこちら
# 実践 Terraformを読んでTerraform勉強中 Vol.1 - もがき系プログラマの日常
# 実践 Terraformを読んでTerraform勉強中 Vol.2 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.3 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.4 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.5 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.6 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.7 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.8 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.9 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.10 - もがき系プログラマの日常
実践 Terraformを読んでTerraform勉強中 Vol.11 - もがき系プログラマの日常
今回も第14章です。
バージョンは以下です。
$ terraform --version Terraform v1.0.3
本題
第14章 デプロイメントパイプライン(CodePipeline以降)
まず最初に、前回のcodebuildでやってなかった部分の buildspec.yml を作成します。
コンテンツはこのような感じでファイルを置きます。
$ tree contents
contents
├── Dockerfile
├── buildspec.yml
├── example.conf
└── src
└── index.html
buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
docker: 18
pre_build:
commands:
- $(aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin https://xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com)
- REPO=$(aws ecr describe-repositories --repository-names example --output text --query "repositories[0].repositoryUri)
- IMAGE=$REPO:latest
build:
commands:
- docker build -t $IMAGE contents
- docker pull $IMAGE
post_build:
commands:
- printf '[{"name":"example", "imageUrl":"%s"}]' $IMAGE > imagedefinitions.json
artifacts:
files: imagedefinitions.json
次に codepipelineのポリシードキュメントとIAMロールを作成します。
# ポリシードキュメント
data "aws_iam_policy_document" "codepipeline" {
statement {
effect = "Allow"
resources = ["*"]
actions = [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning",
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"ecs:DescribeTasks",
"ecr:ListTasks",
"ecr:RegisterTaskDefinition",
"ecr:UpdateService",
"iam:PassRole",
]
}
}
# IAMロール
module "codepipeline_role" {
source = "./iam"
name = "codepipeline"
identifier = "codepipeline.amazonaws.com"
policy = data.aws_iam_policy_document.codepipeline.json
}
# アーティファクト用S3バケット
resource "aws_s3_bucket" "artifact" {
bucket = "kojirock-artifact-pragmatic-terraform"
lifecycle_rule {
enabled = true
expiration {
days = "180"
}
}
}

また、Exportしておきます
$ export GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
codepipeline構築のためのコードを書きます。
長い...
resource "aws_codepipeline" "example" {
name = "example"
role_arn = module.codepipeline_role.iam_role_arn
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "ThirdParty"
provider = "GitHub"
version = 1
output_artifacts = ["Source"]
configuration = {
Owner = "xxxxxxxxxxxxx"
Repo = "xxxxxxxxxxxxx"
Branch = "main"
PollForSourceChanges = false
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = 1
input_artifacts = ["Source"]
output_artifacts = ["Build"]
configuration = {
ProjectName = aws_codebuild_project.example.id
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
category = "Deploy"
owner = "AWS"
provider = "ECS"
version = 1
input_artifacts = ["Build"]
configuration = {
ClusterName = aws_ecs_cluster.example.name
ServiceName = aws_ecs_service.example.name
FileName = "imagedefinitions.json"
}
}
}
artifact_store {
location = aws_s3_bucket.artifact.id
type = "S3"
}
}
githubからのwebhook受付のためのコードを書きます。
resource "aws_codepipeline_webhook" "example" {
name = "example"
target_pipeline = aws_codepipeline.example.name
target_action = "Source"
authentication = "GITHUB_HMAC"
authentication_configuration {
secret_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
filter {
json_path = "$.ref"
match_equals = "refs/heads/{Branch}"
}
}
githubのプロバイダを定義します
provider "github" {
organization = "xxxxxxxxxxxxx"
}
今度はgithub側のwebhook通知のためのコードを書きます。
resource "github_repository_webhook" "example" {
repository = "xxxxxxxxxxxxx"
configuration {
url = aws_codepipeline_webhook.example.url
secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
content_type = "json"
insecure_ssl = false
}
events = ["push"]
}
終わりに
写経して思ったのですが、これ全部理解しているものなのでしょうか...
やってて長すぎて頭おかしくなりそうでした...
ちょっとここはもう一度やりたいと思います。
現場からは以上です。
