AWS CloudFormationを利用したIAMユーザ作成

2019.12.08

「初期 IAM ユーザを複数アカウントにミスなく作成したい!!」

という要望があったので、AWS CloudFormation のテンプレートを作成しました。今回は作成したテンプレートを紹介します。想定読者は AWS CloudFormation 入門者レベルの方です。それでは早速やっていくっ!

AWS CloudFormantionとは?

BlackBelt で基本をおさらい。AWS CloudFormantion (以降、CFn) の概要は、以下のスライドが分かりやすいと思います。

AWS Black Belt Online Seminar 2016 AWS CloudFormation

作成する CFn テンプレートについて

要件

Admin 権限を持つ初期 IAM ユーザ

  • グループ名:demo-admin-group-{アカウントID}
  • ユーザー名:demo-iniadmin-user-{アカウントID}
  • グループにAdminポリシーアタッチ
  • パスワードの設定自体は別の自動化ツールを利用する想定
  • 別の自動化ツールの為に、ログインURLとパスワード設定画面のURLとユーザ名をOutputに出す
  • オプション:対象スタックを削除してもリソースを保持する

期待される効果

  • 人為的なミス (グループポリシーの付け忘れ等) の防止
  • 作業スピードアップ

CFn テンプレート

JSON で書いてみました。

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Template for creating Initial IAM",
    "Resources": {
        "IAMGrouopInitialAdmin": {
            "Type": "AWS::IAM::Group",
            "DeletionPolicy": "Retain",
            "Properties":{
                "GroupName":{"Fn::Join" : [
                        "",
                        ["demo-admin-group-", {"Ref": "AWS::AccountId"}]
                    ]},
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/AdministratorAccess"
                ]
            }
        },
        "IAMUserInitialAdmin": {
            "Type": "AWS::IAM::User",
            "DeletionPolicy": "Retain",
            "Properties":{
                "UserName": {"Fn::Join" : [
                    "",
                    ["demo-iniadmin-user-",{"Ref": "AWS::AccountId"}]
                    ]},
                "Groups":[{"Fn::Join" : [
                    "",
                    ["demo-admin-group-",{"Ref": "AWS::AccountId"}]
                    ]}
                ]
            }
        }
    },
    "Outputs": {
        "UserName": {
            "Description": "Information about User name",
            "Value": { "Ref" : "IAMUserInitialAdmin" }
        },
        "PasswordSettingURL": {
            "Description": "Please create a password at the URL",
            "Value": {"Fn::Join": [
                "",
                ["https://","console.aws.amazon.com/iam/home?region=",{ "Ref": "AWS::Region" },"#/users/", {"Ref": "IAMUserInitialAdmin"},"?section=security_credentials"]
                ]}
        },
        "LoginURL": {
            "Description": "Information about console login URL",
            "Value": {"Fn::Join" : [
                "",
                ["https://",{"Ref": "AWS::AccountId"},".signin.aws.amazon.com/console"]
                ]}
        }
    }
}

YAML 形式で見たい方は、CloudFormation デザイナーで変換してみてください。詳しくは、 YAMLに対応したAWS CloudFormation デザイナーを試してみた を見てください。

CFn テンプレートの各セクションの説明

今回は以下のテンプレートセクションを利用します。上から順番に説明します。

  • AWSTemplateFormatVersion
  • Description
  • Resources
  • Outputs

AWSTemplateFormatVersion

形式バージョン

AWSTemplateFormatVersion セクション (任意) は、テンプレートの機能を識別します。最新のテンプレートの形式バージョンは 2010-09-09 であり、現時点で唯一の有効な値です。

ブログ記載時点では上記の通りなので、以下のように記載しています。

"AWSTemplateFormatVersion": "2010-09-09",

Description

説明

作成するテンプレートの説明を書きます。"初期設定用の IAM ユーザの作成"ということで以下のように追記します。

"Description": "Template for creating Initial IAM",

Resources

リソース

作成するリソースの記述をします。今回の要件で必要なリソースは IAM グループと IAM ユーザです。構文単位で説明します。

"Resources": {
        "IAMGrouopInitialAdmin": {
            "Type": "AWS::IAM::Group",
            "DeletionPolicy": "Retain",
            "Properties":{
                "GroupName":{"Fn::Join" : [
                        "",
                        ["demo-admin-group-", {"Ref": "AWS::AccountId"}]
                    ]},
                "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/AdministratorAccess"
                ]
            }
        },
        "IAMUserInitialAdmin": {
            "Type": "AWS::IAM::User",
            "DeletionPolicy": "Retain",
            "Properties":{
                "UserName": {"Fn::Join" : [
                    "",
                    ["demo-iniadmin-user-",{"Ref": "AWS::AccountId"}]
                    ]},
                "Groups":[{"Fn::Join" : [
                    "",
                    ["demo-admin-group-",{"Ref": "AWS::AccountId"}]
                    ]}
                ]
            }
        }
    },
- Logical ID

