AWS CLIでインスタンスプロファイルからのAssumeRoleが簡単になりました

AWS CLI

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS のクロスアカウント・オペレーションを楽にする地味なアップデートが AWS CLI にきました。

tl;dr

[dst-role]
role_arn = arn:aws:iam::123456789012:role/some-role
credential_source=Ec2InstanceMetadata

というようにクレデンシャル設定($HOME/.aws/credentials)の credential_sourceEc2InstanceMetadata を指定するだけで、インスタンスプロファイルから対象アカウントの IAM Role を assume 出来るようになりました。

ユースケース

特定のサーバーから複数のAWSアカウントのリソースを操作する事を考えます。

操作先の各 AWS アカウントに IAM クレデンシャルを発行すると、アカウントが増えた時のクレデンシャル発行・配布やクレデンシャルが漏れた場合など、クレデンシャルの管理が厄介です。

そのため、操作先の AWS アカウントに IAM Role を作成し、そのロールを assume して操作することが多いかと思います。

では AWS CLI からどうやって各ロールに assume するればよいでしょうか?

ソースが IAM クレデンシャルの場合

assume 元が IAM クレデンシャルの場合

[operator]
aws_access_key_id = dummy_access_key
aws_secret_access_key = dummy_secret_key

[dst-role]
role_arn = arn:aws:iam::123456789012:role/some-role
source_profile = operator

というように $HOME/.aws/credentials で記述しておけば

$ aws s3 ls --profile dst-role

とするだけで AWS アカウント 123456789012 のロール some-role を assume できます。

ソースがインスタンスプロファイルの場合

問題は assume 元がインスタンスプロファイルの場合です。

インスタンスプロファイルが設定された EC2 から自アカウントを操作する場合、 クレデンシャル設定が見つからなければインスタンスプロファイルにフォールバックするため、クレデンシャルの特別な設定は不要です。

インスタンスプロファイルが設定された EC2 から他アカウントの IAM ロールを assume する場合、クレデンシャル設定から source_profile を削除した

[dst-role]
role_arn = arn:aws:iam::123456789012:role/some-role

のような設定でコマンドを実行出来ると良いのですが、エラーが発生します。

$ aws s3 ls --profile dst-role

Partial credentials found in assume-role, missing: 'source_profile'

そのため、自アカウントで一時クレデンシャルを払い出し($ aws sts assume-role --role-arn=ARN_OF_INSTANCE_PROFILE_ROLE ...)、一時クレデンシャルを環境変数に設定して、他アカウントの IAM ロールを assume するなどといった、回りくどリワークアラウンドが行われてきました。

今回の AWS CLI の機能追加により

[dst-role]
role_arn = arn:aws:iam::123456789012:role/some-role
credential_source=Ec2InstanceMetadata

というようにクレデンシャル設定の credential_sourceEc2InstanceMetadata を指定するだけで、対象アカウントの IAM Role を assume 出来るようになりました。

$ aws s3 ls --profile dst-role

assume 元に インスタンスプロファイル以外を利用する場合

credential_source には Ec2InstanceMetadata 以外も利用可能です。

  • Ec2InstanceMetadata : EC2 インスタンスプロファイルを利用。今回紹介
  • Environment : 環境変数を利用
  • EcsContainer : ECS のコンテナクレデンシャルを利用

対応バージョン

この機能は 2017/11/23 にリリースされた botocore 1.8.1 以上で利用可能です。

$ aws --version
aws-cli/1.12.1 Python/2.7.12 Linux/4.9.38-16.33.amzn1.x86_64 botocore/1.8.1

バージョンが古い場合は $ pip install -U awscli でアップデートして下さい。

Python SDK の Boto3 から使う

この機能は botocore ライブラリで機能追加されているため、 AWS CLI だけでなく、Python SDK(Boto3)からも利用可能です。

>>> import boto3
>>> session = boto3.Session(profile_name='dst-profile')
>>> session.client('s3').list_buckets()
...

aws configure list の出力の違い

参考までに

  • IAM クレデンシャル
  • インスタンスプロファイル
  • インスタンスプロファイルからの assume role

それぞれで $ aws configure list の出力にどのような違いがあるのか確認します。

IAM クレデンシャル

Type が shared-credentials-file となっています。

$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************XXXX shared-credentials-file
secret_key     ****************XXXX shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config

インスタンスプロファイル

Type が iam-role となっています。

$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************XXXX         iam-role
secret_key     ****************XXXX         iam-role
    region           ap-northeast-1      config-file    ~/.aws/config

インスタンスプロファイルからの assume role

Type が assume-role となっています。

$ aws configure list --profile foo-bar
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  foo-bar           manual    --profile
access_key     ****************XXXX      assume-role
secret_key     ****************XXXX      assume-role
    region                <not set>             None    None

まとめ

AWS CLI の地味なアップデートにより、インスタンスプロファイルからのクロスアカウント操作時のクレデンシャル操作がシンプルになりました。 この機能を活用すると、運用系スクリプトの認証周りの処理がスッキリするかもしれません。

参照