AWS CLIで Web サイトを構築、管理、運用する(15日目)

15日目です。
昨日に引き続き、 EC2 を立ち上げるために設定をしていきます。

今回は、 IAM Role とそれに関係するリソースを作っていきます。

では、残り10日、いってみよ！


# 15日目の要約
IAM Role と愉快な仲間たちをつくるよ！

# AWS CLI の準備
このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。

バージョン１
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html

バージョン２
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

# 概要
IAM Roleやポリシー、インスタンスプロファイルを作って、AWSリソースからAWSサービスを操作できるようにするよ！

# さあ、やってみよう！
## 必要なアクション許可を確認する
IAM Roleを作るにあたって、関連づける IAM ポリシーにどんなアクション許可(権限）が必要かを確認します。
さらに、最小権限の原則というベストプラクティスに則り、必要最低限の権限にします。
必要な権限があとから必要になったら追加できるのでご安心ください。

今回作るポリシーについては、 Route53 のレコード更新が必要なので ChangeResourceRecordSets アクションに対して許可を与えます。
また、さらに絞るのであれば、 ホストゾーンのIDを確認して、リソース固定します。

## IAM ポリシーを作る
IAM ポリシーは管理タイプとして大きく分けて2種類あります。

* インラインポリシー
* 管理ポリシー
 * AWS 管理
 * カスタマー管理(ユーザー管理）

ちょっと確認するだけなら、インラインポリシーでよいのですが、今回は、カスタマー管理ポリシーとして作成します。

コマンドは iam create-policy を使います。

```sh
aws iam create-policy --policy-name pol-adcale --policy-document '{"Version": "2012-10-17","Statement": [{"Sid": "AdventCalendar","Effect": "Allow","Action": "route53:ChangeResourceRecordSets","Resource": "arn:aws:route53:::hostedzone/<ホストゾーンID>"}]}'
```

正常に作成できると、以下のような json が返ってきます。

```json
{
    "Policy": {
        "PolicyName": "pol-adcale",
        "PolicyId": "ANPA*****************",
        "Arn": "arn:aws:iam::************:policy/pol-adcale",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2021-12-14T15:33:00+00:00",
        "UpdateDate": "2021-12-14T15:33:00+00:00"
    }
}
```

この json のうち、Arn の値はこの後必要になるので、確認しておきます。

## IAM Role を作成する
ポリシーを作成できたら、次は IAM Role を作っていきます。
iam create-role コマンドを実行します。

```sh
aws iam create-role --role-name role-adcale --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "ec2.amazonaws.com"},"Action": "sts:AssumeRole"}]}'
```

正常に作成できると、以下のような json が返ってきます。

```json
{
    "Role": {
        "Path": "/",
        "RoleName": "role-adcale",
        "RoleId": "AROA*****************",
        "Arn": "arn:aws:iam::************:role/role-adcale",
        "CreateDate": "2021-12-14T15:45:07+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
```

Role をつくっただけでは、箱を用意しただけなので、 iam attach-role-policy コマンドを使ってポリシーを割り当てます。

```sh
aws iam attach-role-policy --role-name role-adcale --policy-arn <ポリシーのARN>
```

正常に終了した場合、特に出力されません。

## インスタンスプロファイルを作成する
EC2 に IAM Role を割り当てる場合、インスタンスプロファイルというものが必要になります。
というわけで、インスタンスプロファイルを作っていきます。 iam create-instance-profile コマンドを実行します。
コマンドで指定するインスタンスプロファイル名は、使用するIAM ロール名と同じにしておくと GUI で作成した場合と同様に管理できるので良いと思います。

```sh
aws iam create-instance-profile --instance-profile-name role-adcale
```

正常に作成できると、以下のような json が返ってきます。

```json
{
    "InstanceProfile": {
        "Path": "/",
        "InstanceProfileName": "role-adcale",
        "InstanceProfileId": "AIPA*****************",
        "Arn": "arn:aws:iam::************:instance-profile/role-adcale",
        "CreateDate": "2021-12-14T16:42:38+00:00",
        "Roles": []
    }
}
```

そして、IAM ロールとインスタンスプロファイルを iam add-role-to-instance-profile コマンドで紐づけます。

```sh
aws iam add-role-to-instance-profile --instance-profile-name role-adcale --role-name role-adcale
```

正常に終了した場合、特に出力されません。
これで IAM ロールを EC2 インスタンスで利用可能な状態にできました。

# まとめ
前回、EC2 を立ち上げて Web サーバとして使う方法をお伝えする旨記載していました。
当初は IAM Role を使わない予定でしたが、構成や設定を再考したところ、必要である旨がわかりました。
そのため、今回、このように IAM ポリシーの作成から IAM Role の作成、インスタンスプロファイルの作成といった一連の内容をお伝えしました。

* 今回使ったコマンド
 * iam create-policy
 * iam create-role
 * iam attach-role-policy
 * iam create-instance-profile
 * iam add-role-to-instance-profile