「お前には n 日間でAWSを学んでもらう」 #3 です. AWSの提供するサービスのうちよく名前を聞くであろう「S3」をEC2インスタンスから触ってみたいと思います.

この記事のスコープ

  • IAMロールの作成
  • IAMロールのインスタンスへの付与
  • S3の利用

スコープ外

  • IAMユーザーの作成
  • AWS CLIのインストール
  • インスタンスの起動の方法

上記は前の記事をお読みください.

免責事項

思わぬ請求他, 生じた損害に対しては一切の責任を負いかねます.

Amazon S3 (Amazon Simple Storage Service)

公式によると, スケーラビリティ・可用性・セキュリティ・パフォーマンスを提供するオブジェクトストレージサービスだそうです. まあどこかで見た, 「何かをアップロードするとそれをダウンロードするためのURLを返してくれるサービス」くらいの認識の方がわかりやすいですね.

なお無料枠は以下の通りです. (2020/06/29)

  • S3標準ストレージクラス
  • 5GB
  • 20,000 GETリクエスト
  • 2,000 PUT
  • COPY, POST, LIST
  • データ送信 15 GB

この記事では上記範囲内に収まるように考えておりますが, 思わぬ課金などはご注意ください.

目標構成

次のような構成とします.

前回と同じくVPCをサブネットに切り分けてそのサブネット内にインスタンスを立ち上げます. このインスタンスは私のグローバルIPアドレスでのみSSHアクセスできるようにします. また, インスタンスにIAMロールを与え, S3へのフルアクセス権を与えます.

目標構成

インスタンスの起動

前回と同様にインスタンスを起動します. ここまでが前提です. お好きなSSHクライアントソフトを使ってインスタンスに接続できることを確認してください.

S3バケットの作成

なにはともあれ, Amazon S3にデータをアップロードするために必要なS3 バケットを作成します.

$ aws s3api create-bucket `
--bucket thiele-test-my-bucket `
--region ap-northeast-1 `
--create-bucket-configuration LocationConstraint=ap-northeast-1

--create-bucket-configuration でどのregionにバケットを作成するのかを指定できます.

{
    "Location": "http://thiele-test-my-bucket.s3.amazonaws.com/"
}

デフォルトでACL(アクセス制御リスト)がPrivateなので自分以外は接続できません.

S3アクセス用 IAM ロールの作成

今回作成したS3バケットにアクセスできるIAMロールを作成します.
PowerUserAccessではこのあたりのことができないのでまずIAMFullAccess ポリシーを利用ユーザーにアタッチしておきます.(#1参考)

その後次を実行しましょう.

$aws iam create-role `
--role-name grant_access_to_test_bucket_and_objects_in_the_bucket `
--assume-role-policy-document  file://C:\Users\xxxxx\Test-Role-Trust.json

なおTest-Role-Trust.jsonの中身は次の通りです:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }
  ]
}
Test-Role-Trust.json

これで, EC2インスタンスを信頼して, EC2インスタンスにRoleを引き受けてもらうことができる...という解釈をしました. 色々調べてみましたがこの「信頼関係」なかなか難しそうです.

実行結果は次の通りです:

{
    "Role": {
        "Path": "/",
        "RoleName": "grant_access_to_test_bucket_and_objects_in_the_bucket",
        "RoleId": "XXXXXXXXXXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::xxxxxxxxxxxx:role/grant_access_to_test_bucket_and_objects_in_the_bucket",
        "CreateDate": "2020-06-29T15:11:57+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
create-role に対するレスポンス

次にアクセスポリシーをロールにアタッチします.

$ aws iam put-role-policy `
--role-name grant_access_to_test_bucket_and_objects_in_the_bucket `
--policy-name S3-Permissions `
--policy-document file://C:\Users\xxxxx\Test-Role.json

なおTest-Role.jsonは次の通りです:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::thiele-test-my-bucket",
                "arn:aws:s3:::thiele-test-my-bucket/*"
            ]
        }
    ]
}

bucketそれ自体とその中のオブジェクトに対するアクションの全てを許可しています.

インスタンスプロファイルの作成とロールの付与

ロールをインスタンスに付与するにはインスタンスプロファイルが必要そうです.インスタンスプロファイルを作りましょう.

$ aws iam create-instance-profile `
--instance-profile-name test-buckets-access-profile
{
    "InstanceProfile": {
        "Path": "/",
        "InstanceProfileName": "test-buckets-access-profile",
        "InstanceProfileId": "XXXXXXXXXXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/test-buckets-access-profile",
        "CreateDate": "2020-06-29T15:21:11+00:00",
        "Roles": []
    }
}
create-instance-profileに対するレスポンス
$ aws iam add-role-to-instance-profile `
--instance-profile-name test-buckets-access-profile `
--role-name grant_access_to_test_bucket_and_objects_in_the_bucket

IAMロールのインスタンスへのアタッチ

ロールをアタッチするインスタンスのIDが必要です. aws ec2 describe-instances を用いることで調べることができます.

IAMロールをインスタンスへアタッチしましょう.

$ aws ec2 associate-iam-instance-profile `
--instance-id i-xxxxxxxxxxxxxxxxx `
--iam-instance-profile Name="test-buckets-access-profile"
{
    "IamInstanceProfileAssociation": {
        "AssociationId": "iip-assoc-xxxxxxxxxxxxxxxxx",
        "InstanceId": "i-xxxxxxxxxxxxxxxxx",
        "IamInstanceProfile": {
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:instance-profile/test-buckets-access-profile",
            "Id": "XXXXXXXXXXXXXXXXXXXXX"
        },
        "State": "associating"
    }
}
associate-iam-instance-profile に対するレスポンス

これでIAMロールをEC2インスタンスにアタッチすることができました!

S3を少しだけ触る

好きなSSHクライアントでEC2インスタンスに接続していると思います.

そのEC2インスタンスの中にAWS CLI v2をインストールしてください.

インストールが完了したら次のコマンドを実行してみましょう.

$ aws s3 ls s3://thiele-test-my-bucket
(Amazon Linux上)

何も表示されませんね!無事にできたっぽいことがわかります!

次にファイルをS3に転送してみたいと思います. 適当にインスタンス上に test.txt を作成してください. そのあと次のコマンドで test.txt をS3上に転送できます.(コピー)

$ aws s3 cp test.txt s3://thiele-test-my-bucket/test.txt

upload: ./test.txt to s3://thiele-test-my-bucket/test.txt

これで test.txt をアップロードすることができました.

おわり!

これでEC2インスタンスにIAMロールを付与して, EC2とS3とをつなげることができました!

そろそろシェルスクリプトを使ったオートメーションとか考えたいですね... できるかな...?

この記事で作ったものは必要に応じて停止したり終了したりしてください!