ECRの別リポジトリへコンテナイメージをコピーする

# 背景

Amazon ECRで特定のコンテナイメージのみ提供することを実現するための要素の１つとして、
開発用のリポジトリからリリース用のリポジトリへコンテナイメージをコピーしたい

# 実現したいこと

開発用リポジトリの特定のコンテナイメージを、リリース用リポジトリにコピーする

# 実現方法

EC2上で、開発用リポジトリからコンテナイメージをプルし、リリース用リポジトリにプッシュする
(将来的にはCodeBuildなどで自動化したい)

## Amazon ECRアクセス用EC2の構築

[Amazon ECR での AWS CLI の使用](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/getting-started-cli.html)を参考に、構築していく

EC2構築の手順は省略するが、以下リソースを使用した

- インスタンスタイプ：t2.micro
- OS：Amazon Linux 2

Amazon ECRにアクセスするためにはAWS CLIとDockerが必要なようだが、Amazon Linux 2 AMIにはAWS CLIは元から入っている

```
$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.225-169.362.amzn2.x86_64 botocore/1.18.6
```

サイトの手順に従いDockerをインストールする

```
sudo yum update -y
sudo amazon-linux-extras install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
docker info
```

```
$ docker --version
Docker version 19.03.13-ce, build 4484c46
```

## リポジトリへの認証

今回のリポジトリは、公開しない(or一部のAWSアカウントにしか公開しない)ためにプライベートリポジトリを使用しているので、[プライベートレジストリ認証](https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html)を参考に実施していく

Amazon ECRがDocker CLIのリクエストを認証・承認できるようにするための手順を実行する必要があるとのこと

AWS CLIをセットアップする

```
$ aws configure
```

AmazonECRプライベートレジストリに対してDockerを認証させる

```
$ aws ecr get-login-password --region {region} | docker login --username AWS --password-stdin {aws_account_id}.dkr.ecr.{region}.amazonaws.com
```

## 事前確認

リポジトリを確認する

```
$ aws ecr describe-repositories
{
    "repositories": [
        {
            "repositoryUri": "{aws_account_id}.dkr.ecr.{region}.amazonaws.com/release",
            "imageScanningConfiguration": {
                "scanOnPush": false
            },
            "encryptionConfiguration": {
                "encryptionType": "AES256"
            },
            "registryId": "{aws_account_id}",
            "imageTagMutability": "MUTABLE",
            "repositoryArn": "arn:aws:ecr:{region}:{aws_account_id}:repository/release",
            "repositoryName": "release",
            "createdAt": 1617367993.0
        },
        {
            "repositoryUri": "{aws_account_id}.dkr.ecr.{region}.amazonaws.com/develop",
            "imageScanningConfiguration": {
                "scanOnPush": false
            },
            "encryptionConfiguration": {
                "encryptionType": "AES256"
            },
            "registryId": "{aws_account_id}",
            "imageTagMutability": "MUTABLE",
            "repositoryArn": "arn:aws:ecr:{region}:{aws_account_id}:repository/develop",
            "repositoryName": "develop",
            "createdAt": 1617367563.0
        }
    ]
}
```
releaseリポジトリと、developリポジトリがあることがわかる

developリポジトリのコンテナイメージを確認する

```
$ aws ecr describe-images --repository-name develop
{
    "imageDetails": [
        {
            "artifactMediaType": "application/vnd.docker.container.image.v1+json",
            "imageSizeInBytes": 83920901,
            "imageDigest": "sha256:255d71ecc31ed42351dbc809905360aec3421a6544759315988d26ea114363b3",
            "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "imageTags": [
                "v1.0"
            ],
            "registryId": "{aws_account_id}",
            "repositoryName": "develop",
            "imagePushedAt": 1617372606.0
        }
    ]
}
```

イメージタグ`v1.0`のコンテナイメージがあることがわかる

releaseリポジトリのコンテナイメージを確認する

```
$ aws ecr describe-images --repository-name release
{
    "imageDetails": []
}
```

コンテナイメージが無いことがわかる

EC2上のコンテナイメージを確認する

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
```

コンテナイメージがないことがわかる

## 開発用リポジトリからコンテナイメージのプル

[イメージのプル](
https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-pull-ecr-image.html)を参考に実施していく

developレジストリからイメージタグ`v1.0`のコンテナイメージをプルする

```
$ docker pull {aws_account_id}.dkr.ecr.{region}.amazonaws.com/develop:v1.0
```

EC2上のコンテナイメージを確認する

```
$ docker images
REPOSITORY                                                  TAG                 IMAGE ID            CREATED             SIZE
{aws_account_id}.dkr.ecr.{region}.amazonaws.com/develop   v1.0                935e47d46598        2 days ago          196MB
```

コンテナイメージをプルできたことがわかる

## リリース用リポジトリへのコンテナイメージのプッシュ

[Dockerイメージをプッシュする](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)を参考に実施していく

プッシュするコンテナイメージのイメージIDを特定する

```
$ docker images
REPOSITORY                                                  TAG                 IMAGE ID            CREATED             SIZE
{aws_account_id}.dkr.ecr.{region}.amazonaws.com/develop   v1.0                935e47d46598        2 days ago          196MB
```

プッシュするコンテナイメージに、プル先のリポジトリ情報をタグ付けする

```
docker tag {イメージID} {aws_account_id}.dkr.ecr.{region}.amazonaws.com/{リポジトリ名}:{イメージタグ}
```

タグ付けできたことを確認する

```
$ docker images
REPOSITORY                                                  TAG                 IMAGE ID            CREATED             SIZE
{aws_account_id}.dkr.ecr.{region}.amazonaws.com/develop   v1.0                935e47d46598        2 days ago          196MB
{aws_account_id}.dkr.ecr.{region}.amazonaws.com/release   v1.0                935e47d46598        2 days ago          196MB
```

タグ付けできたことがわかる

コンテナイメージをプッシュする

```
docker push {aws_account_id}.dkr.ecr.{region}.amazonaws.com/{リポジトリ名}:{イメージタグ}
```

## 事後確認

releaseリポジトリのコンテナイメージを確認する

```
$ aws ecr describe-images --repository-name release`
{
    "imageDetails": [
        {
            "artifactMediaType": "application/vnd.docker.container.image.v1+json",
            "imageSizeInBytes": 83920901,
            "imageDigest": "sha256:255d71ecc31ed42351dbc809905360aec3421a6544759315988d26ea114363b3",
            "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "imageTags": [
                "v1.0"
            ],
            "registryId": "{aws_account_id}",
            "repositoryName": "release",
            "imagePushedAt": 1617543739.0
        }
    ]
}
```

releaseリポジトリにイメージタグ`v1.0`のコンテナイメージをプッシュできたことがわかる

各リポジトリのコンテナイメージのimageDigestが一致することから、コピーできたことがわかる