🥈

Claude CodeでAWS CLIをAssume Roleして動かしたかった

に公開

概要

Claude Code上でAWS CLIを実行しながら作業をしようと思っていました。
対象のアカウントはMFAが必須なアカウントであり、かつSwitch roleをする必要があります。
※ Bedrockを使ってClaude Codeを動かしているので、環境変数に入れられなかったのも大きいです

Claude Code上で上記の操作およびセッションの有効期限が切れた場合の有効化をやってほしかったのですが、上手くいかなかったというメモになります

最終的にはログイン情報を ~/.aws/credentials に追記して、そのProfileを利用するようにしています。
誰かほかに良い案があれば教えてください

詳細

AWSのCLIを生成AIに使ってもらったら業務効率化できるのではと思い、Claude Codeに実行させてみることにしました。
Claudeは普段はBedrockで利用しているので、それを維持しつつ、他のアカウントでCLIを実行できるようにすることを目標としました。
ごちゃごちゃしていてわかりにくいので、いったん整理します。

  • Bedrockに利用するAWSアカウント
    • identity centerで発行したCredentialを環境変数にセットして利用している
  • ログイン用のAWSアカウント
    • Switch Roleするために存在している。MFA必須
  • 対象のAWSアカウント
    • CLIを実行したいアカウント

Claude CodeをBedrockで動かす

ドキュメントにもあるように、Bedrockの設定はいくつかあります。

https://docs.anthropic.com/ja/docs/claude-code/amazon-bedrock

今回は環境変数にセットして利用しています。

export AWS_ACCESS_KEY_ID=your-access-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-access-key
export AWS_SESSION_TOKEN=your-session-token

以下の環境変数を設しないと、Anthropic側のアカウントが必要になるので、設定を忘れないようにしてください

export CLAUDE_CODE_USE_BEDROCK=1

Claude CodeにMFAの入力やSwitch Roleをやってもらう

Claude Codeを実行してから以下のプロンプトを実行してみました。
ログイン用のアカウントはReadmeか何かで指定していたので、そのProfileを使ってもらっていたと思います

xxxx のアカウントにassume roleしてください。roleは SRole とします

MFAの入力をして無事に動きましたが、Credentialはセットされているようには見えませんでした。
そこで上記の処理を実行しつつ環境変数への設定をお願いしました。

が、ClaudeCodeは実行中に環境変数を設定できないため、CLIの都度、認証が必要になるか、結果をファイルに書き込みしておいて、AWS CLIの実行前に環境変数に読み込む必要があります。
後者であればある程度うまくいくイメージがあるものの、何かの拍子に変数を読み忘れてしまう可能性があるなと思い、断念しました。

よくよく考えてみると、あとから環境変数が設定できると意図しない動作を仕込まれやすくなるので、安全のためにも設定できないほうが無難だなと思いました。

各プロジェクトで必要な値が固定であるなら、settings.json で設定するのがよさそうですが、今回は動的な認証情報が必要なので、別の手段が必要になります。
https://docs.anthropic.com/ja/docs/claude-code/settings#設定ファイル

事前に実行する

Claude Codeに実行する前に該当のアカウントにログインできる変数をを設定することにしました。
コードは何かしらの生成AIに書いてもらっていますが、参考までに共有しておきます

#!/usr/bin/env bash
set -euo pipefail

# ———— 設定変数 ————
PROFILE="profile"                               # ~/.aws/config のプロファイル名
MFA_SERIAL="arn:aws:iam::xxxx:mfa/merutin" # MFA デバイスの ARN
ROLE_ARN="arn:aws:iam::"                          # 切り替え先のロール ARN
ROLE_SESSION_NAME="session1"                      # AssumeRole 時のセッション名

