[小ネタ] Amazon ECR(Elastic Container Registry)のlatestタグの向き先をAWS CLIで変更する

AWS CLIでAmazon ECRでホストするDockerイメージのlatestタグの向き先を変更します。
2018.07.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、大瀧です。
Amazon ECR(Elastic Container Registry)は、Dockerイメージを格納できるプライベートリポジトリのマネージドサービスです。弊社が提供するEC/CRMサービスPrismatixはAmazon ECSで稼働しており、コンテナイメージをECRでホストしています。各コンテナのアプリケーションコードはGitHub、CIとしてCircle CIで管理しておりECRにPushするDockerイメージにはCircle CIのビルド設定によって、自動でlatestタグが付与されます。

そのためECSのタスク定義でlatestタグを参照すると最近Pushされたイメージを参照してしまうため、実験的なコードを試すとき「安定版のイメージにlatestタグを付け替えたい」というニーズが出てきました。本来、リモートリポジトリのイメージのタグ付けはdockerコマンドを用いるのが最もシンプルです。しかし、ローカルでDockerをセットアップする手間やDockerリポジトリの認証情報の取得が必要なため、今回はAWS CLIのみでタグを付け替える方法をご紹介します。

実行方法

今回は、例としてubuntuイメージの2つのタグubuntu:16.04ubuntu:18.04を用います。現在はlatest18.04を向いているので、これを16.04に向けてみます。

ECRでは個々のDockerイメージをイメージマニフェストというメタ情報で管理しており、aws ecr batch-get-imageコマンドのレスポンスの一部で受け取ることができます。ubuntu:16.04のマニフェストを取得すると以下のようになります。

$ aws ecr batch-get-image \
  --repository-name ubuntu \
  --image-ids imageTag=16.04 \
  --query images[].imageManifest \
  --output text
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 3615,
      "digest": "sha256:5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 43122477,
         "digest": "sha256:b234f539f7a1d65eabae1617e63c81ac01768abffd48b5cbbf7166efca6a3429"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 853,
         "digest": "sha256:55172d420b43cf03feeec11bcc917c7ddfc192036102e065ab57aa9abb95311e"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 619,
         "digest": "sha256:5ba5bbeb6b91e2676c98255c6babc66d7b05cac40185eeba4b3773199c701da0"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 851,
         "digest": "sha256:43ae2841ad7a7fd1aeae30028105cac7f6ee0ec955e5229e52b3333fea3c17b5"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 168,
         "digest": "sha256:f6c9c6de41905e9a66f2bc2c4a19858c8dc5b0a94f01e03eafc719afe25888aa"
      }
   ]
}
$

AWS CLIではaws ecr put-imageコマンドでECRのイメージにタグを付与することができますが、このコマンドの引数として前述のイメージマニフェストを指定することでそのイメージを特定します。以下の実行例ではシェル変数MANIFESTでイメージマニフェストを受け取り、それをaws ecr put-imageコマンドの--image-manifestオプションで渡しています。

$ MANIFEST=$(aws ecr batch-get-image --repository-name ubuntu --image-ids imageTag=16.04 --query images[].imageManifest --output text)
$ aws ecr put-image \
  --repository-name ubuntu \
  --image-tag latest \
  --image-manifest "$MANIFEST"
IMAGE	{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 3615,
      "digest": "sha256:5e8b97a2a0820b10338bd91674249a94679e4568fd1183ea46acff63b9883e9c"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 43122477,
         "digest": "sha256:b234f539f7a1d65eabae1617e63c81ac01768abffd48b5cbbf7166efca6a3429"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 853,
         "digest": "sha256:55172d420b43cf03feeec11bcc917c7ddfc192036102e065ab57aa9abb95311e"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 619,
         "digest": "sha256:5ba5bbeb6b91e2676c98255c6babc66d7b05cac40185eeba4b3773199c701da0"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 851,
         "digest": "sha256:43ae2841ad7a7fd1aeae30028105cac7f6ee0ec955e5229e52b3333fea3c17b5"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 168,
         "digest": "sha256:f6c9c6de41905e9a66f2bc2c4a19858c8dc5b0a94f01e03eafc719afe25888aa"
      }
   ]
}	XXXXXXXXXXXX	ubuntu
IMAGEID	sha256:689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12	latest
$

これでOKです。ECRの管理コンソールを確認してみると...

latestタグが16.04に向いていますね!成功です。

(参考) dockerコマンドでタグを変更する

dockerコマンドであれば、gitでローカルブランチをリモートブランチとPushするのと同じ要領でdocker tagコマンドでlatestタグを任意のイメージに向け、docker pushコマンドでリモート(ECR)に反映することができます。以下のような感じで操作できます。

$ docker images
REPOSITORY                                                 TAG                 IMAGE ID            CREATED             SIZE
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   16.04               5e8b97a2a082        2 weeks ago         114MB
ubuntu                                                     16.04               5e8b97a2a082        2 weeks ago         114MB
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   18.04               113a43faa138        2 weeks ago         81.2MB
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   latest              113a43faa138        2 weeks ago         81.2MB
ubuntu                                                     18.04               113a43faa138        2 weeks ago         81.2MB
$
$ docker tag ubuntu:16.04 XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu:latest
$ docker images
REPOSITORY                                                 TAG                 IMAGE ID            CREATED             SIZE
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   16.04               5e8b97a2a082        2 weeks ago         114MB
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   latest              5e8b97a2a082        2 weeks ago         114MB
ubuntu                                                     16.04               5e8b97a2a082        2 weeks ago         114MB
XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu   18.04               113a43faa138        2 weeks ago         81.2MB
ubuntu                                                     18.04               113a43faa138        2 weeks ago         81.2MB
$ docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu:latest
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/ubuntu]
2de391e51d73: Layer already exists
d73dd9e65295: Layer already exists
686245e78935: Layer already exists
d7ff1dc646ba: Layer already exists
644879075e24: Layer already exists
latest: digest: sha256:689aa49d87d325f951941d789f7f7c8fae3394490cbcf084144caddba9c1be12 size: 1357
$

dockerコマンドが使える環境であれば、こちらの方が簡単ですね。

まとめ

AWS CLIでECRでホストするDockerイメージのlatestタグの向き先を変更する様子をご紹介しました。

参考URL