CloudFormationを使ってスイッチロールしてみた

お疲れ様です。最近、パートナー企業に運用業務を委託していくことになりました。
その際にアカウント内のリソースを確認できるようスイッチロールを行うことになりCloudformationを使用することになりました。

今回はその復習もかねてCloudFormationを使って別のアカウントからスイッチロールできるように試してみました。

## 使用するテンプレートの説明

実際に使用したテンプレートとは少し違いますがほとんど同じなのでこちらのテンプレートの参考にして解説していきたいと思います。ちなみに参考にしたのは下記の記事です。（クラメソさんいつもありがとうございます。）

https://dev.classmethod.jp/articles/created_a_cross-account_access_role_in_cloudformation/

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "IAM Role to Switch",
  "Parameters": {
    "TrustedAWSAccountId": {
      "AllowedPattern": "^[0-9]{12}$",
      "Type": "String",
      "Default": "xxxx-xxxx-xxxx",
      "Description": "Trusted AWS Account ID"
    },
    "IAMUserName": {
      "AllowedPattern": "^[a-zA-Z0-9._-]*$",
      "Type": "String",
      "Default": "TrainingUser",
      "Description": "IAM Role Name"
    }
  },
  "Resources": {
    "IAMRoleForCmEngineerRead": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": { "Fn::Join": ["", ["arn:aws:iam::", { "Ref": "TrustedAWSAccountId" }, ":user/", { "Ref": "IAMUserName" }]] }
              },
              "Action": ["sts:AssumeRole"],
              "Condition": {
                "Bool": {
                  "aws:MultiFactorAuthPresent": "true"
                }
              }
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/ReadOnlyAccess"
        ],
        "Path": "/",
        "RoleName": { "Ref": "IAMUserName" }
      }
    }
  },
  "Outputs": {
    "IAMRoleArn": {
      "Value": { "Fn::GetAtt": ["IAMRoleForCmEngineerRead", "Arn"] }
    },
    "LinkForSwitchRole": {
      "Value": { "Fn::Join": ["", ["https://signin.aws.amazon.com/switchrole?roleName=", { "Ref": "IAMUserName" }, "&account=", { "Ref": "AWS::AccountId" }]] }
    }
  }
}
```

ザックリとセクションはこんな感じです。

|セクション|役割|
|:--------------|:--------------|
|Parameters   |ユーザー名・AWSアカウントIDの入力を受け付ける定義|
|Resources|ロールを作成し、指定ユーザーがAssumeRoleできるようにリソースを定義|
|Outputs|作成したロールのARNと、スイッチロール用URLを出力させる|

さて、細かく見ていきたいと思います。

## "Description": "IAM Role to Switch"の解説
まずは信頼できるAWSアカウントを定義します。
### "TrustedAWSAccountId"
  "Description" : "IAM Role to Switch"：テンプレートの説明（IAMロールをスイッチするための設定）であること
"Parameters":どんな値を実行するかを定義します。
"TrustedAWSAccountId" : どのAWSアカウントのIAMユーザーがこのロールをAssumeRole（スイッチ）できるかを指定。
"AllowedPattern" : "^[0-9.]*$"：数字のみ（AWSアカウントIDの形式）を許可。
"Type": "String"：Parameters セクション で定義されたパラメータのデータ型を指定します。"String" は文字列を表します。"Number"や"AWS::EC2::VPC::Id"などがあります。
"Default" :パラメータが入力されなかったときのデフォルト値が入ります。今回の場合はスイッチ元となるアカウントIDが入ります。
### "IAMUserName"
"AllowedPattern" :[a-z0-9.]でユーザー名で大文字小文字・数字・ドット（.）・ハイフン（-）・アンダースコア（_）を許可 する。
"Default" :パラメータが入力されなかったときのデフォルト値が入ります。今回の場合はスイッチ元となるユーザーIDが入ります。

## "Resources" の解説
このテンプレートで作成するAWSリソースを定義します。
"IAMRoleForCmEngineerRead"："Type": "AWS::IAM::Role"でIAMロールを作成します。
"Properties":どのユーザーがこのロールをAssumeできるかを設定しています。
"Principal"（実行できるユーザー）：TrustedAWSAccountId（パラメータで指定したAWSアカウント）の IAMUserName（IAMユーザー）がAssumeRoleできます。
"Action":なんのアクションを行うのか？sts:AssumeRole → 指定されたユーザーがこのロールにスイッチ可能にすることを示しています。
"Condition":特定のアクションが実行される条件を指定するために使われます。
"Bool"： Boolean（ブール型） を意味し、true または false の2つの値しか取らないデ ータの型のことをいいます。今回はMFA（多要素認証）が有効な場合のみ sts:AssumeRole を許可します。

## "ManagedPolicyArns"の解説
IAMポリシーの適用を行います。
ReadOnlyAccessポリシーの付与をしています。

## "Path"の解説
IAMロールのパス（/ はデフォルトパス）。IAMリソース（ユーザー、ロール、グループ）は パスを使って階層化 できます。組織ごとにIAMロールを整理したいときやアクセス制御を強化したいときに使われるそうです。
例）Path: "/engineering/" → /engineering/ に所属するIAMロール
Path: "/finance/" → /finance/ に所属するIAMロール

作成されるIAMロールの名前を、IAMUserName パラメータの値に設定しています。
Refは、他のパラメータやリソースの値を参照する関数 です。

## "Outputs"の解説
作成したロールのARNと、スイッチロール用URLを出力します。
"IAMRoleArn": 作成されたIAMロールのARNを出力しています。
"LinkForSwitchRole"：AWSのスイッチロール画面へのURLを作成し対象のIAMユーザーがこのURLをクリックすると、指定されたロールにスイッチできるようにしています。

それではテンプレートを投入していきます。
## Cloudformationでテンプレを投入する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/1ef37967-425c-481c-888b-a69a80b159cc.png)

検索窓口から[Cloudformation]-[スタック]-[スタックの作成]
[既存のテンプレートを選択]-[テンプレートファイルのアップロード]-[ファイルの選択]
先ほどのテンプレートを記載したYAMLファイルを選択して次へ行きましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/945a18ce-6a1e-42d3-ac83-cd01f4556219.png)


スタック名は適切な名前を入れます。
パラメータでは先ほどのテンプレートで定義した項目の"TrustedAWSAccountId" と"IAMUserName"が反映されています。
次へ進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/70252f83-b1b8-4165-85d3-7ce779221fa7.png)

スタックのオプションはデフォルトのままでかまいません。下に下がります。
[AWS CloudFormationによってIAMリソースがカスタム名で作成される場合があることを承認します]にチェックを入れて次へ進みます。

確認をして作成をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/530dc7ea-852a-435e-bae5-289d27b7b90e.png)

CREATE_IN_PROGRESSからCREATE_IN_PROGRESSまで確認できればOKです。
スイッチロール用のIAMロールが作成されているか確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/e1a15a4b-5730-4a3a-9952-a3f0967b85d4.png)

ロール名、TrainingUserで作成されています。
ここまでスイッチ先アカウントでの確認ができたのでスイッチ元のアカウントに切り替えてスイッチロールができるか確認します。
スイッチ元のアカウントで対象のIAMユーザーでログインします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/6e5a8d6a-ec65-4276-a769-ca4bc2322d9f.png)

右上のアカウント情報をクリックすると[ロールの切り替え]が表示されているのでクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/ed699837-5e4c-40b7-b7dd-cd6b6a88755e.png)



アカウントIDは12桁のIDを入れます。
IAM role名は先ほどスイッチ先に登録されたIAMロール名を入れます。
DisplayNameはお好みでいれます。
Displaycolorもお好みで。
switch roleをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/4203b8d3-b1bf-4b37-b7a3-9b983060b784.png)

switchleが成功していることが確認できました。

## 参考にしたドキュメント
https://dev.classmethod.jp/articles/create-roles-with-cf/

https://dev.classmethod.jp/articles/created_a_cross-account_access_role_in_cloudformation/

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

## 他にもこんな記事書いています！

https://qiita.com/mmurm/items/0e35a80d6bb0ba7d866b

https://qiita.com/mmurm/items/8e816d8223f370d45f03

https://qiita.com/mmurm/items/fda3fefa4d97e578aee2