0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Batch の CI/CD を試してみる

Posted at

概要

AWS Batch の理解のために以下のハンズオンを実施してみた。

なお、一部手順は手動から CLI または CloudFormation で実行するようにアレンジしています。

事前準備

CloudFormation のデプロイ

必要な AWS リソースを CloudFormation でデプロイしておきます。

wget https://static.us-east-1.prod.workshops.aws/public/66da963d-7962-425a-bf2b-082e9436fb97/static/handson.yaml

aws cloudformation create-stack --stack-name batch-handson --template-body file://./handson.yaml --capabilities CAPABILITY_NAMED_IAM
論理ID タイプ
MyComputeEnv AWS::Batch::ComputeEnvironment
MyJobDefinition AWS::Batch::JobDefinition
MyJobQueue AWS::Batch::JobQueue
IGW AWS::EC2::InternetGateway
PublicSubnetRoute AWS::EC2::Route
PublicSubnetRT AWS::EC2::RouteTable
PublicSubnet1 AWS::EC2::Subnet
PublicSubnet2 AWS::EC2::Subnet
PublicSubnetRTAssociation1 AWS::EC2::SubnetRouteTableAssociation
PublicSubnetRTAssociation2 AWS::EC2::SubnetRouteTableAssociation
VPC AWS::EC2::VPC
VPCIGWAttachement AWS::EC2::VPCGatewayAttachment
AWSBatchServiceRole AWS::IAM::Role
CodeBuildRole AWS::IAM::Role
ecsTaskExecutionRole AWS::IAM::Role

手動デプロイ

ECR リポジトリの作成

ECR リポジトリを作成します。

aws ecr create-repository --repository-name queens 

アプリケーションの準備と動作確認

コンパイルし、動作確認を行います。

curl -O https://www.arch.cs.titech.ac.jp/~kise/nq/package/qn24b-version1.0.tgz
tar -zxvf qn24b-version1.0.tgz
gcc -O2 version1.0/base/queens.c -o queens
./queens 16


qn24b base version 1.0.1 2004-09-02
=============================================
qn24b base version 1.0.1 2004-09-02
problem size n        : 16
total   solutions     : 14772512
correct solutions     : 14772512
million solutions/sec : 4.962
elapsed time (sec)    : 2.977
=============================================

アプリケーションのコンテナ化

Dockerfile を作成し、ビルド後動作確認をします。

Dockerfile
FROM public.ecr.aws/amazonlinux/amazonlinux:latest

COPY ./queens /usr/local/bin/queens

# program execute
CMD /usr/local/bin/queens 16
docker build -t queens .
docker run queens

qn24b base version 1.0.1 2004-09-02
=============================================
qn24b base version 1.0.1 2004-09-02
problem size n        : 16
total   solutions     : 14772512
correct solutions     : 14772512
million solutions/sec : 2.694
elapsed time (sec)    : 5.483
=============================================

ECR へ push

ECR へ コンテナイメージ を push します

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

docker tag queens:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/queens:latest

docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/queens:latest

ジョブ定義の更新

AWS Batch > ジョブ定義 > handson-def を開き、「アクション」から「リビジョンの作成」を開きます。
スクリーンショット 2024-04-02 16.34.25.png

「ステップ 2」の「コンテナ設定」で「イメージ」を自身のイメージの URI に書き換えます。
スクリーンショット 2024-04-02 16.38.59.png

ジョブの実行と確認

AWS Batch > ジョブ > 新しいジョブを送信 を開き、「名前」、「ジョブ定義」、「ジョブキュー」を次の図の通り指定します。
スクリーンショット 2024-04-02 16.43.40.png

ジョブが実行され、「Succeeded」になったことが確認できました。また、「ログ記録」を確認するとローカルで実行した内容と同じ結果が得られました。
スクリーンショット 2024-04-02 16.49.32.png
スクリーンショット 2024-04-02 16.50.31.png

自動デプロイ

CodeCommit リポジトリの作成と clone

