Amazon ECR リポジトリ作成テンプレートとCreate on pushを試してみた
こんにちは、データ事業本部のキタガワです。
最近Amazon ECRに入門しました。
そのECRに嬉しいアップデートがありました。アップデートの内容は以下の通りです。
リポジトリ作成テンプレートに「Create on push」という選択肢が追加されました。簡単に説明すると、リポジトリ作成テンプレートでCreate on pushを設定しておけば、存在しないリポジトリへのプッシュ時にECRが自動でリポジトリを作成し、テンプレートの設定が適用されるという機能です。これにより事前にリポジトリを作成する必要がなく、IaCなどの管理がシンプルになることを期待できます。
これは嬉しい機能ですね。でも、そもそもリポジトリ作成テンプレートってどういうものでしたっけ?
というわけでこのブログでは「リポジトリ作成テンプレート(repository creation templates)」とは何なのか、そしてこのアップデートで何ができるようになったのかについてまとめます。
ここで使用しているソースコードはGitHubにアップロードしていますので参考にしてください。
リポジトリ作成テンプレートとは
大前提としてECRはその名の通りコンテナのレジストリなのでまずリポジトリを作らないと利用できません。しかし、そこはAWSです。嬉しい機能を用意してくれています。ユーザーが明示的にリポジトリを作成しなくても、ECR側が自動的にリポジトリを作成する機能です。
リポジトリ作成テンプレート(以下テンプレート)はECRが自動的にリポジトリを作成するにあたって設定したいリポジトリ設定を事前に定義しておくためのものです。今回のアップデート前までは適用対象として「Pull through cache」と「Replication」が選択できました。それに加えて今後は「Create on push」も選べるようになりました。
適用対象
テンプレートは、ECRが自動的にリポジトリを作成する際に適用されます。適用対象(Applied For)とは、そのテンプレートが適用されるシナリオを示します。設定可能な値は以下の3つです。
- Pull through cache:外部レジストリ(Docker Hub、ECR Publicなど)からイメージを取得する際に自動作成されるリポジトリに適用されます
- Replication:クロスリージョンまたはクロスアカウントでリポジトリを複製する際に自動作成されるリポジトリに適用されます
- Create on push:存在しないリポジトリにイメージをプッシュした際に自動作成されるリポジトリに適用されます
注意したい点として、Pull through cacheとReplicationでは元々リポジトリ作成は自動で行われていました。その作成されるリポジトリの設定を事前に行うのがテンプレートです。一方で今回追加されたCreate on pushはそもそも存在しないリポジトリへのイメージのプッシュはエラーとなっていましたし、今後もテンプレートを設定しない限りはエラーとなります。
表にまとめるとこうなります。
| 機能 | テンプレートなし | テンプレートあり |
|---|---|---|
| Pull through cache | デフォルト設定で自動作成 | カスタム設定で自動作成 |
| Replication | デフォルト設定で自動作成 | カスタム設定で自動作成 |
| Create on push | リポジトリは作成されない | カスタム設定で自動作成 |
このテンプレート機能により、意図しないリポジトリの作成を防ぎながら、明示的に設定した場合のみ自動作成が可能になります。
テンプレートで設定可能な項目
テンプレートでは主に以下の項目を設定できます。
| 項目 | 説明 |
|---|---|
| Prefix | テンプレートを適用するリポジトリ名のプレフィックス(例: prod/)。ROOT を指定すると全リポジトリに適用 |
| Applied For | 前述の通りテンプレートを適用するシナリオ。PULL_THROUGH_CACHE、CREATE_ON_PUSH、REPLICATIONが選択可能。 |
| Image tag mutability | タグの不変性。MUTABLE(上書き可)または IMMUTABLE(上書き不可) |
| Encryption configuration | 暗号化方式。AES-256 または KMS |
| Lifecycle policy | ライフサイクルポリシー。古いイメージの自動削除などが行える。 |
このほかにもリポジトリのパーミッションやリポジトリ作成時にECRが引き受けるIAMロールの設定などがあります。
いろいろ試してみる
Pull through cacheとCreate on pushについて動作検証を進めていきます。Replicationはクロスリージョンまたはクロスアカウントでの設定が必要で、手順が煩雑になるので今回は省きます。
ここでは仮のシナリオとして、ECS FargateでNginxのタスクを起動する場合を想定します。Docker Hubからベースイメージをプルする時にはPull through cacheを使用し、作成したカスタムイメージをプッシュする時にはCreate on pushを使用します。Pull through cacheを経由することでキャッシュされ、2回目以降のプルが高速になるほか、外部レジストリの障害やネットワーク遅延の影響も受けにくくなります。またCreate on pushにより事前のリポジトリ作成が不要になり、IaCやCI/CDパイプラインの管理がシンプルになります。
リソースの定義には最近よく使用しているTerraformを使います。ただしこのブログでは、Create on pushを設定するテンプレートの作成にはAWS CLIを用います。TerraformではまだCreate on pushがサポートされていないからです。
ディレクトリ構成としては以下のようになります。
.
├── main.tf # プロバイダー設定
├── variables.tf # 変数定義
├── outputs.tf # 出力定義
├── ecr.tf # ECR関連リソース
├── ecs.tf # ECS関連リソース
├── network.tf # ネットワーク関連リソース
└── app/
├── Dockerfile # Nginxカスタムイメージ
└── index.html # サンプルHTMLファイル
検証は次のように進めます。
- Terraformでリソース一式のデプロイ
- ベースイメージのプル
- ECRにPull through cache ruleに対応したリポジトリが作成される
- 検証ポイント:作成されるリポジトリにはライフサイクルポリシーが設定されていることが想定される
- カスタムイメージのプッシュ(1回目)
- 検証ポイント:プッシュは失敗することが想定される
- Create on pushに対応したテンプレートの作成
- カスタムイメージのプッシュ(2回目)
- 検証ポイント:テンプレートの効果により成功することが想定される
- ECSでイメージを利用してタスクを起動
Terraformでリソース一式のデプロイ
cd amazon-ecr-repository-creation-templates-create-on-push
terraform apply
これで必要なリソースがデプロイできます。ECRにはまだイメージがないため、ECSのタスクは失敗し続けていると思います。次はこのタスクで使うイメージを用意します。
ベースイメージのプル
Nginx用のベースイメージをプルします。Docker Hubからでもいいのですが、ここでは検証等も兼ねてECR PublicからPull through cacheを経由してプルすることにします。前述の通りECRではPull through cache ruleを設定していると自動でリポジトリを作成してくれます。このとき作成されるリポジトリにはデフォルトの設定が適用されますが、今回はテンプレートを設定しているためライフサイクルの設定が追加されているはずです。まずはベースイメージをプルし、作成されるリポジトリを確認してみます。
各コマンドはterraform outputに出力されるようにしています。
docker pull の前にコンソールからリポジトリの存在を確認してみます。

