CodeBuildのカスタム環境の作成

CodeBuildのDeploy環境は通常AWSが提供している。しかし、Deployするアプリによっては、CodeBuild実行時に追加でパッケージをダウンロードする場合がある。その時は、AWSが提供するデフォルトのコンテナイメージではなく、必要なパッケージを準備したカスタムイメージを使用することで、時間とトラフィックを節約できる。

Angularのビルド用イメージ

Angularが使用するパッケージを記載したpackage.json を予め準備する必要がある。

FROM ubuntu:18.04

WORKDIR /usr/src/app
COPY package.json ./

RUN apt-get update -y && apt-get install curl -y
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
RUN npm update
RUN npm install -g typescript
RUN npm install -g @angular/cli
RUN npm install
RUN npm install @angular-devkit/build-angular
RUN npm install @angular/compiler-cli
RUN npm install @angular/compiler

RUN apt-get install zip -y
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

ビルドしたコンテナイメージをECRにPushする。他アカウントのCodeBuildがPullできるためには、ECRのPolicyを設定する必要がある。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CodeBuildAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "CodeBuildのRoleのARN"  
      },
      "Action": [
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability"
      ]
    }
  ]
}

CloudFormationでCodeBuildを作成する場合、ImageImagePullCredentialsType は以下のように設定する必要がある。

Resources:
  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Description: Build bat Program.
      EncryptionKey: !Sub arn:aws:kms:ap-northeast-1:${SourceAccount}:key/${KmsId}
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/angular:latest
        ImagePullCredentialsType: SERVICE_ROLE
        Type: LINUX_CONTAINER
        EnvironmentVariables:
          - Name: AWS_DEFAULT_REGION
            Value: ap-northeast-1
          - Name: AWS_ACCOUNT_ID
            Value: !Sub ${AWS::AccountId}
          - Name: S3_Contents_Bucket_Name
            Value: !Ref S3ContentsBucketName
      Name: !Sub CodeBuildProject-${CodeCommitRepositoryName}
      ServiceRole: !ImportValue CodeBuildRole
      Source:
        Type: CODEPIPELINE

CodeBuildのbuildspec.ymlは以下のような感じで設定する。

version: 0.2

phases:
  pre_build:
    commands:
      - npm cache clean --force
      - cp -r /usr/src/app/node_modules/ ./
  build:
    commands:
      - echo Build started
      - ng build
  post_build:
    commands:
      - echo post_build
      - aws s3 sync dist/webapp s3://$S3_Contents_Bucket_Name --delete
artifacts:
  files:
    - "**/*"
  base-directory: "dist*"
  discard-paths: yes

Mavenのビルド用イメージ

Mavenのビルド時に使用するレポジトリは/home/username/.m2/repository内に保管される。mvn verifyでレポジトリをローカルにダウンロードできる。これをMavenのバイナリをコンテナ内に置く必要がある。

FROM ubuntu:18.04

WORKDIR /usr/src/app
COPY apache-maven-3.6.3 ./apache-maven-3.6.3

RUN apt-get update -y
RUN apt-get install openjdk-11-jdk -y
ENV PATH="/usr/src/app/apache-maven-3.6.3/bin:${PATH}"

WORKDIR /root/.m2/repository
COPY repository /root/.m2/repository

RUN apt-get install curl -y
RUN apt-get install zip -y
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

RUN apt-get install apt-transport-https ca-certificates gnupg-agent software-properties-common -y
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
RUN apt-get install docker-ce docker-ce-cli containerd.io -y

buildspec.ymlは以下のような感じとなる。

version: 0.2

phases:
  pre_build:
    commands:
      - echo pre_build
      - service docker start
      - echo Logging in to Source Account ECR...
      - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $SOURCE_AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
  build:
    commands:
      - echo build
      - mvn package
      - mv $CODEBUILD_SRC_DIR/target/app.jar .
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - echo Logging in to Local Account ECR...
      - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
      - printf '{"Version":"1.0","ImageURI":"%s"}' $AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imageDetail.json
artifacts:
  files:
    - imageDetail.json
    - appspec.yaml
    - taskdef.json
タイトルとURLをコピーしました