ECSタスクからS3への疎通確認用の簡易Dockerイメージを作成する

ECSタスクとして実行するバッチ処理から、外部システムのS3バケットにアクセスするケースにおいて、まだバッチ処理のアプリケーションができていない状況で、先にインフラレベルの疎通確認を行うための簡易なDockerイメージを用意してみました。

## Dockerfile

```dockerfile:Dockerfile
# syntax = docker/dockerfile:1.3-labs
# ヒアドキュメント使用のためsyntaxバージョンの指定が必要
# BuildKitが有効化されている必要がある

# S3にputするだけなのでAWS公式イメージをそのまま使用
FROM amazon/aws-cli 

# putする固定のダミーファイル。本来はアプリケーションで都度作成するもの
# amazon/aws-cliはWORKDIRが/awsのため、/aws/dummy.csvとして出力される
COPY <<EOF dummy.csv
111111111111111111111111
222222222222222222222222
333333333333333333333333
EOF

# 外部システムのS3へのアクセスは払い出されたIAMユーザに対して許可されている。。。
# CMD(exec形式)では環境変数展開できないので、putもこのシェル内でやってしまう
COPY --chmod=755 <<'EOF' configure-and-put.sh
aws configure set region ap-northeast-1
aws configure set aws_access_key_id ${AWS_ACCESS_KEY_ID}
aws configure set aws_secret_access_key ${AWS_SECRET_ACCESS_KEY}
aws s3 cp /aws/dummy.csv s3://${BUCKET_NAME}/output/${FILE_NAME}
aws s3 ls s3://${BUCKET_NAME}/output/
EOF

# amazon/aws-cliはENTRYPOINTがawsコマンドのため、ENTRYPOINTをshで上書き
ENTRYPOINT ["sh", "-c", "./configure-and-put.sh"]
```


## Dockerイメージのローカル実行確認

```yaml:docker-compose.yml
version: '3'
services:
  awscli:
    build: .
    container_name: 'awscli'
    tty: true
    environment:
      BUCKET_NAME: <バケット名>
      FILE_NAME: dummy.csv
      AWS_ACCESS_KEY_ID: <アクセスキー>
      AWS_SECRET_ACCESS_KEY: <シークレットキー>
```

```bash
$ docker-compose up --build
Building awscli
~~省略~~
Recreating awscli ... done
Attaching to awscli
upload: ./dummy.csv to s3://<バケット名>/output/dummy.csv    s) remaining
awscli    |                            PRE load/
awscli    | 2022-04-16 10:49:12         75 dummy.csv
awscli exited with code 0
```


## ECSタスク実行確認

確認対象のECSクラスタやタスク定義は作成済の前提とします。
なお、アクセスキーとシークレットキーは、ECSで実行するときは、環境変数でなくSecrets Managerから取得します。
以下のチュートリアルのとおり実施してあります。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/specifying-sensitive-data-tutorial.html

- アクセスキーとシークレットキーそれぞれのシークレットを作成
- タスク定義で指定するタスク実行ロールに、作成したシークレットに対する`secretsmanager:GetSecretValue`を許可するポリシーを追加
- タスクの環境変数に以下を追加
    - AWS_ACCESS_KEY_ID
        - ValueFrom
        - アクセスキーのシークレットARN
    - AWS_SECRET_ACCESS_KEY
        - ValueFrom
        - シークレットキーのシークレットARN
- Dockerfileは変更不要で、SecretsManagerから取得した値が環境変数として参照できます。


```bash
# 疎通確認用DockerイメージのECR登録（ECRリポジトリは作成済とする）

$ docker build -t ecs-s3-test .

$ docker tag ecs-s3-test <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sampleapp:ecs-s3-test

$ aws ecr get-login-password | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com

$ docker push <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/sampleapp:ecs-s3-test
```

```bash
# ECSタスク実行

$ aws ecs run-task \
  --cluster test \
  --task-definition sampleapp \
  --overrides '{"containerOverrides": [{"name":"sampleapp-container","environment": [{"name":"BUCKET_NAME","value":"<バケット名>"},{"name":"FILE_NAME","value":"dummy.csv"}]}]}' \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[<サブネットID>],securityGroups=[<セキュリティグループID>],assignPublicIp=ENABLED}"
```


## その他参考サイト

- Dockerfileでのヒアドキュメントの利用
    - [https://www.docker.com/blog/introduction-to-heredocs-in-dockerfiles/](https://www.docker.com/blog/introduction-to-heredocs-in-dockerfiles/)
- amazon/aws-cliのDockerfile
    - [https://github.com/aws/aws-cli/blob/v2/docker/Dockerfile](https://github.com/aws/aws-cli/blob/v2/docker/Dockerfile)
- CMD内での環境変数の展開
    - [http://docs.docker.jp/v1.11/engine/reference/builder.html#cmd](http://docs.docker.jp/v1.11/engine/reference/builder.html#cmd)