NorthNest
AWS

AWS CodeBuildでDockerイメージをビルドしECRへPushする方法(Terragrunt対応)

📅 2024年3月16日
✍️ 王 家豪
#AWS
#CodeBuild
#Terraform
#Docker
#ECR
#Terragrunt
#IAM
#GitHub

はじめに

本記事では、AWS環境において CodeBuildを使ってDockerイメージをビルドし、ECRへPushする方法 を解説します。

Terraform / TerragruntによるIaC構成に加え、以下の実践的な内容も含めています。

  • Docker build / push コマンドの詳細
  • IAMロールの最小権限設計
  • GitHubとの連携(OAuth / Webhook)
  • Qiita・Zenn向けMarkdown構成の最適化

構成

構成図

目次

  1. ECRのTerraformコード作成
  2. ECRのTerragruntコード作成
  3. CodeBuildのTerragruntコード作成
  4. Docker build / push コマンドの詳細
  5. CodeBuildのbuildspec.yml作成
  6. IAMロールの最小権限設計
  7. GitHub連携(OAuth / Webhook)
  8. Terragruntでコードをデプロイする
  9. Qiita・Zenn向けMarkdown最適化

ECRのTerraformコード作成

ECRリポジトリはTerraformで管理します。
ライフサイクルポリシーを設定することで、不要なイメージを自動削除できます。

resource "aws_ecr_repository" "this" {
  name                 = var.repository_name
  image_tag_mutability = "MUTABLE"

  encryption_configuration {
    encryption_type = "AES256"
  }

  image_scanning_configuration {
    scan_on_push = true
  }
}

ECRのTerragruntコード作成

inputs = {
  repository_name = "repository_name"
  description     = "最後の5世代を保持"
  count_number    = 5
}

CodeBuildのTerragruntコード作成

CodeBuildプロジェクトでは privileged_mode = true を必ず有効にします。
(Docker build に必要)

env_vars = {
  AWS_ACCOUNT_ID  = get_aws_account_id()
  IMAGE_REPO_NAME = dependency.ecr.outputs.ecr_repository.name
  IMAGE_TAG       = "latest"
  TARGET_DIR      = "."
}

Docker build / push コマンドの詳細

CodeBuild内では以下の流れでDockerイメージをECRへPushします。

1. ECRへログイン

aws ecr get-login-password   | docker login   --username AWS   --password-stdin   {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com

2. Dockerイメージのビルド

docker build -t {IMAGE_REPO_NAME}:{IMAGE_TAG} {TARGET_DIR}

3. タグ付け

docker tag   {IMAGE_REPO_NAME}:{IMAGE_TAG}   {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/{IMAGE_REPO_NAME}:{IMAGE_TAG}

4. ECRへPush

docker push   {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/{IMAGE_REPO_NAME}:{IMAGE_TAG}

CodeBuildのbuildspec.yml作成

version: 0.2

phases:
  pre_build:
    commands:
      - aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com

  build:
    commands:
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

IAMロールの最小権限設計

CodeBuild用IAMロールには以下の権限が最低限必要です。

ECR操作

{
  "Effect": "Allow",
  "Action": [
    "ecr:GetAuthorizationToken",
    "ecr:BatchCheckLayerAvailability",
    "ecr:PutImage",
    "ecr:InitiateLayerUpload",
    "ecr:UploadLayerPart",
    "ecr:CompleteLayerUpload"
  ],
  "Resource": "*"
}

CloudWatch Logs

{
  "Effect": "Allow",
  "Action": [
    "logs:CreateLogGroup",
    "logs:CreateLogStream",
    "logs:PutLogEvents"
  ],
  "Resource": "*"
}

GitHub連携(OAuth / Webhook)

OAuth連携

  • CodeBuildの「ソース」で GitHub (OAuth) を選択
  • GitHubアカウントと連携
  • プライベートリポジトリも利用可能

Webhook

  • GitHubのPushイベントをトリガーにビルド開始
  • ブランチ制御が可能(mainのみ等)

CI用途では Webhook連携が推奨 です。

Terragruntでコードをデプロイする

terragrunt plan
terragrunt apply

CodeBuildの「ビルドを開始」から
IMAGE_TAGTARGET_DIR を環境変数として指定します。

Qiita・Zenn向けMarkdown最適化

  • 見出しは ## 単位で区切る
  • コードブロックは必ず言語指定
  • 画像はセクション直下に配置
  • 目次リンクは自動生成前提でOK

Qiita / Zenn 両対応の構成になっています。

まとめ

本構成を採用することで、

  • IaCによる再現性の高い環境構築
  • Dockerイメージの自動ビルド & Push
  • セキュアなIAM最小権限設計
  • GitHub連携によるCI構築

が実現できます。

実運用のCI/CD基盤として、そのまま流用可能な構成です。

AI活用についてご相談ください

貴社のビジネス課題に最適なAIソリューションをご提案いたします