AWS CLIからCloudFormation でユーザとロールを作成して、流れるようにスイッチロールの確認をしてみた

2020.04.14

最近は、ABACばっかりやってるAWS 事業本部 梶原@福岡オフィスです。

ABAC(属性ベースのアクセスコントロール )を実施する際、ポリシーは同一にして、スケールすることができるのですが、ユーザやロールの確認作業は必要になってきます。 とはいえ、様々な属性値のユーザの確認作業を手作業でやるのは結構大変です。

ということで検証作業を楽にするため、ユーザー作成、ロール作成部分をTemplate化しました。必要に応じて修正(タグ値を追加など)して、ご自由にお使いください また流れで、ロールの検証を行いたいため、スイッチロールを楽にするために認証情報を取得しやすくしています。 credentialsの設定や、configの設定って微妙にはまりがちなのでなるべく簡単に定型作業でできるようにしています。でわでわ

Templateの説明

Template全体は、Githubへのリンクを参照してください

ユーザー、ロール作成用 CloudFormation テンプレート

https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-iam-user.yml

ユーザ作成部分

パラメータで指定したRoleへのAssumeRoleだけ可能なユーザを作成しています

  IAMManagedPolicyAssumeRole:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: access-assume-role
      Path: /
      PolicyDocument: !Sub |
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "AssumeRole",
                    "Effect": "Allow",
                    "Action": "sts:AssumeRole",
                    "Resource": "arn:aws:iam::${AWS::AccountId}:role/${RoleName}"
                }
            ]
        }

  IAMUser1:
    Type: AWS::IAM::User
    Properties:
      Path: /
      UserName: !Ref UserName
      ManagedPolicyArns:
        - !Ref IAMManagedPolicyAssumeRole

ロール作成部分

信頼されたエンティティに作成したユーザを指定しています

  IAMRole1:
    Type: AWS::IAM::Role
    Properties:
      Path: /
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument: !Sub |
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": "sts:AssumeRole",
                    "Principal": {"AWS":"${IAMUser1.Arn}"}
                }
            ]
        }
      MaxSessionDuration: 3600

API アクセスキー作成部分

API アクセスキーを作成します

  IAMAccessKeyUser1:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref IAMUser1

API アクセスキー保存部分

作成したAPIキーをSecretsManagerに保存しています。 後で使いやすいように認証情報ファイル(credentials)で使いやすいように整形しています 後程、設定情報ファイル(.aws/credentials)に設定します。

※ 認証情報をSecretsManager保持することになるため、必要に応じてパラメータのKmsKeyIdを指定し 作成したユーザだけが復号、取得できるようにするなどの対応を推奨します。

  SecretUser1:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub ${IAMUser1}-credentials
      KmsKeyId: !If [UseKmsKey, !Ref KmsKeyId, !Ref "AWS::NoValue"]
      SecretString: !Sub |
        [${IAMUser1}]
        aws_access_key_id = ${IAMAccessKeyUser1}
        aws_secret_access_key = ${IAMAccessKeyUser1.SecretAccessKey}

こんな感じの文字列が設定されます

[UserA]
aws_access_key_id = xxxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

認証設定情報保存部分

こちらは認証情報を含まないため、設定ファイル(config)で使いやすいように整形して保存しています。 後程、設定情報ファイル(.aws/config)に設定します。

内容は追加したユーザから作成したロールにスイッチロールする設定になります

  IAMRole1Config:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Value: !Sub |
        [profile ${IAMRole1}]
        role_arn = ${IAMRole1.Arn}
        source_profile = ${IAMUser1}

こんな感じの文字列が設定されます

[profile RoleA]
role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleA
source_profile = UserA

出力部

使用しやすいように、作成したユーザやロールをパラメータにしたコマンドを出力しています。

Outputs:
  User1Credentials:
    Value: !Sub |
      aws secretsmanager get-secret-value --secret-id ${SecretUser1} --query 'SecretString' --output text >> ~/.aws/credentials
  User1Config:
    Value: !Sub |
      aws ssm get-parameters --names ${IAMRole1Config} --query 'Parameters[].Value' --output text >> ~/.aws/config
  User1SwitchRole:
    Value: !Sub |
      aws sts get-caller-identity --profile ${IAMRole1}

AWS CLIからCloudFormationの実行

なお、CloudFormationの実行権限等はあるものとして進めています。

Stack作成

テンプレート cfn-iam-user.yml を実行して、スタック作成します。 ユーザ名、ロール名などはパラメータで指定できるようにしていますが、ここではデフォルト値(UserA, RoleA)を使用します。

