一時的に強い権限をIAMポリシーに簡単に付与できるCloudFormationのサンプル

# はじめに
AWSのIAMユーザに対して、時々、一時的に強い権限を与える必要があり、CloudFormationを用いてその操作を簡単にできるようにした内容を記事にしました。

# 概要
- 期間限定で(管理者ユーザにアタッチしている)IAMポリシーに権限を与えます。
    - その操作を、CloudFormationのスタックの更新で行います。
        - パラメータの変更だけで実現でき、操作ミス等が生じにくい運用にできます。

# 利用シーン
AWSのBIサービスであるQuickSightは、S3やRedshiftなど、外部のデータを取得して可視化できます。
QuickSightから外部のサービスにアクセスする際は、専用のIAMロールがQuickSightにアタッチされます。
一方QuickSightの管理者は、QuickSightの操作を行うだけであれば、外部のリソースに対する許可は不要です。

ですが、別サービスとの連携を追加するなどQuickSightの設定変更を行う際、変更するユーザ（ここでは管理者）に「対象のサービスを閲覧できる権限」や「QuickSightのIAMロールを変更できる権限」などの権限が必要な模様でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/dc6bb8e4-b019-b7af-2b1e-2b6d4ce82eeb.png)

そのため、「普段はQuickSightの権限だけもつユーザ。設定変更の際に一時的に強い権限を有効にする、なるべく簡単な操作で」という運用の際に使います。

# CloudFormation
以下が作ったCloudFormationのコードです。英語の拙さはご容赦ください。

```
AWSTemplateFormatVersion: 2010-09-09
Description: Create QuickSight Admin
Parameters: 
  userId:
    Description: QuickSight administrator user ID.
    Type: String
    Default: quicksightadmin
  password:
    Description: QuickSight administrator default password.
    Type: String
    NoEcho: true
  datelessthan:
    Description: the expiration date of the IMPORTANT ACTION.
    Type: String
    Default: 2020-08-31T19:00:00+09:00
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: User Login Information.
        Parameters:
          - userId
          - password
          - datelessthan
          
Resources: 
  # QuickSight用の管理者IAMユーザー
  QuickSightIAMUser:
      Type: "AWS::IAM::User"
      Properties:
          Path: "/"
          UserName: !Ref userId
          LoginProfile:
            Password: !Ref password
            PasswordResetRequired: true
          ManagedPolicyArns: 
            - !Ref QuickSightIAMManagedPolicy
          Tags:
            - Key: "phase"
              Value: "operation"
  QuickSightIAMManagedPolicy:
      Type: "AWS::IAM::ManagedPolicy"
      Properties:
          ManagedPolicyName: "quicksight-admin"
          Path: "/"
          PolicyDocument:
            Version: "2012-10-17"
            Statement: 
              - Effect: "Allow"
                Action:
                  - "ds:AuthorizeApplication"
                  - "ds:UnauthorizeApplication"
                  - "ds:CheckAlias"
                  - "ds:CreateAlias"
                  - "ds:DescribeDirectories"
                  - "ds:DescribeTrusts"
                  - "ds:DeleteDirectory"
                  - "ds:CreateIdentityPoolDirectory"
                  - "iam:ListAccountAliases"
                  - "quicksight:CreateAdmin"
                  - "quicksight:Subscribe"
                  - "quicksight:Unsubscribe"
                  - "quicksight:GetGroupMapping"
                  - "quicksight:SearchDirectoryGroups"
                  - "quicksight:SetGroupMapping"
                Resource: "*"
              # 以下、初期設定のために一時的に強い権限を与える
              - Effect: "Allow"
                Action:
                  - "s3:*"
                  - "glue:*"
                  - "athena:*"
                  - "iam:*"
                Resource: "*"
                Condition:
                  DateLessThan:
                    aws:CurrentTime: !Ref datelessthan
```

- ポリシー"quicksight-admin"の1つ目は、QuickSightの管理者に必要な権限になります。
    - 必要十分な設定のつもりです。わかる方いらっしゃいましたらご指摘ください。
- ポリシー"quicksight-admin"の2つ目が一時的に付与する強い権限です。
    - どれくらい強い権限を与えればいいかわからなかったので、かなり大雑把です、スミマセン。
    - ここではS3とGlueとAthenaですが、他に必要な権限ありましたら適宜追加します。
    - `Condition`にて、現在時刻よりもパラメータの入力時刻が未来であれば有効、という内容になります。

# 使い方
## 作成時
1. このCloudFormationで、管理者を作成。
    1. その際、パラメータ`datelessthan`には、QuickSightの設定を終わらせられそうな時刻を入力。
1. QuickSightを、作ったユーザで有効化。
1. リソース参照など、各種設定を行う。

パラメータ`datelessthan`の時刻が過ぎると、自動的に強い権限が無効化されます。

## 設定ON時
1. 管理者を作成したCloudFormationのスタックを更新。
    1. 現在のテンプレートを使用　を選ぶ。
1. パラメータ`datelessthan`に、変更したい設定を終わらせられそうな時刻を入力し更新。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/0c22206e-ac1b-0703-17a7-d228ac82b918.png)

作成時と同様にパラメータ`datelessthan`の時刻が過ぎると、自動的に強い権限が無効化されます。
これで直接IAMポリシーを修正することなく、入力するだけで一時的に強い権限を付与することができました。

# おわりに
一時的に強い権限を付与する方法を、CloudFormationを使うことで簡単に出来ることを紹介しました。
今回はQuickSightでしたが、他にも使う機会ありましたら参考にしてください。