まえがき
プライベートなVPCでdocker pullしたい👉ECRからイメージを持ってくる
概要
CloudFormationテンプレートでCodeBuildプロジェクト作っておき
AWS CLIでイメージ名・タグを指定してCodeBuildを実行する
CloudFormation
- CodeBuild用のロールを作る
- CodeBuildのプロジェクトを作る
CloudFormationテンプレートはこちら👇
----------------------------------------
全体を表示(折りたたみ)
------------------------------------------
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
ImageName:
Type: "String"
Default: "hello-world"
ImageTag:
Type: "String"
Default: "latest"
Resources:
RoleforCodeBuild:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
Path: '/service-role/'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Policies:
- PolicyName: codebuildpolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ecr:CompleteLayerUpload
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
Resource: "*"
- Effect: Allow
Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
- codebuild:BatchPutCodeCoverages
Resource: !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource: !Sub arn:${AWS::Partition}:s3:::codepipeline-ap-northeast-1-*
CodeBuildImageCopy:
Type: AWS::CodeBuild::Project
Properties:
Name: ECRImport-Common
Description: Create ECR Repository(Name.. ImageTag) Before Exec.
ServiceRole: !GetAtt CodeBuildRole.Arn
Source:
Type: "NO_SOURCE"
BuildSpec: |
version: 0.2
env:
shell: bash
phases:
pre_build:
commands:
- aws --version
- docker --version
- ACCID=$(aws sts get-caller-identity --query Account --output text)
build:
commands:
- docker pull $IMAGENAME:$IMAGETAG
- docker tag $IMAGENAME:$IMAGETAG $ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGENAME:$IMAGETAG
- docker images
- aws ecr get-login-password | docker login --username AWS --password-stdin https://$ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- docker push $ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGENAME:$IMAGETAG
Environment:
Type: LINUX_CONTAINER
Image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
ComputeType: BUILD_GENERAL1_SMALL
PrivilegedMode: true
EnvironmentVariables:
- Name: IMAGENAME
Type: PLAINTEXT
Value: hello-world
- Name: IMAGETAG
Type: PLAINTEXT
Value: latest
TimeoutInMinutes: 5
QueuedTimeoutInMinutes: 5
Artifacts:
Type: NO_ARTIFACTS
実行方法
例えば、docker pull nginx:1.9
で取得できるイメージが欲しい場合
CLI
まず、ECRレポジトリを作る
$IMAGENAME="nginx"
aws ecr create-repository --repository-name $IMAGENAME --image-scanning-configuration scanOnPush=true
CodeBuildにパラメータを渡して実行
$IMAGENAME="nginx"
$IMAGETAG="1.9"
aws codebuild start-build --project-name ECRImport-Common `
--environment-variables-override `
name=IMAGENAME,value=$IMAGENAME,type=PLAINTEXT name=IMAGETAG,value=$IMAGETAG,type=PLAINTEXT
起動パラメータ
ImageName | docker pull で指定するイメージ名 |
ImageTag | イメージタグ(デフォルト:latest) |
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
ImageName:
Type: "String"
Default: "hello-world"
ImageTag:
Type: "String"
Default: "latest"
1、CodeBuild用のロールを作る
長ったらしい理由…
CloudWatchLogsとECRアップロード関係のみで動作はするが、CodeBuildの親切()機能により、不足しているポリシーを追加してくれる様子?
これをやられると、CloudFormation Stackが削除できなくなる(ロールのみ消えない)
なので、補完してくれるポリシーを先に追加しておく
Resources:
RoleforCodeBuild:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
Path: '/service-role/'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
Policies:
- PolicyName: codebuildpolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ecr:CompleteLayerUpload
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
Resource: "*"
- Effect: Allow
Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
- codebuild:BatchPutCodeCoverages
Resource: !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource: !Sub arn:${AWS::Partition}:s3:::codepipeline-ap-northeast-1-*
2、CodeBuildのプロジェクトを作る
BuildSpecで
- 欲しいイメージをdocker pullで取得する
- タグをつける
- ECRにログインする
- ECRにpushする
CodeBuildImageCopy:
Type: AWS::CodeBuild::Project
Properties:
Name: ECRImport-Common
Description: Create ECR Repository(Name.. ImageTag) Before Exec.
ServiceRole: !GetAtt CodeBuildRole.Arn
Source:
Type: "NO_SOURCE"
BuildSpec: |
version: 0.2
env:
shell: bash
phases:
pre_build:
commands:
- aws --version
- docker --version
- ACCID=$(aws sts get-caller-identity --query Account --output text)
build:
commands:
- docker pull $IMAGENAME:$IMAGETAG
- docker tag $IMAGENAME:$IMAGETAG $ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGENAME:$IMAGETAG
- docker images
- aws ecr get-login-password | docker login --username AWS --password-stdin https://$ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- docker push $ACCID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGENAME:$IMAGETAG
Environment:
Type: LINUX_CONTAINER
Image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
ComputeType: BUILD_GENERAL1_SMALL
PrivilegedMode: true
EnvironmentVariables:
- Name: IMAGENAME
Type: PLAINTEXT
Value: hello-world
- Name: IMAGETAG
Type: PLAINTEXT
Value: latest
TimeoutInMinutes: 5
QueuedTimeoutInMinutes: 5
Artifacts:
Type: NO_ARTIFACTS
あとがき
Docker Hubの制限により、たまにダウンロードできないことがあります。
ガチャです
回避方法は「Codebuild Dockerhub limit」などでググれば出てきますが
- dockerhubの認証を追加する
- CodeBuildをVPCに接続して通信経路をNATGW経由にする
など。。