template=cfn-iam-user
aws cloudformation create-stack --stack-name $template \
--template-body "file://./$template.yml" \
--capabilities CAPABILITY_NAMED_IAM

AWS CLIからCloudFormationの実行結果を取得し、認証情報を設定

認証情報の取得

認証情報をSecretsManagerから取得します。CloudFormationの出力に取得用のコマンドを設定しているので取得します。

aws cloudformation describe-stacks --stack-name $template \
--query 'Stacks[].Outputs[?OutputKey==`User1Credentials`].OutputValue' \
--output text

以下のようなコマンドが取得できるかと思いますので実行します。 取得した認証情報を ~/.aws/credentials に追記しています。

aws secretsmanager get-secret-value --secret-id arn:aws:secretsmanager:ap-northeast-1:XXXXXXXXXXXX:secret:UserA-credentials-XXXXX --query 'SecretString' --output text >> ~/.aws/credentials

必要に応じて実際に設定(追記)されているか確認してみます。

cat ~/.aws/credentials

認証設定の取得

認証設定情報をSystemsManager のパラメータから取得します。CloudFormationの出力に取得用のコマンドを設定しているので取得します。

aws cloudformation describe-stacks --stack-name $template \
--query 'Stacks[].Outputs[?OutputKey==`User1Config`].OutputValue' \
--output text

以下のようなコマンドが取得できるかと思いますので実行します。 取得した認証設定情報を ~/.aws/config に追記しています。

aws ssm get-parameters --names CFN-IAMRole1Config-XXXXXXXXXXXX --query 'Parameters[].Value' --output text >> ~/.aws/config

必要に応じて実際に設定(追記)されているか確認してみます。

cat ~/.aws/config

AWS CLIからスイッチロール権限の確認

スイッチロールの確認

profileで指定できるようにしてますのでユーザの認証、スイッチロールが実行できるか確認します。

aws cloudformation describe-stacks --stack-name $template \
--query 'Stacks[].Outputs[?OutputKey==`User1SwitchRole`].OutputValue' \
--output text

以下のようなコマンドが取得できるかと思いますので実行します。 特にエラー等が発生せずに、Arnが取得できていればユーザの認証、スイッチロールは成功しています

aws sts get-caller-identity --profile UserA
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX",
"Account": "XXXXXXXXXXXX",
"Arn": "arn:aws:iam::XXXXXXXXXXXX:user/UserA"
}

aws sts get-caller-identity --profile RoleA
{
"UserId": "XXXXXXXXXXXXXXX:botocore-session-1586854302",
"Account": "XXXXXXXXXXXXXXX",
"Arn": "arn:aws:sts::XXXXXXXXXXXXXXX:assumed-role/RoleA/botocore-session-XXXXXXXXXXXXXXX"
}

おまけ 既存のRoleにポリシーを追加してみる

これだけだと、ただスイッチロールの検証だけですので、必要なポリシーを定義した管理ポリシーを作成したロールに追加します。

サンプルとしてS3の権限を作成した管理ポリシーを先ほど作成したロールに追加します。

template=cfn-add-policy
aws cloudformation create-stack --stack-name $template --template-body "file://./$template.yml" \
--parameters "ParameterKey=Roles, ParameterValue=RoleA" \
--capabilities CAPABILITY_NAMED_IAM

スタックの作成、成功後、にprofileを指定して、S3へのアクセス権限等を確認します。

aws s3 ls --profile RoleA

まとめ

コマンドラインでの作業でなるべく完結するようにしてみました。コマンドライン(AWS CLI)で実施できるところまで行けば、検証含めた自動化もやりやすくなるかと思います。 今回公開しているテンプレートは基本的な部分にそぎおとしてますが、テンプレートの素材としては使いやすいようにしたつもりですので、どなたかのお役に立てれば幸いです。

後片付け

検証が終了したら、スタック、リソースは削除してしまいます。便利です。

template=cfn-iam-user
aws cloudformation delete-stack --stack-name $template

認証情報(~/.aws/credentials)、認証設定情報(~/.aws/config)も適時消してください。

テンプレートファイル

ユーザー、ロール作成用 CloudFormation テンプレート https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-iam-user.yml

既存のロールへの管理ポリシーの追加用 CloudFormation テンプレート

https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-add-policy.yml

参考情報

https://aws.amazon.com/jp/premiumsupport/knowledge-center/iam-assume-role-cli/