EC2から別アカウントのS3バケットへのアクセスについて

# なぜこの記事を書くか
AWSのアカウントAのEC2(Amazon Linux2)からアカウントBのS3バケットへAWS CLIを使ってファイルアップロードを行いたいとの要望。   
方法はいくつか考えられるので検討・実験してみた。

# 実現方法の検討
以下、3つを考えてみた。S3バケット名はアカウントBからアカウントAに連絡済とする。
## 1.アクセスキーID、シークレットアクセスキーの共有
おそらく設定や相手方との調整はこの方法が一番簡単だと思われる。
しかしながら、アクセスキーIDとシークレットアクセスキーを外部に漏れた場合を考慮すると望ましくない。

### ◆設定手順
#### [アカウントB]
- S3バケットの参照・アップロードを許可するIAMポリシーを作成

``` IAMポリシー①
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::s3testbucket/*"
        }
    ]
}
```
- IAMユーザを作成し、先に作成したポリシーを割当。アクセスキーID、シークレットアクセスキーをアカウントAへ提供

#### [アカウントA]
- 提供されたアクセスキーID、シークレットアクセスキーをEC2上のAWS CLI(aws configure)で設定し、S3バケットへアクセス


## 2.バケットポリシーによる許可
1のようにクレデンシャルを管理する必要がない
しかしながら、ファイルの所有者が「ファイルをアップロードしたAWSアカウント」になってしまう。


#### [アカウントA]①
- アカウントBのS3バケットの参照・アップロードを許可するIAMポリシーを作成

``` IAMポリシー①
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::s3testbucket/*"
        }
    ]
}
``` 
- 信頼されたエンティティの種類「AWSサービス-EC2」、先に作成したポリシーをアタッチしたIAMロールを作成
- 作成したIAMロールをEC2へアタッチ（例1)
- 作成したIAMロールのARNをアカウントBへ連絡

#### [アカウントB]①
- S3のバケットポリシーに、アカウントAから連絡のあったIAMロールのARNに対してアクセス許可を設定

``` S3バケットポリシー①
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/RoleEc2s3access_anoteraccount"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::s3testbucket/*"
        }
    ]
}
```
※上記はアカウントAのIDが"111111111111"、作成したIAMロールを「RoleEc2s3access_anoteraccount」とした場合の例
#### [アカウントA]②
- EC2からAWS CLIでS3バケットへアクセス


## 3.クロスアカウントアクセス
1～3の中ではこれが一番ベストと考えているが、正直設定や相手との調整が少々面倒。
AsumeRoleの話を相手が理解しているかにもよる。

#### [アカウントA]①
- アカウントAのアカウントID[数字12桁]をアカウントBへ連絡

#### [アカウントB]①
- S3バケットへアクセスを許可するポリシーを作成

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::s3testbucket/*"
        }
    ]
}
```
- 信頼されたエンティティの種類「別のAWSアカウント」、アカウントIDにアカウントAのアカウントIDを設定し、先に作成したポリシーをアタッチしたIAMロールを作成
- 作成したIAMロールのARNをアカウントAへ連絡

####[アカウントA]②
- アカウントBから連絡のあったIAMロールのARNへのAsumeRoleを許可するポリシーを作成する

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111111111111:role/RoleAnoterS3upload"
        }
    ]
}
```
※上記はアカウントAのIDが"111111111111"、作成したIAMロールを「RoleAnoterS3upload」とした場合の例

- 信頼されたエンティティの種類「AWSサービス-EC2」、先に作成したポリシーをアタッチしたIAMロールを作成
- EC2にログインし、profileを作成する。

```
mkdir ~/.aws/
cd ~/.aws/
vi config
--- ※configの中に記載する内容 ここから---
[profile RoleEc2s3access_anoteraccount]
role_arn = arn:aws:iam::111111111111:role/RoleAnoterS3upload

credential_source = Ec2InstanceMetadata
--- ※configの中に各する内容 ここまで---
aws s3 cp stskensyo.txt s3://s3testbucket--profile RoleEc2s3access_anoteraccount
```
・EC2からAWS CLIでS3バケットへアクセス

# 感想
・バケットポリシーのパブリックアクセスの部分の設定はもう一度整理する必要がある。2のやり方ではパブリックアクセスを許可する必要があるのかと考えたが特にその必要はなかった様子
・AssumeRoleする際、外部IDを使ったほうがよいかな。



#参考文献
#### 【そんなときどうする？】S3をクロスアカウントで使いたい
https://blog.serverworks.co.jp/tech/2016/10/27/s3-crossaccount/
#### Amazon EC2 インスタンスに、別の AWS アカウントの Amazon S3 バケットへのアクセス権限を付与するにはどうすればよいですか?
https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-instance-access-bucket/
#### 初めてのAssumeRole
https://dev.classmethod.jp/articles/sugano-005-s3/
#### クロスアカウントアクセス(他の AWS アカウントの Amazon S3 バケットにアクセスする方法,Switch Roleも)
https://qiita.com/emai/items/4b17ee058db965253332