はじめに
株式会社インティメート・マージャーのy_kannoです。
弊社ではメインクラウドとしてGCPを利用していますが、
一部のシステムにてAWSを利用しています。
AWSの運用にあたってCLIでのアクセスが必要な際は
- Google workspaceで管理しているGoogleアカウントから
- saml2awsを利用してassume role
を行っているのですが、以下の問題がありました。
- 2段階認証に関する不安定性
- 筆者のローカル端末では、TOTPやプッシュ通知による認証が成功する日もあれば失敗する日もある
- Google側の変更に対し、saml2awsが追随できていない可能性が考えられる
- 運用手順の煩雑さ
- 問題を回避するためにブラウザモードで運用しているが、ログイン手順がCLIで完結せず手間がかかる
これらの課題を踏まえ、代替ソリューションに何かないかと考えている状態でした。
代替案
色々調べてみたところ
- Google Compute EngineのVMに紐付いたサービスアカウント
をベースにAWS CLIからAWS STSを叩いて一時的なcredentialsを取得する方法がありました。
リンク先の方法はGCE VMとサービスアカウントを前提としていますが、
弊社ではGoogleアカウントによるAWS CLI操作を必要としていました。
この記事では、Googleアカウントベースの方法を共有します。
※ 動作のおおまかな仕組み自体はリンク先に記載されている通りです。
この記事で実行する内容としては下記の図(いずれもリンク先より引用)において
1: Get Instance's identity token -> 1: Google account's identity token
Google Cloud IAM(ServiceAccount) -> Google Account
へ置き換えるイメージになります。
権限設定の手順
初期設定 - CLI実行マシン側
-
assume roleしたいAWS IAMロールが存在する前提です
-
gcloud CLIをインストールしておき
hoge.fuga@example.com (対象のgoogleアカウント)で実行できるように設定します -
AWS CLI, jq, curlをインストールしておきます
-
以下のscriptを適当なディレクトリ(ここでは
/opt/credentials.sh
)に追加します
※<YOUR_AWS_ACCOUNT_ID>
をassume roleしたい対象のAWSアカウント
<YOUR_TARGET_IAM_ROLE>
をassume roleしたい対象のAWS IAMロール名 に置き換えておきます
#!/bin/bash
ROLE_ARN="arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:role/<YOUR_TARGET_IAM_ROLE>"
jwt_token=$(gcloud auth print-identity-token)
jwt_sub=$(jq -R 'split(".") | .[1] | @base64d | fromjson' <<< "$jwt_token" | jq -r '.sub')
credentials=$(aws sts assume-role-with-web-identity --role-arn $ROLE_ARN --role-session-name $jwt_sub --web-identity-token $jwt_token | jq '.Credentials' )
export AWS_ACCESS_KEY_ID=$(echo "$credentials" | jq -r '.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo "$credentials" | jq -r '.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo "$credentials" | jq -r '.SessionToken')
初期設定 - AWS側
- 以下コマンドを実行して
gcloud auth print-identity-token
出力されたJWTトークンを https://jwt.io/ でdecodeします。
- decodeされた
PAYLOAD: DATA
からazp, aud, sub
の値をコピーしておきます
コピーした値を元にassumeする対象のAWS IAMロールの信頼関係ポリシーに、
以下の通り記載します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "accounts.google.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:oaud": "<aud-value>",
"accounts.google.com:sub": [
"<sub-value>"
],
"accounts.google.com:aud": "<azp-value>",
}
}
}
]
}
※ 同一ドメインで信頼するGoogleアカウントを追加する際は
accounts.google.com:sub
に値を追加することで対応可能です
ここまで実施すれば初期設定は完了です!
運用時の権限設定
CLIにて対象のGoogleアカウントに切り替えてから
-
source /opt/credentials.sh
を実行します
aws sts get-caller-identity
を実行して以下のように出力されればassume role成功です
{
"UserId":"AIDACKCEVSQ6C2EXAMPLE:[Identity subject claim]",
"Account":"<YOUR_AWS_ACCOUNT_ID>",
"Arn":"arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:role/YOUR_TARGET_IAM_ROLE:[Identity subject claim]"
}
まとめ
Googleアカウントベースによるsaml2awsの運用に困っていたので、
代替案として
- GoogleアカウントのJWTトークンによる
- AWS CLIでのassume role実行
について手順をまとめてみました。
saml2awsはサードパーティ製の非常に便利なツールですが、
- プラットフォーム側の都合に伴って一時的に使えなくなる可能性
- 運用にあたっての代替案
を考えておくのが重要だな、と記事を書いて改めて感じた次第です。
不明な点がありましたら、随時コメントなど頂けますと幸いです。
おわりに
まだまだアドベントカレンダーは続きますのでお楽しみに!
また、インティメート・マージャーでは、新卒から中途採用まで幅広く採用募集中です!
記事を読んで弊社に興味をお持ちいただけた方は、採用情報もあわせてご確認ください!