11
3

More than 1 year has passed since last update.

はじめてのAWS CloudFormation -IAMユーザー作成編-

Last updated at Posted at 2021-11-30

はじめに

前回の記事:はじめてのAWS CloudFormation -S3バケット作成編-
前回に引き続きCloudFormationを学ぼうという試みと取り組んだ内容の記録です。
今回はCloudFormationでIAMユーザー、グループ、ポリシーを作成してみます。

IAMユーザーのパラメータ設計

作成するIAMユーザーを考えます。
社内でアカウントを払い出す時にありがちなユーザーと権限を想定して以下のようにしました。

  • 方針

    • IAMポリシーは権限管理を容易にするため、原則IAMグループに対してポリシーをアタッチする(個々のユーザーに対して直接ポリシーをアタッチしない)。
    • 運用ユーザー相当のOpeUserはec2インスタンスの起動・停止のみ操作可能とし、その他のサービスについては読み取りのみ可能とする。
    • 各IAMユーザーのパスワードは、共通のものをデプロイ時にパラメーターとして指定。初回ログイン時に変更させる。
  • IAMグループ

IAMグループ名 マネージドポリシー カスタムポリシー
CFn-test-AdminGroup AdministratorAccess -
CFn-test-PowerUserGroup PowerUserAccess -
CFn-test-OpeGroup ReadOnlyAccess CFn-test-ec2-OpePolicy
  • IAMユーザー
IAMユーザー名 所属グループ
CFn-test-AdminUser CFn-test-AdminGroup
CFn-test-PowerUser CFn-test-PowerUserGroup
CFn-test-OpeUser CFn-test-OpeGroup
  • カスタムポリシー:CFn-test-ec2-OpePolicy
CFn-test-ec2-OpePolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ActionInstances",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

テンプレート用パラメータの確認

公式ドキュメントから各リソースで指定可能なPropertiesを確認します。

IAMグループ

AWS公式ドキュメント - AWS::IAM::Group

IAMGroupProperties
Type: AWS::IAM::Group
Properties: 
#グループ名を指定
  GroupName: String
#付与するマネージドポリシーのARNを指定
  ManagedPolicyArns: 
    - String
#パスを指定
  Path: String
#インラインポリシーを記載
  Policies: 
    - Policy

IAMユーザー

AWS公式ドキュメント - AWS::IAM::User

IAMUserProperties
Type: AWS::IAM::User
Properties: 
#所属グループ名を指定
  Groups: 
    - String
#パスワードに関する設定を指定
  LoginProfile: 
    LoginProfile
#付与するマネージドポリシーのARNを指定
  ManagedPolicyArns: 
    - String
#パスを指定
  Path: String
#PermissionsBoundaryを指定
  PermissionsBoundary: String
#インラインポリシーを記載
  Policies: 
    - Policy
#タグを指定
  Tags: 
    - Tag
#ユーザー名を指定
  UserName: String

IAMポリシー

AWS公式ドキュメント - AWS::IAM::ManagedPolicy
IAMポリシー作成時に指定するリソースタイプとしては、「AWS::IAM::ManagedPolicy」と「AWS::IAM::Policy」が存在します。
紛らわしいのですがカスタムポリシー(カスタマー管理ポリシー)を作成する場合は「AWS::IAM::ManagedPolicy」を指定します。
「AWS::IAM::Policy」で作成するとインラインポリシーの作成になってしまいます。

IAMPolicyProperties
Type: AWS::IAM::ManagedPolicy
Properties: 
#説明を記載
  Description: String
#アタッチするIAMグループを指定
  Groups: 
    - String
#ポリシー名を指定
  ManagedPolicyName: String
#パスを指定
  Path: String
#ポリシーの内容を記載
  PolicyDocument: Json
#アタッチするIAMロールを指定
  Roles: 
    - String
#アタッチするIAMユーザーを指定
  Users: 
    - String

Propertiesを記載

リソースごとにPropertiesを記載します。以下のようになりました。

IAMグループ

IAMGroup
#"CFn-test-AdminGroup"
  AdminUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref AdminUserGroupName
      #マネージドポリシーのアタッチ
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
#"CFn-test-PowerGroup"
  PowerUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref PowerUserGroupName
      #マネージドポリシーのアタッチ
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/PowerUserAccess
#"CFn-test-OpeGroup"
  OpeUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref OpeUserGroupName
      #マネージドポリシーのアタッチ
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        #AWS :: IAM :: ManagedPolicyリソースは戻り値としてARNを返すため、!RefでARNを取得
        - !Ref OpePolicy

IAMユーザー

IAMUser
#CFn-test-AdminUser
  AdminUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref AdminUserName
      Groups:
        - !Ref AdminUserGroupName
      #初期パスワードとリセット設定
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true
#CFn-test-PowerUser
  PowerUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref PowerUserName
      Groups:
        - !Ref PowerUserGroupName
      #初期パスワードとリセット設定
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true
#CFn-test-OpeUser
  OpeUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref OpeUserName
      Groups:
        - !Ref OpeUserGroupName
      #初期パスワードとリセット設定
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true