CodeCommit リポジトリを作成しておきます。

aws codecommit create-repository --repository-name handson-repo

作成した CodeCommit リポジトリを clone し、handson-repo リポジトリに移動しておきます。

git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/handson-repo

cd handson-repo

buildspec.yaml の作成

この buildspec.yaml は手動デプロイで行った作業を自動デプロイに落とし込んでいるだけのようなので、ここでの詳しい説明は省きます。

buildspec.yaml
version: 0.2
phases:
    pre_build:
        commands:
            - AWS_ACCOUNT_ID=$(echo ${CODEBUILD_BUILD_ARN} | cut -f 5 -d :)
            - 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
            - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/queens
            - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
    build:
        commands:
            - docker build -t $REPOSITORY_URI:latest .
            - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
    post_build:
        commands:
            - docker push $REPOSITORY_URI:latest
            - docker push $REPOSITORY_URI:$IMAGE_TAG
            - cat job-definition-template.json | jq --arg IMAGE_URI $REPOSITORY_URI:$IMAGE_TAG '.image|=$IMAGE_URI' > job-definition.json
            - aws batch register-job-definition --job-definition-name handson-def --type container --platform-capabilities FARGATE --container-properties file://job-definition.json

ジョブ定義の作成

ジョブ定義で指定するコンテナのプロパティを作成します。

job-definition.json
{
  "image": "TBD",
  "command": [],
  "executionRoleArn": "arn:aws:iam::123456789012:role/service-role/ecsTaskExecutionRole-handson",
  "volumes": [],
  "environment": [],
  "mountPoints": [],
  "ulimits": [],
  "resourceRequirements": [
    {
      "value": "0.25",
      "type": "VCPU"
    },
    {
      "value": "512",
      "type": "MEMORY"
    }
  ],
  "secrets": [],
  "networkConfiguration": {
    "assignPublicIp": "ENABLED"
  },
  "fargatePlatformConfiguration": {
    "platformVersion": "LATEST"
  },
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX",
    "cpuArchitecture": "X86_64"
  }
}

リポジトリへ push

手動デプロイで作成した Dockerfile と queens を handson-repo ディレクトリ配下にコピーします。

cp ../Dockerfile .
cp ../queens .

リポジトリへ push するファイルは以下の通りとなります。

.
├── Dockerfile
├── buildspec.yaml
├── job-definition-template.json
└── queens

CodeCommit へ push します。

git add .
git commit -m "my first commit"
git push

CodePipeline の作成

CloudFormation で CodePipeline をデプロイします。

handson-pipeline.yaml
AWSTemplateFormatVersion: "2010-09-09"

