AWS staging accountにS3 Bucketを共有する方法

## 背景
AWSで開発していて、本番アカウントと検証（ステージング）アカウントを分けて開発するのは、一般的ではあります。
その時にS3バケット経由で本番とステージングで同期する必要があります。

今回は、Account XのS3 BucketをAccount Yに共有させるスクリプトを掲載します。

## How to code

```Typescript
import AWS = require("aws-sdk");
AWS.config.update({ region: "ap-northeast-1" }); // Set the Region

const s3 = new AWS.S3({ apiVersion: "2006-03-01" });    // Create S3 service object

function shareS3BucketGenerator(bucketName: string) {
    // Create the parameters for calling createBucket
    const bucketParams: AWS.S3.Types.CreateBucketRequest = {
        Bucket: bucketName,
        CreateBucketConfiguration: { LocationConstraint: "ap-northeast-1" }
    };

    // call S3 to create the bucket
    s3.createBucket(bucketParams, function(err, data) {
        if (err) {
            console.log("Failed to create S3 Bucket", err);
        } else {
            console.log("Successfully to create S3 bucket", data.Location);
            const s3BucketPolicy = {
                Version: "2012-10-17",
                Statement: [
                    {
                        Sid: "Example permissions",
                        Effect: "Allow",
                        Principal: {
                            AWS: [
                                "arn:aws:iam::[ACCOUNT_ID]:user/[USER_NAME]",
                                "arn:aws:iam::740291936661:root"
                            ]
                        },
                        Action: [
                            "s3:GetBucketLocation",
                            "s3:ListBucket",
                            "s3:GetObject",
                            "s3:PutObject"
                        ],
                        Resource: [
                            `arn:aws:s3:::${bucketName}`,
                            `arn:aws:s3:::${bucketName}/*`
                        ]
                    }
                ]
            };

            const bucketPolicyParams = {
                Bucket: bucketName,
                Policy: JSON.stringify(s3BucketPolicy)
            };

            s3.putBucketPolicy(bucketPolicyParams, function(err, data) {
                if (err) {
                    console.log("Error. Failed to touch policy", err);
                    s3.deleteBucket(
                        {
                            Bucket: bucketName
                        },
                        function(err, data) {
                            if (err) {
                                console.log(
                                    `Error. Failed to delete bucket ${bucketName}`,
                                    err
                                );
                            } else {
                                console.log(
                                    "Successfully to delete bucket ",
                                    bucketName
                                );
                            }
                        }
                    );
                } else {
                    console.log("Touch policy successfully", data);
                }
            });
        }
    });
}

shareS3BucketGenerator("production-account-shared");
```

## 参考サイト
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/example-walkthroughs-managing-access-example2.html