[AWS][CFn]IAMの設定

## はじめに

こんにちは。なじむです。
引き続き、クラスメソッドさんのブログ記事、[AWSアカウントを作ったら最初にやるべきこと ～令和元年版～](https://dev.classmethod.jp/cloud/aws/aws-1st-step-new-era-reiwa/)を参考にさせていただき、AWSでの初期設定をCloudFormationで実施していきます。
今回は「IAMの設定」をCloudFormationで実施していきます。IAMはAWSを使用する上で一番重要と言っても過言ではないと思います。その設定が少しでも楽になれば。

## 前提

今回は特定のIPからのアクセスのみを有効にします。ただし、特定のIPからのアクセスのみに制限してしまうと、AWS内部の通信（例えばEBSの暗号化）も制限してしまうことになるため以下の条件で設定します。

- コンソールにログインした後、スイッチロールを行い任意のロールにスイッチする
- 上述のスイッチロールは特定のIPからしか実行できないよう制限する
- スイッチロールした後はIPアドレスの制限を設けず、任意の操作を実行可能とする

今回は例としてAdministartorAccessのIAMポリシーを使用して、すべての権限を持つグループを作成します。
サンプルコードで実施しているのは以下です。

- IAMグループ（Administrator）を作成する
- IAMポリシー（OnlyMyIPAccess, AssumeAdministrator）を作成する
- IAMロール（Administrator）を作成する

## サンプルコード
```yaml
---
AWSTemplateFormatVersion: 2010-09-09
Description: IAM - Group, Role, Policy for Administrator

#------------------------------
# Resources: Your resource list
#------------------------------
Resources:
  # IAM(Group) Resource
  ## Administrator
  GroupAdministrator:
    Type: AWS::IAM::Group
    Properties:
      GroupName: Administrator
      ManagedPolicyArns: 
      - !Ref AssumeAdministrator
      - !Ref OnlyMyIPAccess

  # IAM(Policy) Resource
  ## Group's Policy -- MyIPAccess
  OnlyMyIPAccess:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Deny
          Action: "*"
          Resource: "*"
          Condition:
            NotIpAddress:
              aws:SourceIp:
              - xxx.xxx.xxx.xxx/32 # ここは任意のIPアドレスに修正してください。

  ## Group's Policy -- Administrator
  AssumeAdministrator:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Action: sts:AssumeRole
          Resource: !GetAtt RoleAdministrator.Arn

  # IAM(Role) Resource
  ## Administrator
  RoleAdministrator:
    Type: AWS::IAM::Role
    Properties:
      RoleName: Administrator
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Action: sts:AssumeRole
          Principal:
            AWS: !Sub ${AWS::AccountId}
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/AdministratorAccess
      Path: "/"
```

## 実行結果

では、いつも通り作成したリソースを見ていきます。

- IAMグループ（Administrator）を作成する

- IAMポリシー（OnlyMyIPAccess, AssumeAdministrator）を作成する
![20191215_212819.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396510/7cc35e65-6161-ebe7-bbf2-40ec15682642.jpeg)

- IAMロール（Administrator）を作成する
![20191215_212847.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396510/de5f1f81-30db-8fbd-3562-41fa09bdf057.jpeg)

今回は作成したリソースではなく、動作を見ていきましょう。

- MyIPからログインした直後 ※describeInstancesの権限がないことが分かります。
![20191215_212443.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396510/f0887bf3-7e13-dad6-eece-9a2b560b3643.jpeg)

- スイッチロール後 ※describeInstancesの権限が付与されていることが分かります（EC2を作成していないので何も表示されません…笑）
![20191215_212530.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396510/3bba1db8-f5dd-b69f-93c9-e41c90ab4c7e.jpeg)

## まとめ

今回は自社のオフィス以外からはアクセスさせたくないという場面を想定して特定のIPからのみにログインを絞る方法でIAMを構築してみました。ただ、この方法だと1度スイッチロールした後、その状態を保持したままIPが変わってもログインは保持されるため操作が可能となります（そんな場面はまれだと思いますが）。その場合、IAMロールの認証が切れる1時間後か、ユーザがログアウトするのを待つしかないかなと思います。
IAMの構成については、個人的にはネストスタックを使用すると少し構造が分かりやすくなるかなと思うので、次回はIAMの設定をネストスタックでやってみるをお送りしようと思いますノシ