AWS SDK For Python (Boto3) で「多要素認証(MFA)が必要なAssumeRole(スイッチロール)」をするスクリプトを書いてみる

IAMユーザの認証情報を用いて、別AWSアカウント内のIAMロールにMFA付きでAssumeRole(スイッチロール)するスクリプトのサンプルを書きました。
2021.05.12

オペレーション部の加藤(早)です。

上図のように、あるAWSアカウントのIAMユーザから別AWSアカウントに存在するIAMロールに対して
MFA用のワンタイムパスワードを用いてAssumeRole(スイッチロール)するスクリプトを作成しました。

サンプルコード

  • IAMユーザの持ち主がローカル端末で動かすことを想定しています。
  • ワンタイムパスワードは対話的に入力します。

sample.py

from boto3.session import Session

# 変数設定
PROFILE = 'default' # 端末の ~/.aws/credentials 内で設定しているプロファイル名
ROLE_NAME='myRole' # スイッチロール先のロール名
TARGET_ACCOUNT='123456789012'  # スイッチロール先AWSアカウントID(12桁)
REGION = 'ap-northeast-1' # お好みのリージョンで


# IAMユーザの認証情報を利用したsts, iamクライアント作成
session = Session(profile_name=PROFILE)
sts = session.client('sts')
iam = session.client('iam')

# IAMユーザ情報の取得
iam_user_arn = sts.get_caller_identity()['Arn']
iam_user_name = iam_user_arn.split('/')[1]

mfa_device = iam.list_mfa_devices(UserName=iam_user_name)['MFADevices'][0]['SerialNumber']

# AssumeRole前にワンタイムパスワードの入力待ち
mfa_TOTP = input('MFA code: ')

# AssumeRole
temp_credentials = sts.assume_role(
    RoleArn='arn:aws:iam::' + TARGET_ACCOUNT + ':role/' + ROLE_NAME,
    RoleSessionName='assume_role_sample',
    SerialNumber= mfa_device,
    TokenCode=mfa_TOTP
)

assume_role_session = Session(
    aws_access_key_id=temp_credentials['Credentials']['AccessKeyId'],
    aws_secret_access_key=temp_credentials['Credentials']['SecretAccessKey'],
    aws_session_token=temp_credentials['Credentials']['SessionToken'],
    region_name=REGION
)

# AssumeRole後の作業
# 今回はセッション名を表示してみる
assume_role_sts = assume_role_session.client('sts')
assume_role_session_name = assume_role_sts.get_caller_identity()['Arn']
print(assume_role_session_name)

出力例

  • ワンタイムパスワードを対話的に入力しEnterを押すことで処理が進み、(上記サンプルコードの場合は)AssumeRoleして、セッション名を出力します。
$ python sample.py 
MFA code: 123456
arn:aws:sts::123456789012:assumed-role/myRole/assume_role_sample

まとめ

AssumeRole先アカウントがたくさんある場合は特に、コンソールでの手作業はせず自動化してあげたほうが便利です。 MFAが強制されていてもスクリプト化することはできるので、機会があればぜひやってみてください。

リファレンス・参考

STS — Boto3 Docs 1.17.70 documentation

サンプルコード: 多要素認証での認証情報のリクエスト - AWS Identity and Access Management