初めてのAssumeRole

2016.04.21

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

まだまだ使ったことの無いAWSサービスが多い菅野です。
今回はサービスではないのですが、AssumeRoleという機能を初めて使ったのでまとめてみました。

案件としては別AWSアカウントに存在するS3バケットにファイルを保存する事が目的なのですが、
保存するだけでしたらバケットポリシーで別アカウントのIDを許可するという方法があります。

ただ、その方法だとファイルの所有者が「ファイルをアップロードしたAWSアカウント」になってしまいますので、
トラブルにならないように、AssuemRoleを使うことでファイルの所有者がS3バケットを持つアカウントとなるようにします。

今回の目標

  • 別アカウントのS3バケットにファイルを保存する
  • AssumeRoleにより権限の委譲を行い、S3バケットへの保存許可を得る

作業が完了した時には、以下のようなイメージになります
AWS Design 2

大まかな作業の流れ

【S3バケットを持つアカウント(アカウント名:12345)】

  • AssumeRole用のロールを作成する(ロール名:s3put-ok)
  • ロールの持つ設定で相手アカウント(アカウント名:ABCDE)を許可する
  • ロールのカスタムポリシーでS3バケット(バケット名:test-bucket)へPutObjectだけを許可するポリシーを設定する

【S3にputするアカウント(アカウント名:ABCDE)】

  • AssumeRoleを許可するユーザーを作成する
  • 対象のEC2インスタンスにcredentialsとconfigファイルを作成する

AssumeRole用のロールを作成する

作業はS3バケットを持つアカウント(アカウント名:12345)で行います。

  • IAMの「ロール」のページを開き、「新しいロールの作成」ボタンをクリック
  • ロール名には「s3put-ok」と入力
  • ロールタイプの選択ページでは、「クロスアカウントアクセスのロール」を選択
  • 「所有している AWS アカウント間のアクセスを提供します」の「選択」ボタンをクリック
  • 許可する相手のアカウント(アカウント名:12345)のアカウントIDを入力
  • 「ポリシーのアタッチ」のページでは、何も選択せずに「次のステップ」ボタンをクリック
  • 「ロールの作成」ボタンをクリック
  • 作成したロールが一覧に表示されるのでクリック
  • 「インラインポリシー」をクリックし、表示されたリンクをクリック
  • 「カスタムポリシー」をクリックし、「選択ボタン」をクリック
  • 「ポリシー名」に「Allow-PutObject」と入力
  • 「ポリシードキュメント」に以下の内容を記載(バケット名の変更を忘れないように)
  • {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::test-bucket/*"
            }
        ]
    }
  • 「ポリシーの適用」ボタンをクリック

AssumeRoleを許可するユーザーを作成する

作業はファイルをS3にコピーするアカウント(アカウント名:ABCDE)で行います。

  • IAMの「ユーザー」のページを開き、「新規ユーザーの作成」ボタンをクリック
  • ユーザー名に「send-to-s3」と入力し「作成」ボタンをクリック
  • 「ユーザーのセキュリティ認証情報を表示」をクリックし、表示されたアクセスキーと シークレットアクセスキーをメモする
  • 「閉じる」ボタンをクリック
  • ユーザー一覧で、今作成したユーザーを選択
  • 「インラインポリシー」をクリックし、表示されたリンクをクリック
  • 「カスタムポリシー」をクリックし、「選択ボタン」をクリック
  • 「ポリシー名」に「Allow-AssumeRole」と入力
  • 「ポリシードキュメント」に以下の内容を記載
  • {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "sts:AssumeRole",
                "Resource": "arn:aws:iam:: 【12345のアカウントのID】:role/s3put-ok"
            }
        ]
    }

対象のEC2インスタンスにcredentialsとconfigファイルを作成する

credentialsファイルにユーザーの情報を登録します。
configファイルには相手アカウントと借りるroleの情報を登録します。
これら二つのファイルを作っておけば、コマンドにオプションを一つ追加するだけで済みます。

credentialsファイルを作成する

  • ファイル名:~/.aws/credentials
  • ファイルの内容は以下
  • [Allow-AssumeRole-user]
    aws_access_key_id = アクセスキーID
    aws_secret_access_key = シークレットアクセスキー

configファイルを作成する

  • ファイル名:~/.aws/config
  • ファイルの内容は以下
  • [profile Allow-AssumeRole-profile]
    role_arn = arn:aws:iam:: 【12345のアカウントのID】:role/s3put-ok
    source_profile = Allow-AssumeRole-user

ファイルをS3バケットにコピーしてみる

以下のコマンドでコピーするファイルを作成します

date > ~/test-file.txt

S3バケットへコピーするコマンドはこれだけです。

aws --profile Allow-AssumeRole-profile s3 cp ~/test-file.txt s3://test-bucket/

実行すると、以下のレスポンスが表示されたはずです。

upload: ./test-file.txt to s3://test-bucket/test-file.txt

今回もできました

別アカウントのS3バケットにファイルをコピーする事ができました。
.awsフォルダの下にcredentialsとconfigの二つのファイルを用意したので
「--profile Allow-AssumeRole-profile」というオプションをつけるだけで済みます。
もう一つの目標だったS3バケットにコピーしたファイルの所有者は、マネジメントコンソールから
S3バケットにコピーしたファイルのプロパティを見て確認してみてください。
S3バケットを持つアカウントになっているはずです。

このように、AssumeRoleを使えば別アカウントに分かれていてもお互いのリソースを使えまので、
開発用アカウントと本番アカウントを分けるといった事も検討できると思います。

AssumeRoleは覚えておいて損のない機能だと思いますので、是非一度はお試しください。

参考ページ

これらのページを参考にさせていただきました。
ありがとうございました。
AWS CLIがAssumeRoleによる自動クレデンシャル取得とMFAに対応しました!