IAMポリシー

IAMPolicyProperties
  OpePolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: "CFn-test-ec2-OpePolicy"
      PolicyDocument:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "ActionInstances",
              "Effect": "Allow",
              "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
              ],
              "Resource": "*"
            }
          ]
        }

完成したCloudFormationテンプレート

CreateIAMUsers
AWSTemplateFormatVersion: 2010-09-09
Description: Create IAM Users

Parameters:
  AdminUserGroupName:
    Type: String
    Default: CFn-test-AdminGroup
    Description: AdminUserGroupName
  PowerUserGroupName:
    Type: String
    Default: CFn-test-PowerUserGroup
    Description: PowerUserGroupName
  OpeUserGroupName:
    Type: String
    Default: CFn-test-OpeGroup
    Description: OperationUserGroupName
  AdminUserName:
    Type: String
    Default: CFn-test-AdminUser
    Description: AdminUserName
  PowerUserName:
    Type: String
    Default: CFn-test-PowerUser
    Description: PowerUserName
  OpeUserName:
    Type: String
    Default: CFn-test-OpeUser
    Description: OpeUserName
  Passwd:
    Type: String
    Description: Password
    NoEcho: True

Resources:
  AdminUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref AdminUserGroupName
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
  PowerUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref PowerUserGroupName
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/PowerUserAccess
  OpeUserGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Ref OpeUserGroupName
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - !Ref OpePolicy

  AdminUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref AdminUserName
      Groups:
        - !Ref AdminUserGroupName
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true
  PowerUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref PowerUserName
      Groups:
        - !Ref PowerUserGroupName
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true
  OpeUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Ref OpeUserName
      Groups:
        - !Ref OpeUserGroupName
      LoginProfile:
        Password: !Ref Passwd
        PasswordResetRequired: true

  OpePolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: "CFn-test-ec2-OpePolicy"
      PolicyDocument:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "ActionInstances",
              "Effect": "Allow",
              "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
              ],
              "Resource": "*"
            }
          ]
        }

Outputs:
  UserName:
    Description: UserName
    Value: !Join [",", [!Ref AdminUserName, !Ref PowerUserName, !Ref OpeUserName]]
  LoginURL:
    Description: LoginURL
    Value: !Join ["", ["https://", !Ref AWS::AccountId, ".signin.aws.amazon.com/console"]]

実行後の確認

IAMユーザー
CFn-IAM_User.JPG

IAMグループ
CFn-IAM_Group.JPG

CFn-test-OpeGroupに付与されたポリシー
CFn-IAM_GroupPolicy.JPG

考慮した点や途中発生したエラーについて

Parametersセクション

グループ/ユーザー名は固定値でも良かったのですが、Parametersセクションでデプロイ時に指定可能にしています。
Default:の値として「IAMユーザーのパラメータ設計」で決めた値を記載しているため、最初から入力された状態になっています。
CFn-IAM_1.JPG

Outputsセクション

Outputsセクションで、作成されたIAMユーザー名の表示とログインURLの生成を行いデプロイ完了後に「出力」タブで確認できるようにしています。
機能的にはなくても良いのですが、前回のS3バケット作成で使うことがなかったOutputsセクションを使ってみたかっただけです。
CFn-IAM_2.JPG

NoEcho属性

Parametersセクションのパスワードを指定するPasswd:について、NoEcho: Trueを指定しています。
最初はNoEcho属性を記載していなかったのですがVSCode上で[cfn-lint]: Parameter Passwd used as Password, therefore NoEcho should be True
という警告が表示されていました。
NoEcho属性を記載しない場合、以下のように「パラメータ」タブに指定した値がマスクされずに表示さるため、NoEcho: Trueを記載した方が良い旨の警告でした。

CFn-IAM_4.JPG

NoEcho属性を記載した場合以下のようになります。

CFn-IAM_5.JPG

CloudFormationに対して読み取り権限があればパラメータとして渡したパスワード情報を見ることができてしまうので、
ログインパスワード等の重要情報をパラメータとして渡す場合はNoEcho: Trueを指定してマスクした方が安全性が高まります。

参考:AWS公式ドキュメント - パラメータ

おわりに

CloudFormationを使ってIAMユーザー、グループ、ポリシーを作成してみました。
今回は自分のAWSアカウント内で完結していますが、
AWS Organizationsを利用している場合、Organizations管理アカウントからCloudFormationのStackSetsを利用することで、
OU単位で簡単に複数のAWSアカウントに対して同じリソースをデプロイすることもできるようです。
(Organizations環境でなくても、StackSetsを利用することで別アカウントに対してのClodFormation実行は可能)
会社で検証やプロジェクトごとのアカウント払い出し時に、標準化されたIAMユーザーや権限のセットがあればテンプレート化することで払い出しにかかる時間を短縮できそうですね。

11
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
3