ジャコ Lab

プログラミング関連のメモ帳的ブログです

Docker コンテナ起動時に AssumeRole を実行してからメインコマンドを動かしたい

zako-lab929.hatenablog.com

昨日、Docker コンテナ起動時に前処理を実行しました。
本当にやりたかったのはウェイトではなく AssumeRole です。

AssumeRole が何か についてはこの記事では書いていません。

前提

前提として、
IAM ユーザー と AssumeRole で使用する IAM ロール は作成済みとします。

また、昨日と同様、Dockerfile と docker-compose.yml の定義しておきます。 ここでは、昨日の最後 と一緒です。

また、必要に応じて Docker Image は削除するなりして、ちゃんと Build されるようにしておきます。

Dockerfile & docker-compose.yml & docker-entrypoint.sh

FROM python:3.11.10-slim-bullseye

RUN apt update -y

COPY ./app ./app
COPY ./docker-entrypoint.sh ./docker-entrypoint.sh

ENTRYPOINT ["bash", "docker-entrypoint.sh"]
CMD ["python", "app/main.py"]
services:
  app:
    build:
      context: .
    container_name: app
# このブロックに本当にやりたい処理を入れる
for i in {1..10}; do
  echo "Waiting... count: $i"
  sleep 1
done

exec $@

AssumeRole 前後の期待値について

期待値は、いわゆる aws s3 ls ができるかどうかです。

この記事では、あくまで簡単なサンプルになりますので、
PythonAWS リソースにアクセスするのではなく、
aws cliAWS リソースにアクセスできることを期待値と設定します。

AssumeRole 前の動作確認をする

動作確認用のスクリプト等の設定

  [Dockerfile]

  FROM python:3.11.10-slim-bullseye

  RUN apt update -y
+ RUN pip install awscli

  COPY ./app ./app
  COPY ./docker-entrypoint.sh ./docker-entrypoint.sh

  ENTRYPOINT ["bash", "docker-entrypoint.sh"]
  CMD ["python", "app/main.py"]
  [docker-compose.yml]

  services:
    app:
      build:
        context: .
      container_name: app
+     command: ["aws", "s3", "ls"]
+     environment:
+      - AWS_DEFAULT_REGION=ap-northeast-1
+      - AWS_ACCESS_KEY_ID=xxxxx
+      - AWS_SECRET_ACCESS_KEY=zzzzz
docker-compose の方で aws s3 lsをメインコマンドとして実行するように上書きしておきます。
  [docker-entrypoint.sh]

  # このブロックに本当にやりたい処理を入れる
- for i in {1..10}; do
-   echo "Waiting... count: $i"
-   sleep 1
- done

  exec $@

動作確認

$ docker compose up
〜省略〜
app  | An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:iam::000000000000:user/practice is not authorized to perform: s3:ListAllMyBuckets because no identity-based policy allows the s3:ListAllMyBuckets action
現在のユーザーでは aws s3 ls の権限がないことを確認!

本題:AssumeRole を実行してからメインコマンドを実行する

docker-entrypoint.sh に本当にやりたいことを記述する

- # このブロックに本当にやりたい処理を入れる
+ ROLE_ARN="arn:aws:iam::000000000000:role/AssumeRole_S3FullAccess"
+ SESSION_NAME="practice-user"

+ # AssumeRole を実行
+ CREDS=$(aws sts assume-role --role-arn $ROLE_ARN --role-session-name $SESSION_NAME --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output text)

+ # AssumeRole のレスポンスを変数に代入
+ read AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN <<< "$CREDS"

+ # 環境変数に設定
+ export AWS_ACCESS_KEY_ID
+ export AWS_SECRET_ACCESS_KEY
+ export AWS_SESSION_TOKEN

  exec $@

いざ!動作確認

$ docker compose up
〜省略〜
app  | 2024-10-09 12:25:24 aaaaa
app  | 2024-10-09 12:26:31 bbbbb
aaaaabbbbb というバケットが存在している様子を表しています。

まとめ

AWS_ACCESS_KEY_ID等を環境変数に設定することでデフォルトユーザーを切り替えてからメインコマンドを実施できるようになりました。でも AssumeRole には有効期限があるからこの方法では注意する必要がありそうです。