クロスアカウントアクセス(他の AWS アカウントの Amazon S3 バケットにアクセスする方法,Switch Roleも)

IAMのクロスアカウントアクセスがもやっとしていたので、[ドキュメント](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/delegation-cross-acct-access.html)に沿って試してみました。

##シナリオ
AWSアカウントAのAmazon S3バケットにAWSアカウントBのIAMユーザーからアクセスしてみる、というシナリオです。**IAMロールを使用したクロスアカウントアクセス**と**リソースベースのポリシーを使用したクロスアカウントアクセス**をそれぞれ試してみます。

##IAMロールを使用したクロスアカウントアクセス

###準備
* テスト用に2つのアカウントを準備
 ・アカウントA(アカウントIDを控えておく)
 ・アカウントB(アカウントIDを控えておく)
<br>

* テスト用にバケットを準備
 ・アカウントA内にバケット(samplexxxx)を作成
<br>

* テスト用にIAMユーザーとIAMグループを準備
 ・アカウントB内にIAMユーザー(User01),グループ(Developers)を作成
 ・IAMユーザーのアクセスポリシーは指定なし
 ・グループのアクセスポリシーはPowerUserAccessを指定

###ロールの作成
アカウントAで、アカウントAのsamplexxxxバケットへアクセス可能なロールを作成
Role Name : UpdateApp
Select Role Type : Role for Cross-Account Access-Provide access between AWS 　　
account ID : アカウントBのID
Custom Policy : 以下を指定
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::samplexxxx"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::samplexxxx/*"
    }
  ]
}
</pre></div></div>

###IAMグループのアクセスポリシーを変更
アカウントBのDevelopersグループへ、アカウントAのUpdateAPPロールが取得(AssumeRole)できるよう以下のポリシーを追加
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::アカウントAのID:role/UpdateAPP"
  }
}
</pre></div></div>

###アカウントBのIAMユーザーUser01からアカウントAのsamplexxxxバケットへアクセス
Amazon CLIを使用してさくっと確認してみる
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
$ export AWS_ACCESS_KEY_ID=User1のアクセスキーID
$ export AWS_SECRET_ACCESS_KEY=User1のシークレットアクセスキー
$ aws sts assume-role --role-arn arn:aws:iam::アカウントAのID:role/UpdateApp --role-session-name session1(←任意)
{
    "AssumedRoleUser": {
        "AssumedRoleId": "xxxxxxxxxxxx:session1",
        "Arn": "arn:aws:sts::アカウントAのID:assumed-role/UpdateApp/session1"
    },
    "Credentials": {
        "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "SessionToken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Expiration": "2015-01-12T10:10:31Z",
        "AccessKeyId": "xxxxxxxxxxxxxxxxx"
    }
}
↑assume-roleで一時的なアクセス情報が取得される(AccessKeyId,SecretAccessKey,SessionToken)
$ export AWS_ACCESS_KEY_ID=assume-roleで取得されたAccessKeyIdを指定
$ export AWS_SECRET_ACCESS_KEY=assume-roleで取得されたSecretAccessKeyを指定
$ export AWS_SECURITY_TOKEN=assume-roleで取得されたSessionTokenを指定
$ aws s3 ls s3://samplexxxx
2015-01-12 09:04:39     142164 event.jpg
↑アカウントAのsamplexxxxバケット内のファイルにアクセスできている
</pre></div></div>

###Switch Role機能を使ってアカウントBのIAMユーザーUser01からアカウントAのsamplexxxxバケットへアクセス
AWS management consoleからSwitch Role機能により別アカウントへアクセスできるという機能があるので、そちらも試してみます。

1.アカウントBのIAMユーザーUser01でログインし、[User01@accountID]-[Switch Role]を選択
2.アカウントAのアカウントIDおよびRole名(UpdateApp)とDisplay Name(任意)を入力
![switchrole.jpg](https://qiita-image-store.s3.amazonaws.com/0/60916/1e920aee-e07c-2585-8cfb-122298fa7b9b.jpeg)

3.必要に応じてロールの切りかえ
![switchrole2.jpg](https://qiita-image-store.s3.amazonaws.com/0/60916/98eeeaab-c376-e6cb-56de-5148741c0080.jpeg)


ロールを切りかえた場合、このマネジメントコンソール上ではロールで許可されている操作しかできません。今回はアカウントAのsamplexxxxバケットのみ操作できるという状態になります。この機能相当便利なのでは。

##リソースベースのポリシーを使用したクロスアカウントアクセス

###準備
* テスト用に2つのアカウントを準備
 ・アカウントA
 ・アカウントB(アカウントIDを控えておく)
<br>

* テスト用にバケットを準備
 ・アカウントA内にバケット(samplexxxx2)を作成
<br>

* テスト用にIAMユーザーとIAMグループを準備
 ・アカウントB内にIAMユーザー(User02),グループ(Testers)を作成
 ・IAMユーザーのアクセスポリシーは指定なし
 ・グループのアクセスポリシーはPowerUserAccessを指定

###バケットポリシーを設定
アカウントAのsamplexxxx2バケットへ以下バケットポリシー(samplexxxx2へのアクセス権限をアカウントBに付与)を設定
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "AccountBAccess1",
    "Effect": "Allow",
    "Principal": {"AWS": "アカウントBのID"},
    "Action": "s3:\*",
    "Resource": [
      "arn:aws:s3:::samplexxxx2",
      "arn:aws:s3:::samplexxxx2/*"
    ]
  }
}
</pre></div></div>

###IAMグループのアクセスポリシーを変更
アカウントBのIAMグループへアカウントAのsamplexxxx2バケット内をList\*できるよう以下のポリシーを追加
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:List*",
            "Resource": [
                "arn:aws:s3:::samplexxxx2",
                "arn:aws:s3:::samplexxxx2/*"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::samplexxxx2/*"
        }
    ]
}
↑ここで指定されているsamplexxxx2はアカウントAのバケット
アカウントBに許可されているのはS3に対する全操作権限だが、グループの権限としてはList*のみに制限
</pre></div></div>

###アカウントBのIAMユーザーUser02からアカウントAのsamplexxxx2バケットへアクセス
Amazon CLIを使用してさくっと確認してみる
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
$ export AWS_ACCESS_KEY_ID=User02のアクセスキーID
$ export AWS_SECRET_ACCESS_KEY=User02のシークレットアクセスキー
$ aws s3 ls s3://samplexxxx2/
2015-01-12 10:20:18     142164 event2.jpg
↑アカウントAのsamplexxxxバケット内のファイルにアクセスできている
</pre></div></div>

以上です。
うむ。ドキュメントどおりなので当然なのですが、IAMが思いどおり動くと嬉しいかぎり。そしてCLI便利ですね。