VS CodeのDev Container環境にAWS認証情報を環境変数で渡す

# はじめに
VS CodeのDev Containerを使って開発をしようと環境を準備していたところ、AWSの認証情報が渡されない事象に出くわしたので備忘として書いておきます。

# 検証環境
- Windows 10
- PowerShell 5.1
- aws-vault v7.2.0
- docker 24.0.6

# 最初に結論
aws-vaultで認証後、同じターミナルでVS Codeで開きたいパスに移動して、`code .`コマンドでVSCodeを起動すればAWS認証情報が引き継がれます。

# 事象
Terraform開発環境構築のため、偉大なる先人方の記事を参考にしつつdevcontainer.jsonファイルを実装しました。

- [Devcontainerを用いてPythonやAWS CDK・Serverless Frameworkなどのデプロイ環境の構築をしてみた](https://dev.classmethod.jp/articles/devcontainer-python-aws-cdk-sls-etc/)
- [Visual Studio Code Dev ContainerでAWS CDKの開発環境を作ってみた](https://note.alhinc.jp/n/n55f7b9ba4b93)

一部改変していますが大体こんな感じです。

```json
{
  "name": "DevContainer",
  "build": {
    "dockerfile": "./Dockerfile"
  },
  "runArgs": [
    "--init"
  ],
  "mounts": [
    "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
  ],
  "remoteEnv": {
    "AWS_ACCESS_KEY_ID": "${localEnv:AWS_ACCESS_KEY_ID}",
    "AWS_SECRET_ACCESS_KEY": "${localEnv:AWS_SECRET_ACCESS_KEY}",
    "AWS_SESSION_TOKEN": "${localEnv:AWS_SESSION_TOKEN}",
    "AWS_DEFAULT_REGION": "${localEnv:AWS_DEFAULT_REGION}"
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-azuretools.vscode-docker",
        "hashicorp.terraform",
        "github.copilot",
        "github.copilot-chat"
      ]
    }
  }
}
```

Dockerfileはこちらです。
諸事情で色々入れてますが、最低限必要なのはTerraformイメージとAWSCLIぐらいだと思います。

```Dockerfile
FROM hashicorp/terraform:1.7.2

# install awscli and docker
RUN apk add --no-cache aws-cli
RUN apk add --no-cache dos2unix
RUN apk add --no-cache jq
RUN apk add --no-cache bash
RUN apk add --no-cache docker-cli

# Docker Compose V2をインストール
RUN mkdir -p /usr/local/lib/docker/cli-plugins
RUN wget -q https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -O /usr/local/lib/docker/cli-plugins/docker-compose
RUN chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
```

VS Codeを手動起動します。
試しに`aws configure list`を実行していますが、ここではデフォルトのAWS認証情報が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/55cded0d-f2cd-4a1d-b8ec-5725452f8230.png)

`aws-vault exec [プロファイル名] -- powershell`コマンドを実行してAWS認証を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/55a0766c-86ab-47f8-a4f1-152b2661da27.png)

検証環境ではPowerShellを利用しているので、以下のワンライナーでPowerShellの環境変数名からDev Containerへ渡す環境変数名に設定し直します。
```
$AWS_ACCESS_KEY_ID = $env:AWS_ACCESS_KEY_ID; $AWS_SECRET_ACCESS_KEY = $env:AWS_SECRET_ACCESS_KEY; $AWS_SESSION_TOKEN = $env:AWS_SESSION_TOKEN; $AWS_DEFAULT_REGION = $env:AWS_DEFAULT_REGION
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/07a5b71d-f35b-4f75-8ffe-8ec81ee265f4.png)

Ctrl+Shift+PでDev Containerを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/ef77fc0c-3daf-4411-af94-b1e03d3c7229.png)

VS Code上のターミナルで`aws configure list`コマンドを実行すると何故か環境変数が引き継がれていませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/dc77abe5-6033-45cc-a3e9-39df06b4e884.png)

起動したVS Code上のターミナルで認証・設定すればDev Containerにも渡されると思い込んでましたが、Dev Containerに渡すためにはVS Code側で保持するように環境変数を設定する必要があるようです。
(ターミナルで設定してもVS Code自体には保持されない)

> 特に VSCode のターミナルから操作する場合です。VSCode に限らず、ターミナルは基本的に起動時の環境変数しか保持していないからです。
[Docker で環境変数をホストからコンテナに渡す方法（ホスト OS 側からゲスト OS に渡す方法各種）](https://qiita.com/KEINOS/items/518610bc2fdf5999acf2)

# 解決方法
私はローカルのPowerShellでaws-vaultコマンドで認証後、VS Codeで開きたいパスに移動して、`code`コマンドを実行してVS Codeを起動することで対応しました。
※キャプチャでは実行場所を間違えて2回`code`コマンドを実行しています

- PowerShell
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/ded06352-7268-4a5d-8470-8d1fae7c0875.png)

- Dev Container
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/2bccfead-1e44-4938-acab-2f414f9ebb0a.png)

# おわりに
一番てっとり早いのはホスト側の`.aws`ディレクトリをマウントする方法ですが、今回はaws-vaultを使って認証したかったので環境変数での渡し方を検証してみました。
調べても意外にピンポイントで該当する記事が見つかったので、自分のためにも書いてみました。

この記事がどなたかの参考になれば幸いです。