【IAMロール】なぜCloud9は他のAWSサービスにアクセスできるのか？

#疑問に思ったこと
Organizationsの管理アカウントのCloud9から、CLIでメンバーアカウントの作成を試みました。
やりたかったメンバーアカウントの作成は無事完了したのですが、その時こんな疑問がわいてきました。

「なぜ、Cloud9はメンバーアカウントを作成できるの？」

コンソールを操作していたIAMユーザーはadmin権限を持つものでした。
が、Cloud9から何らかのリソース作成を試みる場合、肝心なのはIAMユーザーの権限ではなくCloud9の権限だと思います。
理屈を理解したいと思い、ちょっと調べてみました。

#確認内容
元々持ってた知識に触れ、そこから実際に確認した内容を見ていきます。
##前提知識
大まかに以下の認識は持っていました。
・IAMユーザーは私達人間がAWSの操作を行うために存在するもの。
　→IAMユーザーには、IAMポリシーをアタッチしたIAMグループに所属させることでアクセス権限を与える。
・IAMロールはAWSサービスなどがAWSの操作を行うために存在するもの。
　→AWSサービスには、IAMポリシーをアタッチしたIAMロールを付与することでアクセス権限を与える。


##「サービスリンクロール」？
↑の理解を持ったうえで、まずはCloud9の実体となるEC2を見てみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/b82988bd-bd36-848d-c65e-1f3b6cf5eee3.png)

「IAMロール」、空欄じゃないの。
この子は何もアクセス権限を持っていないってこと？
それじゃCLIでAWSアカウント作成できた説明がつかないなあ。

調べると、ユーザーガイドに以下の説明がありました。
``AWS Cloud9は、AWS Identity and Access Management（IAM）サービスにリンクされたロールを使用します。サービスリンクロールは、AWSCloud9に直接リンクされているユニークなタイプのIAMロールです。サービスにリンクされたロールはAWSCloud9によって事前定義されており、サービスがユーザーに代わって他のAWSサービスを呼び出すために必要なすべてのアクセス許可が含まれています。(Google翻訳)``

・Cloud9は事前に定義されたサービスリンクロールを使用する
・サービスリンクロールは、他サービスの呼び出しに必要なアクセス許可を含む
なるほど、ロールと一言でいっても色々種類があるんですね。
「サービスリンクロール」、覚えておこう。

参考：Using Service-Linked Roles for AWS Cloud9
https://docs.aws.amazon.com/cloud9/latest/user-guide/using-service-linked-roles.html

実際にコンソールからIAMロールを見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/baeb168f-b8a7-91ae-6736-f1c16d15173f.png)
AWSサービス:cloud9(サービスにリンクされ... と記述があるロールがありました。
これっぽいです。詳細見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/550e4adb-956c-0a71-8a00-e10835f4364f.png)
まずアクセス権限。
「AWSCloud9ServiceRolePolicy」というポリシーがアタッチされてます。
目的を表すシンプルな命名ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/5eeb62a2-f536-da42-d13e-99da553ca2e6.png)
信頼されたエンティティ にcloud9.amazonaws.comとあります。
我々のあずかり知らないところで彼らは信頼関係を築いているようです。
まあおかげで、ロールを意識せずにcloud9で様々な操作をできるとも言えます。

##ポリシーを見てみる
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances",
                "ec2:CreateSecurityGroup",
                "ec2:DescribeVpcs",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus",
                "cloudformation:CreateStack",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStackResources"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:DeleteSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:DeleteStack"
            ],
            "Resource": "arn:aws:cloudformation:*:*:stack/aws-cloud9-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ec2:*:*:security-group/*"
            ],
            "Condition": {
                "StringLike": {
                    "aws:RequestTag/Name": "aws-cloud9-*"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "ec2:ResourceTag/aws:cloudformation:stack-name": "aws-cloud9-*"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListInstanceProfiles",
                "iam:GetInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::*:instance-profile/cloud9/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/service-role/AWSCloud9SSMAccessRole"
            ],
            "Condition": {
                "StringLike": {
                    "iam:PassedToService": "ec2.amazonaws.com"
                }
            }
        }
    ]
}
```
EC2,CloudFormationに関する許可設定が多め？
"Action":"Organizations":~などの記述はない。
なのになぜOrganizationsのCLI使ってメンバーアカウントを作成できたのか？
このあたりがちょっと疑問として残る。

参考：Service-Linked Role Permissions for AWS Cloud9
https://docs.aws.amazon.com/cloud9/latest/user-guide/using-service-linked-roles.html#service-linked-role-permissions

#まとめ
・一部のAWSサービスには「サービスリンクロール」が事前定義されている。
・そのため、そのAWSサービスが基本動作する分には、ユーザー側でロールの付与など考える必要はない。

「IAMロール」という大枠でとらえていましたが、もう少し深く理解していく必要性があると認識しました。
引き続き勉強していきます。

#追加で確認したい・やりたいこと
・「サービスリンクロール」では足りず、追加でロールを付与したいケースはある？
・「ロールの種類」を整理したい。

#参考
AWS services that work with IAM
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
→「サービスリンクロール」が用意された各AWSサービスを確認できる。

AWS Cloud9環境で利用できる一時クレデンシャル『AWS Managed Temporary Credentials』について調べてみた
https://dev.classmethod.jp/articles/aws-cloud9-aws-managed-temporary-credentials/#toc-2
Cloud9からIAM Roleの権限でAWS CLIを実行する
https://dev.classmethod.jp/articles/execute-aws-cli-with-iam-role-on-cloud9/
→ざっと見たものの理解しきれてない。追加の疑問点を解消するポイントはありそう。

What can I do with AWS Cloud9?
https://docs.aws.amazon.com/cloud9/latest/user-guide/what-can-i-do.html
→そもそもCloud9でなにできるん？の話。本記事の内容と直接関係ないけどよく読みたい。