Resources:

    S3Bucket:
        Type: 'AWS::S3::Bucket'
        Properties:
          BucketName: !Sub "codepipeline-${AWS::Region}-20240403"

    IAMRole:
        Type: "AWS::IAM::Role"
        Properties:
            Path: "/service-role/"
            RoleName: !Sub "AWSCodePipelineServiceRole-${AWS::Region}-${CodeBuildProject}"
            AssumeRolePolicyDocument: {
                                "Version": "2012-10-17",
                                "Statement": [
                                    {
                                    "Effect": "Allow",
                                    "Principal": {
                                        "Service": "codepipeline.amazonaws.com"
                                    },
                                    "Action": "sts:AssumeRole"
                                    }
                                ]
                }
            MaxSessionDuration: 3600
            ManagedPolicyArns: 
              - !Sub "arn:aws:iam::${AWS::AccountId}:policy/service-role/AWSCodePipelineServiceRole-${AWS::Region}-${CodeBuildProject}"

    CodeBuildProject:
        Type: "AWS::CodeBuild::Project"
        Properties:
            Name: "handson-pipeline"
            Source: 
                GitCloneDepth: 1
                GitSubmodulesConfig: 
                    FetchSubmodules: false
                InsecureSsl: false
                Location: !Sub "https://git-codecommit.${AWS::Region}.amazonaws.com/v1/repos/handson-repo"
                Type: "CODECOMMIT"
            Artifacts: 
                Type: "NO_ARTIFACTS"
            Cache: 
                Type: "NO_CACHE"
            Environment: 
                ComputeType: "BUILD_GENERAL1_SMALL"
                Image: "aws/codebuild/amazonlinux2-x86_64-standard:5.0-24.03.20"
                ImagePullCredentialsType: "CODEBUILD"
                PrivilegedMode: true
                Type: "LINUX_CONTAINER"
            ServiceRole: !Sub "arn:aws:iam::${AWS::AccountId}:role/service-role/codebuild-handson-role"
            TimeoutInMinutes: 60
            QueuedTimeoutInMinutes: 480
            EncryptionKey: !Sub "arn:aws:kms:${AWS::Region}:${AWS::AccountId}:alias/aws/s3"
            BadgeEnabled: false
            LogsConfig: 
                CloudWatchLogs: 
                    Status: "ENABLED"
                S3Logs: 
                    Status: "DISABLED"
                    EncryptionDisabled: false
            Visibility: "PRIVATE"

    CodePipelinePipeline:
        Type: "AWS::CodePipeline::Pipeline"
        Properties:
            Name: !Ref CodeBuildProject
            RoleArn: !GetAtt IAMRole.Arn
            ArtifactStore: 
                Location: !Ref S3Bucket
                Type: "S3"
            Stages: 
              - 
                Name: "Source"
                Actions: 
                  - 
                    Name: "Source"
                    ActionTypeId: 
                        Category: "Source"
                        Owner: "AWS"
                        Provider: "CodeCommit"
                        Version: "1"
                    Configuration: 
                        BranchName: "master"
                        OutputArtifactFormat: "CODE_ZIP"
                        PollForSourceChanges: "false"
                        RepositoryName: "handson-repo"
                    OutputArtifacts: 
                      - 
                        Name: "SourceArtifact"
                    Region: !Ref AWS::Region
                    Namespace: "SourceVariables"
                    RunOrder: 1
              - 
                Name: "Build"
                Actions: 
                  - 
                    Name: "Build"
                    ActionTypeId: 
                        Category: "Build"
                        Owner: "AWS"
                        Provider: "CodeBuild"
                        Version: "1"
                    Configuration: 
                        ProjectName: !Ref CodeBuildProject
                    InputArtifacts: 
                      - 
                        Name: "SourceArtifact"
                    OutputArtifacts: 
                      - 
                        Name: "BuildArtifact"
                    Region: !Ref AWS::Region
                    Namespace: "BuildVariables"
                    RunOrder: 1
aws cloudformation create-stack --stack-name handson-pipeline --template-body file://./handson-pipeline.yaml --capabilities CAPABILITY_NAMED_IAM

パイプラインの実行

Dockerfile で 16 → 10 にし、push します。

Dockerfile
FROM public.ecr.aws/amazonlinux/amazonlinux:latest

COPY ./queens /usr/local/bin/queens

# program execute
CMD /usr/local/bin/queens 10
git add .
git commit -m "change queens param"
git push

デベロッパー用ツール > CodePipeline > パイプライン > handson-pipeline にいくと、自動デプロイが成功していることが確認できます。

スクリーンショット 2024-04-03 16.02.32.png

ジョブの実行と確認

AWS Batch > ジョブ > handson-def を確認すると、イメージが書きかわっていることがわかります。
buildspec.yaml で指定したIMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)の部分です。

スクリーンショット 2024-04-03 16.06.42.png

AWS Batch > ジョブ > 新しいジョブを送信 を開き、「名前」、「ジョブ定義」、「ジョブキュー」を次の図の通り指定します。
スクリーンショット 2024-04-03 16.09.30.png

「ログ記録」を確認すると Dockerfile で 16 → 10 に変更した内容で実行されたことが確認できました。
スクリーンショット 2024-04-04 13.46.25.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?