# コマンドライン引数または入力で MFA コードとアカウントを取得
if [ $# -ge 1 ]; then
  ACCOUNT=$1
else
  read -p "Enter target account: " ACCOUNT
fi

if [ $# -ge 2 ]; then
  ROLE_NAME=$2
else
  read -p "Enter role name (default: hogehoge): " ROLE_NAME
  if [ -z "$ROLE_NAME" ]; then
    ROLE_NAME="hogehoge"
  fi
fi

if [ $# -ge 3 ]; then
  MFA_CODE=$3
else
  read -p "Enter MFA code: " MFA_CODE
fi


echo "🔐 MFA認証とロール切り替えを実行します..."

# ① MFA セッション取得
echo "MFA セッション取得中..."
MFA_JSON=$(aws sts get-session-token \
  --profile "${PROFILE}" \
  --serial-number "${MFA_SERIAL}" \
  --token-code "${MFA_CODE}" \
  --duration-seconds 36000 \
  --output json)

export AWS_ACCESS_KEY_ID=$(  echo "${MFA_JSON}" | jq -r '.Credentials.AccessKeyId'    )
export AWS_SECRET_ACCESS_KEY=$(echo "${MFA_JSON}" | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(   echo "${MFA_JSON}" | jq -r '.Credentials.SessionToken'   )

# ② 別アカウントへ AssumeRole(Switch Role)
echo "Role ${ACCOUNT}:role/${ROLE_NAME} に切り替え中..."
ASSUME_JSON=$(aws sts assume-role \
  --role-arn "${ROLE_ARN}${ACCOUNT}:role/${ROLE_NAME}" \
  --role-session-name "${ROLE_SESSION_NAME}" \
  --duration-seconds 3600 \
  --output json)

echo "[srole]"
echo "AWS_ACCESS_KEY_ID=$(  echo "${ASSUME_JSON}" | jq -r '.Credentials.AccessKeyId'    )"
echo "AWS_SECRET_ACCESS_KEY=$(echo "${ASSUME_JSON}" | jq -r '.Credentials.SecretAccessKey')"
echo "AWS_SESSION_TOKEN=$(   echo "${ASSUME_JSON}" | jq -r '.Credentials.SessionToken'   )"

echo "✅ ロールの切り替えが完了しました: ${ACCOUNT}:role/${ROLE_NAME}"

出力した値を環境変数にセットして起動すればいいと思っていたのですが、環境変数はBedorckを利用しているAWSのアカウント用に利用しているため、使えないことがわかりました。
そのため、 ~/.aws/credentials に設定をしつつ、Claude Codeには該当のProfileを使ってもらうよ指定することでAWS CLIが実行できるようになりました。

~/.aws/credentials
[srole]
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_SESSION_TOKEN=your-session-token

ちなみに、以下のようなを処理をお願いしたのですが、直接CLIを実行するのではなく、Shellをまず作成して、そのShellを実行するような処理になっていました。

 以降の操作は基本的に東京リージョンに対して行ってください。\ 
 EBSの一覧を出力して、 `ebs.csv` としてまとめてください。その際、ディスクのタイプとサイズは最低限出力してください

作成されたシェル

#!/bin/bash

# Set Tokyo region
AWS_REGION="ap-northeast-1"

# Fetch EBS volumes info and output to CSV
echo "VolumeId,VolumeType,Size,State,AvailabilityZone,CreateTime,Encrypted,SnapshotId" > ebs.csv

aws ec2 describe-volumes --region ${AWS_REGION} --query "Volumes[*].[VolumeId,VolumeType,Size,State,AvailabilityZone,CreateTime,Encrypted,SnapshotId]" --output text --profile srole | tr '\t' ',' >> ebs.csv

echo "EBS volumes data saved to ebs.csv"

結論

  • 環境変数も利用できなかったので、 ~/.aws/credentials に認証情報を格納しておき、対象のProfileを指定することで何とか使いたい環境のAWS CLIが利用できるようになりました。

  • この方法だと、手作業面倒なのと、AWSのセッションが1時間で切れてしまうため、改善の余地はあるなと感じています

  • だれかいい運用方法を知っていれば教えてください。。

おまけ

ClaudeCodeでAWS CLIを利用して業務の効率化ができたかというと、まだまだ言語化できてない部分が多くできてないのが現状です。
ただ、ある程度決まっている処理に対して繰り返し作業する場合は、Readmeなどの指示をちゃんと書いておけばいい感じになりそうなイメージもあります。
試行錯誤していく中で、何かいい知見が見つかればまた記事にまとめておきたいと思います。

DELTAテックブログ

Discussion