AWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に向けた知識の整理 IAMポリシーサンプル

# 概要
AWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に向けた小ネタ集。
今回は様々なところで出題されるIAMポリシーで制限可能などの問題や設問に対し、具体的にIAMポリシーをどう書いたらいいかわからず調べてみたいくつかのIAMポリシーのサンプルです。

[2020年10月]
2回目の受験でついにプロフェッショナル試験に合格しました！
合格体験記／勉強法を以下で投稿しているので良かったら読んでください。
試験受ける予定がある方の少しでも役に立てればと思います(^^)

[AWS初心者がAWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に合格した時の勉強法](https://qiita.com/fkooo/items/17fa401f4e46ecd00675 "AWS初心者がAWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に合格した時の勉強法")

## EC2 インスタンスや EBS ボリュームの作成において、指定可能なタグを制限する方法

* https://aws.amazon.com/jp/premiumsupport/knowledge-center/iam-policy-tags-restrict/
    * SCP や IAMポリシーでaws:RequestTag/aws:TagKeys（TagKeysは大文字と小文字の区別可能）、ForAllValues（すべて）/ForAnyValue（いずれか）を定義してタグを強要する。
    * 次の例は、「key1/value1」 and 「key2/value2」 の指定のみ OK
    * 「KEY1/value1」 and 「key2/value2」 は 指定NGとする指定方法。　

```json
"Condition": {
 "StringEquals": {
  "aws:RequestTag/key1": "value1",
  "aws:RequestTag/key2": "value2"
 },
 "ForAllValues:StringEquals": {
  "aws:TagKeys": [
   "key1",
   "key2"
  ]
 }
}
```

## 特定の VPC エンドポイントへのアクセスの制限

* https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/example-bucket-policies-vpc-endpoint.html
    * 次の例は、特定のバケット (awsexamplebucket1) に対するアクセスを ID が vpce-1a2b3c4d の VPC エンドポイントからのアクセスのみに制限します。

```json
{
   "Version": "2012-10-17",
   "Id": "Policy1415115909152",
   "Statement": [
     {
       "Sid": "Access-to-specific-VPCE-only",
       "Principal": "*",
       "Action": "s3:*",
       "Effect": "Deny",
       "Resource": ["arn:aws:s3:::awsexamplebucket1",
                    "arn:aws:s3:::awsexamplebucket1/*"],
       "Condition": {
         "StringNotEquals": {
           "aws:SourceVpce": "vpce-1a2b3c4d"
         }
       }
     }
   ]
}
```

## 指定した IP アドレス範囲アクセスからCodeCommitリポジトリに接続するユーザーを許可

* https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html
    * 次の例は、特定のIPアドレスレンジ (203.0.113.0/16) からのアクセスのみに制限します。

```json
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Deny",
         "Action": [
            "codecommit:*"
         ],
         "Resource": "*",
         "Condition": {
            "NotIpAddress": {
               "aws:SourceIp": [
                  "203.0.113.0/16"
               ]
            }
         }
      }
   ]
}
```

## AssumeRoleを利用した様々な外部アクセスの許可

* https://dev.classmethod.jp/articles/iam-role-and-assumerole/
    * 他のAWSアカウントを信頼する（クロスアカウントアクセスを許可する）。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": [ "123456789012" ] // ← AWSアカウントを信頼
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

* AWSサービスからアクセスを許可する。

```json
{
  "Version" : "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [ "ec2.amazonaws.com" ] // ← EC2サービスを信頼
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

* Facebookユーザのアクセスを許可する。
* PrincipalとConditionを利用して、Facebookの外部IDを指定する。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Principal": {
        "Federated": "graph.facebook.com"
      },
      "Condition": {
        "StringEquals": {
          "graph.facebook.com:app_id": "012345678901234" // ← FacebookアプリケーションID
        }
      }
    }
  ]
}
```
## ウェブ ID フェデレーションを使用したユーザーの識別

* https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_oidc_user-id.html
    * 次の例は、バケットのプレフィックスが文字列に一致する場合にのみ、Amazon S3 のバケットへのアクセスを許可するアクセス許可ポリシーを示します。
    * 例えば、「myBucket/Amazon/mynumbersgame/user1」
    * この例では、ユーザーが Login with Amazon を使用してサインインし、mynumbersgame というをアプリを使用していると仮定しています。
    * ユーザーの一意の ID は、user_id と呼ばれる属性として表示されます。 
    * Resourceにユーザー専用のバケットパスを指定します。
    * ConditionにユーザーのIDを指定します。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::myBucket"],
      "Condition": {"StringLike": {"s3:prefix": ["Amazon/mynumbersgame/${www.amazon.com:user_id}/*"]}}
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::myBucket/amazon/mynumbersgame/${www.amazon.com:user_id}",
        "arn:aws:s3:::myBucket/amazon/mynumbersgame/${www.amazon.com:user_id}/*"
      ]
    }
  ]
}
```

## EC2 の IAMロールとインスタンスプロファイルの関連

* https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
    * IAMポリシーではないが、インスタンスプロファイルとIAMロールの具体例
    * create-instance-profile コマンドを使用して、s3access-profile という名前のインスタンスプロファイルを作成します。
        * aws iam create-instance-profile --instance-profile-name s3access-profile

```json
{
    "InstanceProfile": {
        "InstanceProfileId": "AIPAJTLBPJLEGREXAMPLE",
        "Roles": [],
        "CreateDate": "2013-12-12T23:53:34.093Z",
        "InstanceProfileName": "s3access-profile",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:instance-profile/s3access-profile"
    }
}
```

* 次のコマンドで s3access-profile インスタンスプロファイルに s3access ロールを追加します。
    * aws iam add-role-to-instance-profile --instance-profile-name s3access-profile --role-name s3access
    * このコマンド実行で上記のインスタンスプロファイルのRolesに s3access ロールが設定されるはず。

## その他参考

アソシエイト資格の勉強法は以下を参照

[AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法](https://qiita.com/fkooo/items/e5284a4ed3c3466ffd41 "AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法")

プロフェッショナル資格の勉強法は以下を参照

[AWS初心者がAWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に合格した時の勉強法](https://qiita.com/fkooo/items/17fa401f4e46ecd00675 "AWS初心者がAWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に合格した時の勉強法")

その他のプロフェッショナルの小ネタは以下を参照

[プロレベルのTips](https://qiita.com/fkooo/items/e3c0c9a11d078619cbe0 "プロレベルのTips")
[フェデレーションとDDoS対策](https://qiita.com/fkooo/items/a6d71407b2bed42332cc "フェデレーションとDDoS対策")
[IAMポリシー](https://qiita.com/fkooo/items/45cd86fa6e71d51f12e2 "IAMポリシー")
[DR対策](https://qiita.com/fkooo/items/cbeb13fea8b99e4b7964 "DR対策")
IAMポリシーサンプル（本記事）