Docker Compose で作成してある複数コンテナを AWS ECS に上げてみる


AWS のサービスの記事はいろいろ乱立していて、ベータ版の頃の記事がヒットしたり、チュートリアルばかりヒットして、結局、業務で使えそうとなったときにどこからはじめたらいいのかわからなかったりしますよね。

ぼくもこれどこから始めるんだろうと思ってました。まずは、ローカル側から準備するんですよ。

AWS CLIの準備

AWSのコマンドラインツールです。ぼくは Windows にサブシステムで入っている(WSLってやつです)Ubuntu を使っているので Linux 版の CLI をいれます。

インストール方法の公式ドキュメントを読んでそのままコピペしたら入ります。

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

入ったかどうか確かめます。

$ aws --version
aws-cli/2.1.29 Python/3.8.8 Linux/5.4.72-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off

今日時点での最新2.1.29が入りました。

プロファイル作成

AWS への接続情報を含むプロファイルを作成します。

$ aws configure --profile dev
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json

できました。

Amazon ECS 用 docker context 作成

$ docker context create ecs ecs_dev_context
? Create a Docker context using: An existing AWS profile
? Select AWS Profile dev
Successfully created ecs context "ecs_dev_context"

できました

$   docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
ecs_dev_context     ecs 

設定の確認

よくわかってないんですが、LongArnFormat に関する設定が Enable
になっている必要があるそうです。ぜんぶ Enable になっていることを確認しました。

$ aws ecs list-account-settings --effective-settings
{
    "settings": [
        {
            "name": "awsvpcTrunking",
            "value": "disabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        },
        {
            "name": "containerInsights",
            "value": "disabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        },
        {
            "name": "containerInstanceLongArnFormat",
            "value": "enabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        },
        {
            "name": "dualStackIPv6",
            "value": "enabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        },
        {
            "name": "serviceLongArnFormat",
            "value": "enabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        },
        {
            "name": "taskLongArnFormat",
            "value": "enabled",
            "principalArn": "arn:aws:iam::XXXXXXXXXXXX:user/sugimoto-dev"
        }
    ]
}

ECRリポジトリを用意

Web ブラウザで AWS のコンソールにログインして、ここから作成します。

ECR へログイン

またローカルのコマンドです。
ログインが必要です。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin  XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com

username は自分のものを入れるのではなく固定で AWS と入れるようです。

プッシュしておく。

docker-compose push
Pushing api (XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest)...
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge]
1f6de88c2dc9: Preparing                                                                                                 73e3e78bfd9a: Preparing                                                                                                 7384658657bf: Preparing                                                                                                 c1ae2439e41e: Preparing                                                                                                 72fd383bd06f: Preparing                                                                                                 7e918812cca3: Waiting                                                                                                   b45d11f9e6b5: Waiting                                                                                                   3676846f14f0: Waiting                                                                                                   10c7b2ce5f37: Waiting                                                                                                   e3d73f29c674: Waiting                                                                                                   10bf86ff9f6a: Waiting                                                                                                   da654bc8bc80: Waiting                                                                                                   4ef81dc52d99: Waiting                                                                                                   909e93c71745: Waiting                                                                                                   7f03bfe4d6dc: Waiting                                                                                                   ERROR: denied: User: arn:aws:iam::XXXXXXXXXXXX:user/hogefuga-user is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:ap-northeast-1:XXXXXXXXXXXX:repository/hogehoge

エラーになった。?????
あっ。

version: '3.8'
services:
  api:
    build: ./app
    image: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/api-hawk:latest
    ports:
      - 5000:5000

docker-compose の image で XXXXXXXXXXXX のところに間違ってユーザのIDをいれてました。あほです。ちゃんとコンソールから取得したリポジトリURLを入れましょう。

$ docker-compose push
Pushing api (XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest)...
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge]
1f6de88c2dc9: Pushed                                                                                                    73e3e78bfd9a: Pushed                                                                                                    7384658657bf: Pushed                                                                                                    c1ae2439e41e: Pushed                                                                                                    72fd383bd06f: Pushed                                                                                                    7e918812cca3: Pushed                                                                                                    b45d11f9e6b5: Pushed                                                                                                    3676846f14f0: Pushed                                                                                                    10c7b2ce5f37: Pushed                                                                                                    e3d73f29c674: Pushed                                                                                                    10bf86ff9f6a: Pushed                                                                                                    da654bc8bc80: Pushed                                                                                                    4ef81dc52d99: Pushed                                                                                                    909e93c71745: Pushed                                                                                                    7f03bfe4d6dc: Pushed                                                                                                    latest: digest: sha256:7e949d6732a116f81811c4520b505391a6da4db7d34c9e50d179becc390539c8 size: 3475

成功しました。コンソールで見るとちゃんとリポジトリに入りました。

ECS へデプロイ

ECS へのデプロイ用のコンテキスト(さっき作った ecs_dev_context)を使うように Docker の設定を変更します。

$ docker context use ecs_dev_context
ecs_dev_context

このコンテキストで docker-compose up するとなんと AWS にあがってしまうらしいです。すごい。

[+] Running 14/14
 ⠿ docker-api-hawk           CreateComplete                                                                                                291.0s
 ⠿ LogGroup                  CreateComplete                                                                                                  2.0sh
 ⠿ ApiTCP5000TargetGroup     CreateComplete                                                                                                  1.0s
 ⠿ LoadBalancer              CreateComplete                                                                                                152.0s
 ⠿ DefaultNetwork            CreateComplete                                                                                                  5.0s
 ⠿ CloudMap                  CreateComplete                                                                                                 48.1s
 ⠿ ApiTaskExecutionRole      CreateComplete                                                                                                 22.0s
 ⠿ Cluster                   CreateComplete                                                                                                  7.0s
 ⠿ Default5000Ingress        CreateComplete                                                                                                  1.0s
 ⠿ DefaultNetworkIngress     CreateComplete                                                                                                  1.0s
 ⠿ ApiTaskDefinition         CreateComplete                                                                                                  3.0s
 ⠿ ApiServiceDiscoveryEntry  CreateComplete                                                                                                  2.0s
 ⠿ ApiTCP5000Listener        CreateComplete                                                                                                  3.0s
 ⠿ ApiService                CreateComplete                                                                                                121.0s

あがりました。