論理 ID は英数字(A-Za-z0-9)とし、テンプレート内で一意である必要があります。論理名は、テンプレートの他の部分のリソースを参照するために使用します。

初期管理者用 IAM グループと初期管理者用 IAM ユーザを作成するので、それぞれ以下のような論理名にします。

  • "IAMGrouopInitialAdmin"
  • "IAMUserInitialAdmin"
- Type

リソースタイプは、宣言しているリソースのタイプを識別します。たとえば、AWS::EC2::Instance は EC2 インスタンスを宣言します。

IAM リソースタイプのリファレンス

新しいグループとユーザを作成したいので、上記リファレンスの内、以下のリソースタイプを選択します。

  • "AWS::IAM::Group"
  • "AWS::IAM::User"
- Properties

IAM グループの箇所は、 AWS::IAM::Group を参考にして書きます。GroupName のプロパティで作成するグループ名の指定をして、ManagedPolicyArns のプロパティでアタッチする IAM ポリシーの ARN を指定します。

  • GroupName のプロパティでは、 Fn::Join を用いて、文字列と Ref で指定した AWS アカウント ID を連結して、demo-admin-group-{アカウントID} という要件のグループ名を指定しています。
  • ManagedPolicyArnsのプロパティでアタッチするIAMポリシーは、IAMポリシーにデフォルトで存在する、AdministratorAccess の ARN を指定しています。

//画像追加

IAM ユーザの箇所は、 AWS::IAM::User を参考にして書きます。UserNameのプロパティで作成するユーザ名の指定をして、Groups のプロパティでユーザを追加する IAM グループを指定します。

  • UserName のプロパティでは、前述の組み込み関数 (Fn::Join と Ref) を用いて、demo-iniadmin-user-{アカウントID} という要件のユーザ名を指定しています。
  • Groups のプロパティでも、組み込み関数 (Fn::Join と Ref) を用いて、 IAM グループで指定したグループ名を指定しています。
- DeletionPolicy

冒頭の構文には載っていないですが、要件の「オプション:対象スタックを削除してもリソースを保持する」を満たすために、 DeletionPolicy 属性 を用います。DeletionPolicy のオプションは、Retain を指定することで、当該要件を実現します。


Outputs

出力

出力内容の記述をします。今回の要件で必要な出力は、ユーザ名とパスワード設定画面の URL とログイン URL です。構文単位で説明します。

"Outputs": {
        "UserName": {
            "Description": "Information about User name",
            "Value": { "Ref" : "IAMUserInitialAdmin" }
        },
        "PasswordSettingURL": {
            "Description": "Please create a password at the URL",
            "Value": {"Fn::Join": [
                "",
                ["https://","console.aws.amazon.com/iam/home?region=",{ "Ref": "AWS::Region" },"#/users/", {"Ref": "IAMUserInitialAdmin"},"?section=security_credentials"]
                ]}
        },
        "LoginURL": {
            "Description": "Information about console login URL",
            "Value": {"Fn::Join" : [
                "",
                ["https://",{"Ref": "AWS::AccountId"},".signin.aws.amazon.com/console"]
                ]}
        }
    }
- Logical ID

各出力ごとに以下の論理名を与えています。

  • ユーザ名:UserName
  • パスワード設定画面のURL:PasswordSettingURL
  • ログインURL:LoginURL
- Description

冗長なので紹介しません。

- Value

組み込み関数 (Fn::Join や Ref) を用いて、出力値を指定しています。

  • "UserName"の出力値には、Resources セクションで作成する IAM ユーザの Logical ID を指定
  • "PasswordSettingURL"の出力値には、IAM ユーザの画面の認証情報タブを選択時のURLを参照します。可変要素は、リージョンとユーザ名なので、こちらを不変の文字列と連結させています。リージョンは擬似パラメータで参照可能です。
  • "LoginURL"の出力値には、マネジメントコンソールのログインURLを参照します。可変要素は AWSアカウントID なので、こちらを不変の文字列と連結させています。

CFn テンプレートでスタック作成

AWS CloudFormation コンソールでのスタックの作成 を参考にして 作成した CFn テンプレートでスタック作成を進めます。

スタックの名前は、仮で demo とします。それ以外は全てデフォルトでOKです。「スタック作成」を押下する前に、チェックをつけ忘れないようにしましょう。

作成ができたら、対象リソースが存在していること、また「出力」タブで以下のような画面が表示されて要件が満たせていることを確認しましょう。

作成したスタックを削除すると通常は、CFn テンプレートを元に作成したリソースは削除されます。しかし、前述の DeletionPolicy のオプションは、Retain を指定することで対象のリソースの保護が可能です。重要なリソースについては誤ってスタック削除しても大丈夫なように当該オプションを有効にしておきましょう。

最後に

CFn を用いて、初期設定用の IAM ユーザを作成してみました。要件に併せて多要素認証を必須にしたりしてアレンジして見てください。

以上、筧 @TakaakiKakei でした!

更新履歴

  • 2019/12/08 新規作成