EC2ではなくCodeBuildでECRイメージを作成しpushする
EC2を使わずビルドする試み。ソースコードの改変などは非常にやり辛いが、これは主にパイプラインという手法でソースを改変できるからそんなに気にしなくてもいいというか、何のためにこれやるのかよくわからないかもしれないけど、AWSの知識を深めるには割と重要かもしれない。
というわけでチュートリアルとして読みすすめてもらえれば光栄である。
まず最初に
お使いのリージョンが正しく意図した場所(ここでは東京)になっている事を確認してから初める事(間違えやすい)
プロジェクトの作成
そうしたら
CodeBuildのダッシュボードから「プロジェクトを作成する」を押す
プロジェクト名を入力する。ここでは ecr-demo-push という名前した。ソースは「ソースがありません」の状態で構わない
ここに関してはUbuntuにしておいた。理由は「慣れてるから」。ここにあるようにWindowsサーバーを使ったビルドもできる(やらないけど)。powershellとかも動くんだと思う。
ロールに関して
ロールに関しては新規に作成するのだが、これをゆくゆく変更していくので一応メモっとくというか注視しておきたい。
この箇所であるが、「エディタに切り替え」ボタンを押す
そしてこれをコピペする、余裕がある場合はこのyamlをイチイチ自作してみたり内容を精査してみたりしてもいいと思う
version: 0.2
phases:
build:
commands:
# AmazonのパブリックECRからAlpineイメージを使用
- |
cat << 'EOF' > Dockerfile
FROM public.ecr.aws/docker/library/alpine:latest
CMD echo 'Hello from Amazon ECR Alpine Docker!'
EOF
# 作成したDockerfileの内容を表示
- cat Dockerfile
# Dockerビルドの実行
- docker build -t test-docker-image .
# ビルドしたDockerイメージを確認
- docker images
# テストとしてDockerイメージの実行
- docker run test-docker-image
それ以外は全てdefaultで保存する。アーティファクトもなしってことになる。
で、「ビルドを開始」ボタンを押す
うまいこといけばこのように、Dockerイメージがビルドされて実行されるはずだ。
ECRへのログインとかpushとか
ECRのリポジトリの作成は終わっていると仮定している。まだの場合は作るなり過去の記事を参考に作るなり、とにかく作るなりする。
まずログインできる権限を付けていく
EC2でやったのと同じような手順。
webコンソールに戻ってきて
編集 ボタンを押す
Buildspecを変更していくことになる。ここで
version: 0.2
phases:
pre_build:
commands:
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
- "echo AWS account ID: $AWS_ACCOUNT_ID"
build:
commands:
# ECRにログイン
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
# AmazonのパブリックECRからAlpineイメージを使用
- |
cat << 'EOF' > Dockerfile
FROM public.ecr.aws/docker/library/alpine:latest
CMD echo 'Hello from Amazon ECR Alpine Docker!'
EOF
# 作成したDockerfileの内容を表示
- cat Dockerfile
# Dockerビルドの実行
- docker build -t test-docker-image .
# ビルドしたDockerイメージを確認
- docker images
# テストとしてDockerイメージの実行
- docker run test-docker-image
このようにする。紙面の関係でちょっと細かくみてらんないけど、これを実行すると
An error occurred (AccessDeniedException)
とかになるはずだ。
これは当該ロールにログイン情報を取る権限がないためで、前回と同じくroleに権限を付けていく必要があるわけ。
ロールの権限を編集していく
サービスロールのところに何のロールを使ってるのか出てるので、これを改変していく。これは前回みたように
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGetLoginPasswordOnly",
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}
この権限つまりecr:GetAuthorizationTokenが欲しい。
この辺に既にポリシーがセットされているので、そいつをいじってしまうのが楽だとは思う。末尾にこれを付け加える
"Resource": [
"...."
]
},
{
"Sid": "AllowGetLoginPasswordOnly",
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
そうすればうまくいくだろう。
後、やる事はEC2のときと同じ
先程の追加部分を以下のようにする
{
"Sid": "AllowECRLoginPushPull",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": "*"
}
なお、本来はResourceに制限をかける事を強く推奨するが、とりあえず動作する方をメインで書いているので、実運用にあたってはこの辺をよく考えてやった方がよい。
でビルドのyamlを更新する
version: 0.2
phases:
pre_build:
commands:
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
- "echo AWS account ID: $AWS_ACCOUNT_ID"
# ECRにログイン
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
- REPOSITORY_URI="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/demos/ecr-echo-test"
build:
commands:
# AmazonのパブリックECRからAlpineイメージを使用
- |
cat << 'EOF' > Dockerfile
FROM public.ecr.aws/docker/library/alpine:latest
CMD echo 'Hello from Amazon ECR Alpine Docker!'
EOF
# 作成したDockerfileの内容を表示
- cat Dockerfile
# Dockerビルドの実行
- docker build -t test-docker-image .
# ビルドしたDockerイメージを確認
- docker images
# テストとしてDockerイメージの実行
- docker run test-docker-image
# タグを付けてプッシュ準備
- docker tag test-docker-image:latest $REPOSITORY_URI:latest
post_build:
commands:
# イメージのプッシュ
- docker push $REPOSITORY_URI:latest
この辺はもうある程度YAMLを眺めてこういうもんかーって思ってるくらいでok。定義されていない変数が突然出てきたりとかもあるけど、ここでは解説しない。
まとめ
CodeBuild 単体でdockerをビルドしプッシュする事を行い、またCodeBuildのロールを適切に変更することで失敗を成功に変えるという事を行ったので、前回とセットで見てきたならば権限についてある程度ぼんやり理解できてきたはずだ。
次回はgit(gitlab)と連携し、pipelineを使ったイメージの作成とプッシュなどを行ってみよう。