Dockerコンテナで上で動くAWS SDKにローカルの認証情報(~/.aws/credentials)を読み込ませる
概要
今やDockerでローカルの開発環境を構築することがほとんどだと思う。
先日、Dockerコンテナ + AWS SDKを使った開発において、コンテナを使わない開発ではAWS上のリソースにアクセスできたのに、コンテナを使った瞬間Credentialsのロードに失敗してアクセスできなくなった。
当たり前の事象だが少しはまってしまったので、備忘として解決方法を残しておく。
Fargateコンテナに付与したRoleと同等の権限でローカル開発環境からAWS S3にアクセスするでも紹介しているが、SDKへの認証情報の提供にはいくつか種類があり、本記事では
共有認証情報ファイル (~/.aws/credentials) から読み込む
こちらの方法を対象とする。
結論
apiというイメージがあったとして、下記のように .aws/
をコンテナにマウントすればOK。
$ docker run -v $HOME/.aws/:/root/.aws/ --rm api
もうちょっと具体的に
このようなディレクトリ構造で開発を行っていたとする。
※モノリスだがうち(FastLabel)は開発スピードとCICDの単純化のため実際にこのような構造をあえて採用している。
$ tree -L 1
.
├── README.md
├── api
├── docker-compose.yaml
├── front
└── mysql
実務では docker-compose.yaml
で全てを立ち上げているが、簡単化のため、api(バックエンド開発)に絞って話を進める。
api/
以下には、下記のようなDockerfileがある。
FROM node:14.15.3-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
mysql-client
WORKDIR /usr/src/api
COPY package.json ./
COPY yarn.lock ./
RUN yarn install
COPY . .
EXPOSE 4000
CMD ["/bin/sh", "entrypoint.sh"]
また、 api/src/
以下にAWS SDKを使ったソースコードが含まれている。この場合、コンテナを起動するには通常下記のようにコマンドを実行すると思う。
$ docker build -t api ./api
$ docker run -p 4000:4000 -v $(pwd)/api/src:/usr/src/api/src --rm api
しかし、このままでは ~/.aws/credentials
がコンテナ上にマウントされないため、SDKの読み込みでエラーが起きてしまう。
そこで -v $HOME/.aws/:/root/.aws/
を追加して認証情報も一緒にマウントしてあげる。
$ docker run -p 4000:4000 -v $(pwd)/api/src:/usr/src/api/src -v $HOME/.aws/:/root/.aws/ --rm api
以下のコマンドでマウントされたか確認できる。
$ docker run -p 4000:4000 -v $(pwd)/api/src:/usr/src/api/src -v $HOME/.aws/:/root/.aws/ -it --rm api bash
xxxxx:/usr/src/api# ls $HOME/.aws/
cli config credentials
実務で毎回 docker run
するのは面倒なので、 docker-compose.yaml
にこのように記述しておくことで、 docker-compose up --build
のみで済む。
version: "3.6"
services:
api:
container_name: api
build: api/
volumes:
- ./api/src:/usr/src/api/src
- $HOME/.aws/:/root/.aws/
working_dir: /usr/src/api
ports:
- "4000:4000"
Discussion