Boto3でAssumeRoleする | AWS SDK for Python

Boto3 (AWS SDK for Python) でAssumeRoleするやり方の備忘録です。


はじめに

Boto3を利用したPythonスクリプト内にてAssumeRoleしたい状況にはしばしば遭遇します。

その度にAssumeRole実装の詳細を調べなおしている自分がいるので、今回はその実装方法の備忘録を書き残します。


Boto3でAssumeRoleする

AssumeRole関数の実装

まずは、AssumeRoleするためのPython関数を実装します。

※実装はaws-samplesにあるこちらのスクリプトを参考/改変しています。

import boto3

def assume_role(aws_account_number: str, role_name: str) -> boto3.Session:
    """
    Assumes the provided role in the target account and returns Session.
    Args:
        - aws_account_number: AWS Account Number
        - role_name: Role to assume in target account
    Returns:
        AssumeRole Session.
    """
    try:
        sts_client = boto3.client('sts')

        # Get the current partition
        partition = sts_client.get_caller_identity()['Arn'].split(":")[1]

        response = sts_client.assume_role(
            RoleArn=f'arn:{partition}:iam::{aws_account_number}:role/{role_name}',
            RoleSessionName=f'SessionFor{role_name}In{aws_account_number}'
        )

        # Storing STS credentials
        session = boto3.Session(
            aws_access_key_id=response['Credentials']['AccessKeyId'],
            aws_secret_access_key=response['Credentials']['SecretAccessKey'],
            aws_session_token=response['Credentials']['SessionToken']
        )
    except Exception as e:
        raise ValueError(f'Error in AssumeRole process: {e}')
      
    print(f'Assumed session for {role_name} in {aws_account_number}.')

    return session

このコードの大まかな流れを説明すると、以下のようになります:

  1. AssumeRoleしたいRole名とアカウントidを引数に受け取る
  2. STSのBoto3クライアントを作成する
  3. AssumeRoleする
  4. AssumeRoleしたcredentialsを設定したSessionを返却する

この関数から返却されたSessionを利用すれば、AssumeRole先の権限でアクションが行える、という訳です。


では次に、上記AssumeRole関数の簡単な使用例を見ていきます。


使用例

上記関数assume_role()を用いて、AssumeRole先の権限でs3バケットリストを取得するAPIを叩いてみます。

# 必要情報の格納
role_name = 'AssumeRoleTest' # AssumeRoleしたいRole名
target_account_id = '123456789012' # AssumeRole先のアカウントid

# AssumeRole先のSessionからs3のboto3クライアントを取得
session = assume_role(target_account_id,role_name)
s3_client = session.client('s3')

# APIの実行
buckets = s3_client.list_buckets()
print(buckets)

assume_role()で取得したsessionから、各種boto3クライアントを発行する、というのが主な使い方になります。

上の例ではs3クライアントを発行していますが、ほかのサービスを使うときも、それぞれ対象サービスのクライアントを発行します。

client = session.client('[対象サービス名]')

各サービスのboto3クライアント発行方法の詳細は、直接ドキュメントに当たるのがおすすめです:
Boto3 documentation — Boto3 Docs 1.16.9 documentation


以上、AssumeRole関数の簡単な使用方法でした。


おわりに

今回は、Boto3でAssumeRoleする方法を書きました。

最近は、AssumeRoleの利用を前提としたきめ細かいRole設計も普通になってきたかと思います。 マルチアカウントで運用しているような大きなプロジェクト等では、AssumeRoleの活用は必須といえるでしょう。

そのようなケースでの参考になれば幸いです。


関連記事

AWS CLIのs3 cpとs3 syncの違いをまとめました。 www.bioerrorlog.work


Pythonではじめて自作したゲームの製作記録です。 www.bioerrorlog.work


参考

GitHub - aws-samples/amazon-detective-multiaccount-scripts: interact with Amazon Detective in multiple accounts and regions

Boto3 documentation — Boto3 Docs 1.16.9 documentation

AssumeRole - AWS Security Token Service