TerragruntでCodeBuild上dockerイメージをビルドできる環境構築

# はじめに
<!-- 発端や概要を記載 -->
本記事はAWS環境においてCodeBuildを使って、ビルド成功したimageをECRにpushする方法について記載しています。

# 構成
![スクリーンショット 2024-03-16 14.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/05284a5f-8969-f274-8ca1-68973582de9e.png)



# 目次
<!-- タイトルとアンカー名を編集 -->
1. [ECRのTerraformコード作成](#ECRのTerraformコード作成)
1. [ECRのTerragruntコード作成](#ECRのTerragruntコード作成)
1. [CodeBuildのTerragruntコード作成](#CodeBuildのTerragruntコード作成)
1. [ECRのTerragruntコード作成](#ECRのTerragruntコード作成)
1. [CodeBuildのbuildspec.yml作成](#CodeBuildのbuildspec.yml作成)
1. [terragruntでコードをデプロイする](#terragruntでコードをデプロイする)



<!-- 各チャプター -->
<a id="#ECRのTerraformコード作成"></a>
# ECRのTerraformコード作成

ECR リポジトリのライフサイクルポリシーは[aws_ecr_lifecycle_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_lifecycle_policy)で管理します。
また、ecr_repositoryのリポジト名はterragrunt.hclのinputsから受け取る形にします。

```言語名:aws/common/ecr/main.tf
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
  }
}

resource "aws_ecr_lifecycle_policy" "policy" {
  repository = aws_ecr_repository.this.name

  policy = jsonencode({
    "rules" : [
      {
        "rulePriority" : 1,
        "description" : var.description,
        "selection" : {
          "tagStatus" : "any",
          "countType" : "imageCountMoreThan",
          "countNumber" : var.count_number
        },
        "action" : {
          "type" : "expire"
        }
      }
    ]
  })
}

```

```言語名:aws/common/ecr/output.tf
output "ecr_repository" {
  value = aws_ecr_repository.this
}
```

```言語名:aws/common/ecr/variables.tf
variable "repository_name" {
  type = string
}

variable "description" {
  type        = string
  description = "ecrライフサイクルルールの説明"
}

variable "count_number" {
  type        = number
  description = "ecr制限するタグ数"
}
```

<a id="#ECRのTerragruntコード作成"></a>
# ECRのTerragruntコード作成

```言語名:aws/terragrunt/ecr/terragrunt.hcl
include "root" {
  path = find_in_parent_folders()
}

include "template" {
  // ecrのterraformのルートパス
  path = "../../common/ecr"
}

inputs = {
  // common/ecr/variables.tfの値はここで記入します
  repository_name = "repository_name"
  description     = "最後の5つのタグを保留する"
  count_number    = 5
}

```

<a id="#CodeBuildのTerragruntコード作成"></a>
# CodeBuildのTerragruntコード作成

```言語名:aws/terragrunt/codebuild/terragrunt.hcl
include "root" {
  path = find_in_parent_folders()
}

dependency "ecr" {
  config_path = "../ecr/dev"
}


inputs = {
  project_name            = "project_name"
  project_description     = "project_description"
  type                    = "ARM_CONTAINER"
  image                   = "aws/codebuild/amazonlinux2-aarch64-standard:3.0"
  build_timeout           = 120
  buildspec               = "codebuild/buildspec.yml"
  primary_repository_name = "primary_repository_name"
  ssm_github_token_name   = "ssm_github_token_name"
  privileged_mode         = true
  attach_iam_policie_names = ["AWSCodeBuildAdminAccess", "AmazonVPCFullAccess", "AmazonEC2ContainerRegistryFullAccess"]
  // vpcは必要に応じて別途作成
  vpc_id                   = vpc_id
  // security_groupは必要に応じて別途作成
  security_group_ids       = security_group_ids
　　　　// subnetsは必要に応じて別途作成
  subnets                  = dependency.nw.outputs.main_subnet_private_ids
  　// s３は必要に応じて別途作成
  bucket                   = bucket
  env_vars = {
    AWS_ACCOUNT_ID  = get_aws_account_id()
    IMAGE_REPO_NAME = dependency.ecr.outputs.ecr_repository.name
    IMAGE_TAG       = ""
    TARGET_DIR      = ""
  }
}


```


<a id="#CodeBuildのbuildspec.yml作成"></a>
# CodeBuildのbuildspec.yml作成

```言語名:aws/codebuild/buildspec.yml
version: 0.2

phases:
  install:
    commands:
      # Terraformのインストール（バージョン確認）
      - |
        if ! terraform --version | grep "1.5.7"; then
          wget https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip
          sudo unzip -o terraform_1.5.7_linux_amd64.zip -d /usr/local/bin/
        fi
      - terraform --version

      # Terragruntのインストール（バージョン確認）
      - |
        if ! terragrunt --version | grep "v0.54.10"; then
          wget https://github.com/gruntwork-io/terragrunt/releases/download/v0.54.10/terragrunt_linux_amd64
          chmod +x terragrunt_linux_amd64
          sudo mv -f terragrunt_linux_amd64 /usr/local/bin/terragrunt
        fi
      - terragrunt --version

  pre_build:
    commands:
      - echo Pre-build phase...
      - cd ./
      - export BUILD_ROOT_DIR=$(pwd)

  build:
    commands:
      - echo Build phase...
      # Build
      - echo ----------------------------------
      - echo Build common
      - echo ----------------------------------
      - cd $BUILD_ROOT_DIR
      - terragrunt run-all $TERRAGRUNT_CMD --terragrunt-non-interactive

      - echo ----------------------------------
      - echo Build container
      - echo ----------------------------------
      - cd $BUILD_ROOT_DIR
      - terragrunt run-all $TERRAGRUNT_CMD --terragrunt-non-interactive --terragrunt-include-external-dependencies


cache:
  paths:
    - /usr/local/bin/**/*

```


<a id="#terragruntでコードをデプロイする"></a>
# terragruntでコードをデプロイする

[terragruntインストール手順](https://terragrunt.gruntwork.io/docs/getting-started/install/)


```言語名:terragruntでコードをデプロイ
terragrunt plan　// コードが正しいか確認できる
terragrunt apply　// コードをデプロイ
```

awsのcodebuildでデプロイしたビルドプロジェクトに対して、上書きでビルドを開始するボタンを押す。
aws/terragrunt/codebuild/terragrunt.hclのenv_varsが空欄の引数は以下の環境変数に入力し、ビルドを開始する。
![スクリーンショット 2024-03-17 14.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/46d8a79b-2e75-3e09-ca47-8c0cbbace941.png)