🐟

[AWS Copilot] MFA + AssumeRoleのAWS Profileを使う

2022/02/06に公開

これは何

  • AWS Copilot CLI でAWS Profileを使う方法についてざっくりとまとめたものです。
  • 本資料ではキーストアOSS aws-vault を使いMFA付きプロファイルへの昇格をします。

バージョン情報

copilot -v
$copilot -v
copilot version: v1.14.0

背景

  • AWS Copilot CLI では環境変数に名前を指定することでプロファイルを変更できます。
  • ただAssumeRole先のIAMRoleに MultiFactorAuthPresent が設定されていると以下のようにコマンドが失敗します。
copilotの場合
$export AWS_PROFILE=sample_profile
$copilot app init
✘ default session: AssumeRoleTokenProviderNotSetError: assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.
aws cliの場合
$export AWS_PROFILE=sample_profile
$aws s3 ls
# 対話式でMFA入力を求められる
Enter MFA code for arn:aws:iam::012345678910:mfa/sample-user: 

実行環境

各種バージョン

OS
Mac (Mojave 10.14.6)
VSCode
バージョン: 1.64.0 (Universal)
コミット: 5554b12acf27056905806867f251c859323ff7e9
 日付: 2022-02-03T04:20:17.224Z (2 日前)
Electron: 13.5.2
Chromium: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Darwin x64 18.7.0
aws-cli
$aws --version
aws-cli/2.1.21 Python/3.7.4 Darwin/18.7.0 exe/x86_64 prompt/off
aws copilot
$docker --version
ocker version 20.10.12, build e91ed57
$copilot -v
copilot version: v1.14.0

設定ファイル

~/.aws/config
[profile sample_profile]
output = json
region = us-east-1
role_arn = arn:aws:iam::012345678910:role/sample-role
mfa_serial = arn:aws:iam::012345678910:mfa/sample-user
source_profile= default

[default]
output = json
region = us-east-1
~/.aws/credential
[default]
aws_access_key_id = ***
aws_secret_access_key = ***
region = us-east-1
aws_mfa_device = arn:aws:iam::012345678910:mfa/sample-user

本題

AWS Vaultのインストール

command
brew install --cask aws-vault
[result] brew install
# install success log
🍺  aws-vault was successfully installed!

クレデンシャル情報の登録

  • aws-vaultdefault プロファイル のアクセスキー、シークレットキーを登録します。
  • また、キーストアに登録された情報にアクセスするためのパスワードを入力します。
command
aws-vault add default
[result] aws-vault add
Enter Access Key ID: ***
Enter Secret Access Key: 
Added credentials to profile "default" in vault

.aws/configの編集

  • .aws/config に 新しいプロファイル test(任意の名前) を追加します。
  • このプロファイルは、AssumeRoleしたいロールの一時クレデンシャルをaws-vaultから受け取る役目を持ちます。
.aws/config
[profile sample_profile]
output = json
region = us-east-1
role_arn = arn:aws:iam::012345678910:role/sample-role
mfa_serial = arn:aws:iam::012345678910:mfa/sample-user
source_profile= default

[default]
output = json
region = us-east-1

# 以下を追加
[profile test]
output = json
region = us-east-1
credential_process = aws-vault exec sample_profile --json --prompt=osascript
  • 今まで使ってきたプロファイル名を使いたい場合は以下のようにすればできます。
  • (後の手順でもこちらの形式を採用しています)
.aws/config
# sample_profile -> vault_profile
[profile vault_profile]
output = json
region = us-east-1
role_arn = arn:aws:iam::012345678910:role/sample-role
mfa_serial = arn:aws:iam::012345678910:mfa/sample-user
source_profile= default

[default]
output = json
region = us-east-1

# AWS Vaultの受け取るプロファイルを既存のプロファイル名にする
[profile sample_profile]
output = json
region = us-east-1
credential_process = aws-vault exec vault_profile --json --prompt=osascript

実行確認

  • 必要に応じて、キーチェーンのパスワードとMFAを入力します。
  • AssumeRoleTokenProviderNotSetError が出ないことを確認します。

copilot app init

