(旧)研究メモ

kennkyuumemo

AWS SDK (boto3) でIAM roleをchainしたい

  • Account A: IAM User A, IAM Role A
  • Account B: IAM Role B

という状況で、IAM User A → IAM RoleA → IAM Role BとAssumeしてIAM Role Bの権限でなにかをしたいとき、AWS CLIだと ~/.aws/credentialsで、以下のようにsource_profileをつなげていくことで実現できる。

[iam_user_a]
aws_access_key_id = ....
aws_secret_access_key = ....

[iam_role_a]
role_arn = arn:aws:iam::000000000000:role/iam_role_a
source_profile = iam_user_a

[iam_role_b]
role_arn = arn:aws:iam::000000000000:role/iam_role_b
source_profile = iam_role_a

というのは探すとけっこう出てくるのだが、これをboto3でやりたいという欲求を満たしてくれるものがぱっと探したところ見つからなかった。

Switching to an IAM role (AWS API) - AWS Identity and Access Management

こちらの公式ドキュメントでも、Pythonを使った一段AssumeしてるサンプルをあるもののChainに関しては

You can also use role chaining, which is using a role to assume a second role.

とだけ書いてある。 結局自分がやったのは愚直にこれを繰り返すというもので、IAM User AでAssumeしたIAM Role Aのtemp credentialを使ってIAM Role Bを新しくAssumeし、またそれでゲットしたIAM Role Bのtemp credentialsを使ってなんらかAWSサービスのクライアントを呼び出す(以下の例ではs3)。

# Assume IAM Role A using IAM User A
sts = boto3.client('sts', aws_access_key_id=aws_access_key_id_iam_user_a,
                   aws_secret_access_key=aws_secret_access_key_iam_user_a)
acct = sts.assume_role(
    RoleArn='arn:aws:iam::000000000000:role/iam_role_a',
    RoleSessionName="iam_role_a"
)

# Retrieve credentials from IAM Role A
aws_access_key_id_iam_role_a = acct['Credentials']['AccessKeyId']
aws_secret_access_key_iam_role_a = acct['Credentials']['SecretAccessKey']
session_token_iam_role_a = acct['Credentials']['SessionToken']

# Assume IAM Role B using IAM Role A
sts_assume = boto3.client('sts', aws_access_key_id=aws_access_key_id_iam_role_a,
                          aws_secret_access_key=aws_secret_access_key_iam_role_a,
                          aws_session_token=session_token_iam_role_a)
acct_assume = sts_assume.assume_role(
    RoleArn='arn:aws:iam::000000000000:role/iam_role_b',
    RoleSessionName="iam_role_b"
)

# Retrieve credentials from IAM Role B
aws_access_iam_role_b = acct_assume['Credentials']['AccessKeyId']
aws_secret_iam_role_b = acct_assume['Credentials']['SecretAccessKey']
session_token_iam_role_b = acct_assume['Credentials']['SessionToken']

# Create a S3 connection with IAM Role B
self.s3 = boto3.client('s3', aws_access_key_id=aws_access_iam_role_b,
                       aws_secret_access_key=aws_secret_iam_role_b,
                       aws_session_token=session_token_iam_role_b)