当然リポジトリは作成されていません。
# ECRログイン
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
# Pull through cache経由でベースイメージ取得
docker pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-template-demo-ecr-public/nginx/nginx:stable-alpine
再度コンソールを確認してみましょう。

今度は作成されていますね。ECR Publicをupstreamとしてプルを契機にキャッシュ用のリポジトリが作成されました。ライフサイクルポリシーについても確認してみます。これはデフォルトの設定だとライフサイクルポリシーはないのですが、このリポジトリについてはテンプレートによって自動作成時に追加の設定が行われていることが確認できます。

カスタムイメージのプッシュ(1回目)
先ほどプルしたベースイメージをもとにカスタムイメージをビルドします。
# カスタムイメージをビルド
docker build --build-arg AWS_ACCOUNT_ID=123456789012 --build-arg ECR_PREFIX=ecr-template-demo-ecr-public -t 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-template-demo-app/my-app:latest ./app
# ECRにプッシュ
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-template-demo-app/my-app:latest
実行すると次のようなエラーになります。

ecr-template-demo-app/my-app という名前のリポジトリがないよというエラーですね。想定通りの挙動です。
Create on pushに対応したテンプレートの作成
では新しく追加されたCreate on pushを適用対象にしたテンプレートを作成します。本来であればTerraformで実装したかったのですが、それはまたの機会に。
AWS CLIで以下のコマンドを実行します。
aws ecr create-repository-creation-template \
--prefix "ecr-template-demo-app/" \
--applied-for CREATE_ON_PUSH
テンプレートが作成できれば準備OKです。

カスタムイメージのプッシュ(2回目)
テンプレートを作成したのでもう一度同じカスタムイメージをプッシュしてみます。正常にプッシュが完了し、対応するリポジトリが作成されているはずです。
# ECRにCreate on pushでプッシュ
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-template-demo-app/my-app:latest
今度は成功しました。

リポジトリが作成されているかも確認してみましょう。

いいですね、ecr-template-demo-app/my-app が追加で作成されました。意図通りの挙動になっています。
ECSでイメージを利用してタスクを起動
ここまででカスタムイメージのリポジトリが作成できました。あとはECSタスクで該当のイメージを利用してタスク起動するだけです。ECSサービスはリトライを続けているはずなので、次の試行を待ってもいいですし、AWS CLIで新しいデプロイを強制しても良いです。
aws ecs update-service \
--cluster ecr-template-demo-cluster \
--service ecr-template-demo-service \
--force-new-deployment
無事にタスク起動ができたら割り当てられているパブリックIPアドレスにアクセスします。Nginxで配信しているHTMLが表示されたらOKです。
一連の検証が済んだらリソースを削除しておきましょう。
terraform destroy
自動作成されたリポジトリはTerraformの管理対象外なので、AWS CLIで削除します。
aws ecr delete-repository --repository-name ecr-template-demo-app/my-app --force
aws ecr delete-repository --repository-name ecr-template-demo-ecr-public/nginx/nginx --force
まとめ
ここまでで以下のポイントを検証しました。
- Pull through cacheによってリポジトリが自動作成されること。またこのリポジトリの設定をカスタムすること。
- Create on pushを適用対象としたテンプレートを作成しない場合、ECRへプッシュしたときに失敗すること。
- Create on pushを適用対象としたテンプレートを作成した場合、ECRへプッシュしたときに成功すること。
特に新しく追加されたCreate on pushはIaCやCI/CDで活躍することが期待できます。テンプレートを適切に設定することによって不要なリポジトリが乱立することも避けられると思います。Terraformではまだサポートされていないですが、近々アップデートが予定されているのでそれを待ちたいですね。
この記事が参考になれば幸いです。
それでは次の記事でお会いしましょう。
つまづきポイント
TerraformではまだCREATE_ON_PUSHをサポートしていない
- v6.28.0以降のサポートを予定しています
- https://github.com/hashicorp/terraform-provider-aws/issues/45701
Docker HubのPull through cacheには認証が必須
- Docker CLIでは匿名pullが可能だが、ECR Pull through cacheでは認証情報が必須です
- https://docs.aws.amazon.com/AmazonECR/latest/userguide/pull-through-cache.html
このブログでは簡便に済ませたかったのでECR PublicからNginxイメージをプルしています。
参考