command
export AWS_PROFILE=sample_profile
copilot app init
[result] copilot app init
Application name: my-app
✔ Created the infrastructure to manage services and jobs under application my-app.

✔ The directory copilot will hold service manifests for application my-app.

Recommended follow-up action:
  - Run `copilot init` to add a new service or job to your application.

copilot env init

command
copilot env init
[result] copilot env init
Environment name: dev
Credential source: [profile sample_profile]
Default environment configuration? Yes, use default.
✔ Linked account 012345678910 and region us-east-1 to application my-app.

✔ Proposing infrastructure changes for the my-app-dev environment.
- Creating the infrastructure for the my-app-dev environment.            [create complete]  [82.2s]
  - An IAM Role for AWS CloudFormation to manage resources               [create complete]  [14.6s]
  - An ECS cluster to group your services                                [create complete]  [6.9s]
  - An IAM Role to describe resources in your environment                [create complete]  [14.0s]
  - A security group to allow your containers to talk to each other      [create complete]  [4.1s]
  - An Internet Gateway to connect to the public internet                [create complete]  [16.9s]
  - Private subnet 1 for resources with no internet access               [create complete]  [18.5s]
  - Private subnet 2 for resources with no internet access               [create complete]  [18.5s]
  - Public subnet 1 for resources that can access the internet           [create complete]  [14.6s]
  - Public subnet 2 for resources that can access the internet           [create complete]  [18.5s]
  - A Virtual Private Cloud to control networking of your AWS resources  [create complete]  [16.9s]
✔ Created environment dev in region us-east-1 under application my-app.

おまけ

aws-vaultコマンド経由でCopilotを実行する (非推奨)

  • ~/.aws/config にて credential_process を設定しなくても aws-vault コマンドを使うことでCopilotの実行は可能です。
  • しかし、この方法で実行した場合は環境変数に一時クレデンシャルが設定されます。
  • 環境変数に直接クレデンシャル設定をしてしまうと意図しない上書きなどで問題を生みやすいため、Copilotの公式ドキュメントでも非推奨としています。
copilot app init
$aws-vault exec sample_profile -- copilot app init
Enter MFA code for arn:aws:iam::012345678910:mfa/sample-user: 
Note: Looks like you're creating an application using credentials set by environment variables.
Copilot will store your application metadata in this account.
We recommend using credentials from named profiles. To learn more:
https://aws.github.io/copilot-cli/docs/credentials/
...
copilot env init
$aws-vault exec sample_profile -- copilot env init
Environment name: dev
Credential source: Enter temporary credentials

  What's your AWS Access Key ID? (****************AAAA) 

AWS Vaultの本来の使い方に寄せる

  • 今回はAWS Copilotのプロファイルエラーを解決するためにAWS Vaultを使いました。
  • ただキーストアの本来の役割は機密情報の管理・保存にあります。
  • したがって特に問題がなければ、~/.aws/credential に記述しているアクセスキーとシークレットキーを合わせて削除した方がセキュリティ的には良さそうです。

設定ファイル

~/.aws/config
[profile vault_profile]
output = json
region = us-east-1
role_arn = arn:aws:iam::012345678910:role/sample-role
mfa_serial = arn:aws:iam::012345678910:mfa/sample-user
source_profile= default

[default]
output = json
region = us-east-1

[profile sample_profile]
output = json
region = us-east-1
credential_process = aws-vault exec vault_profile --json --prompt=osascript
~/.aws/credential
[default]
region = us-east-1
aws_mfa_device = arn:aws:iam::012345678910:mfa/sample-user

各種コマンドの動作確認

  • 特に問題なく動くことを確認できます。
aws cli
$aws s3 ls --profile sample_profile
2022-02-01 11:01:17 sample-bucket
aws cdk
$cdk list --profile sample_profile
CognitoStack
VPCStack
****************************************************
*** Newer version of CDK is available [2.10.0]   ***
*** Upgrade recommended (npm install -g aws-cdk) ***
****************************************************

参考にしたもの

https://aws.github.io/copilot-cli/docs/credentials/
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html
https://github.com/99designs/aws-vault
https://github.com/hashicorp/terraform-provider-aws/issues/10491

Discussion

ログインするとコメントできます