LoginSignup
2
0

AWS Organizations無しでユーザ権限を良い感じに管理する

Last updated at Posted at 2023-12-14

この記事はZOZO AdventCalender 2023シリーズ9の15日目の記事です。

はじめに

  • 本記事は以下のようなケースを想定しています。
    • 何らかの理由によってOrganizationsが使えない。
    • マルチアカウント構成におけるユーザ権限を良い感じに管理したい。
  • Organizationsを使わないことを推奨するものではありません、使える場合には迷うことなく使いましょう。
    • 例えば、ルートユーザに対して制限を加えたい場合にはOrganizationsによるSCPが必要です。
  • こういった作り方もあるよねという一例として見てもらえればと思います。

前提条件

本記事における前提条件を記載します。

  • AWSアカウントは3つ(管理用アカウント、開発用アカウント1、開発用アカウント2)
    • 管理用アカウント
      • IAMユーザの管理
      • 後述するStackSetsの管理用アカウント
    • 開発用アカウント1、開発用アカウント2
      • 開発者の作業用
  • 開発用アカウントには、以下3つの役割でアクセスする想定。
    • 管理者
      • 全ての権限を持つ(AdministratorAccess相当)
    • 開発者
      • 一部を除いて全ての権限を持つ(基本はAdministratorAccess相当)
      • CloudTrailに対する書き込み系の操作は禁止
      • 自身の権限を変更することは禁止(権限昇格の防止)
    • 監査者
      • 閲覧権限のみを持つ(ReadOnlyAccess相当)

アーキテクチャ

アーキテクチャは以下の通りです。

アーキテクチャ図.png

IAMユーザは管理アカウントに作成します。
一方で、開発用アカウントには役割毎に適切なポリシーを付与したIAMロールを作成し、管理アカウントからスイッチロール出来るようにします。
IAMユーザにはスイッチロールするためのAssumeRole権限が必要となるため、役割毎に用意したIAMグループに対して、当該操作を許可するポリシーを割り当てます。

設定の配布方法

設定の配布は以下のイメージで行います。

リソースの管理方法.png

各AWSアカウントに設定を配布する際には、CloudFormation StackSetsを用いて一元管理します。
また、StackSetsで作成されたリソースにはManagedResourceという名前のタグで目印をつけます(タグの名前は任意で良いです)。
タグがついたリソースに対するポリシーを各IAMロールへ適切に設定することで、勝手に権限が変更されないようにします。

作り方

まず、AWSアカウントを3つ作成します。
作成方法は以下をご確認ください。

続けて、以下の流れで設定を行なっていきます。

  1. 開発用アカウントの設定(StackSets用)
  2. 管理アカウントの設定(StackSets用)
  3. 管理アカウントの設定(IAMグループの作成)
  4. スイッチロール用IAMロールの作成
  5. IAMユーザの作成

本手順で記載されている内容は最低限の設定のみを実施しています。
実際に運用する際にはセキュリティを考慮した上で適宜判断してください。

1. 開発用アカウントの設定(StackSets用)

StackSetsの実行に使用するターゲットアカウント側のIAMロールを作成します。
このIAMロールはAWSCloudFormationStackSetExecutionRoleという名前である必要があります。
詳細は、以下をご確認ください。

ロールを作成します。
image.png

信頼されたエンティティタイプとしてAWSアカウントを選択し、別のAWSアカウントに管理用アカウントのアカウントIDを入力します。

スクリーンショット 2023-12-12 16.26.40.png

許可ポリシーとしてAdministratorAccessを選択します。

image.png

ロール名をAWSCloudFormationStackSetExecutionRoleとして作成します。

image.png

同様の手順を、もう一方の開発用アカウントに対しても実施します。

2. 管理アカウントの設定(StackSets用)

StackSetsの実行に使用する管理者アカウント側のIAMロールを作成します。
このIAMロールはAWSCloudFormationStackSetAdministrationRoleという名前である必要があります。
詳細は、以下をご確認ください。

ロールを作成します。

image.png

信頼されたエンティティタイプとしてAWSのサービスを選択し、サービスまたはユースケースとしてCloudFormationを選択します。

image.png

許可を追加では何もせずに次へ進みます。

image.png

ロール名をAWSCloudFormationStackSetAdministrationRoleとして作成します。

image.png

続けて、作成したAWSCloudFormationStackSetAdministrationRoleロールを選択し、許可を追加からインラインポリシーを作成します。

image.png

以下のルールでポリシーを作成します(ポリシー名は任意です)。

AWSCloudFormationStackSetAdministrationRolePolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"
            ],
            "Effect": "Allow"
        }
    ]
}

3. 管理アカウントの設定(IAMグループの作成)

管理アカウントに対して、役割毎のIAMグループを作成します。
今回は、以下のCloudFormationテンプレートを用意します。

create-iam-group.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: create iam group

Resources:
  # ---------------------------------------------
  # Group
  # ---------------------------------------------
  GroupAdministrator:
    Type: AWS::IAM::Group
    Properties:
      GroupName: group-administrator

  GroupDeveloper:
    Type: AWS::IAM::Group
    Properties:
      GroupName: group-developer

  GroupAudit:
    Type: AWS::IAM::Group
    Properties:
      GroupName: group-audit

  # ---------------------------------------------
  # Policy
  # ---------------------------------------------
  PolicyAdministrator:
    Type: AWS::IAM::Policy
    Properties:
      Groups:
        - !Ref GroupAdministrator
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - "sts:AssumeRole"
            Resource:
              - "arn:aws:iam::*:role/role-administrator"
      PolicyName: policy-administrator

  PolicyDeveloper:
    Type: AWS::IAM::Policy
    Properties:
      Groups:
        - !Ref GroupDeveloper
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - "sts:AssumeRole"
            Resource:
              - "arn:aws:iam::*:role/role-developer"
      PolicyName: policy-developer

  PolicyAudit:
    Type: AWS::IAM::Policy
    Properties:
      Groups:
        - !Ref GroupAudit
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - "sts:AssumeRole"
            Resource:
              - "arn:aws:iam::*:role/role-audit"
      PolicyName: policy-audit

CloudFormationから当該テンプレートを適用します。
スタックの作成を押下します。
image.png

用意したテンプレートファイルを選択して次へ。
image.png

任意の名前を入力して次へ。
image.png

スタックオプションの設定では何をせずに次へ。
image.png

設定内容を確認して送信を押下します。
image.png

スタックの作成が完了したら次の手順へ進みます。

4. スイッチロール用IAMロールの作成

管理アカウントから開発アカウントに対してスイッチロール用IAMロールを作成します。
今回は、以下のCloudFormationテンプレートを用意します。

create-switchrole.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: create switchrole

Parameters:
  ManagementAWSAccountId:
    Type: String
    Description: AWS Account ID of Management Account

Resources:
  # ---------------------------------------------
  # Role
  # ---------------------------------------------
  RoleAdministrator:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref ManagementAWSAccountId
            Action:
              - 'sts:AssumeRole'
      Description: Administrator Role
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AdministratorAccess
      RoleName: role-administrator

  RoleDeveloper:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref ManagementAWSAccountId
            Action:
              - 'sts:AssumeRole'
      Description: Developer Role
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AdministratorAccess
      RoleName: role-developer

  RoleAudit:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref ManagementAWSAccountId
            Action:
              - 'sts:AssumeRole'
      Description: Audit Role
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/ReadOnlyAccess
      RoleName: role-audit

  # ---------------------------------------------
  # Policy
  # ---------------------------------------------
  PolicyAdministratorRestriction:
    Type: AWS::IAM::Policy
    Properties:
      Roles:
        - !Ref RoleAdministrator
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action:
              - "*"
            Resource:
              - "*"
            Condition:
              StringEquals:
                aws:ResourceTag/ManagedResource: "true"
      PolicyName: policy-administrator-restiction

  PolicyDeveloperRestriction:
    Type: AWS::IAM::Policy
    Properties:
      Roles:
        - !Ref RoleDeveloper
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action:
              - "*"
            Resource:
              - "*"
            Condition:
              StringEquals:
                aws:ResourceTag/ManagedResource: "true"
          - Effect: Deny
            Action:
              - "cloudtrail:Cancel*"
              - "cloudtrail:Create*"
              - "cloudtrail:Delete*"
              - "cloudtrail:Enable*"
              - "cloudtrail:Put*"
              - "cloudtrail:Start*"
              - "cloudtrail:Stop*"
              - "cloudtrail:Update*"
              - "cloudtrail:Deregister*"
              - "cloudtrail:Register*"
              - "cloudtrail:Disable*"
              - "cloudtrail:Restore*"
            Resource:
              - "*"
      PolicyName: policy-developer-restiction

  PolicyAuditRestriction:
    Type: AWS::IAM::Policy
    Properties:
      Roles:
        - !Ref RoleAudit
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Action:
              - "*"
            Resource:
              - "*"
            Condition:
              StringEquals:
                aws:ResourceTag/ManagedResource: "true"
      PolicyName: policy-audit-restiction

CloudFormation StackSetsから当該テンプレートを適用します。
StackSetsの作成を押下します。
image.png

IAM管理ロールとして、先に作成したAWSCloudFormationStackSetAdministrationRoleを選択します。
また、実行ロール名にはターゲットアカウント側に作成したAWSCloudFormationStackSetExecutionRoleを入力します。
image.png

用意したテンプレートファイルを選択して次へ。
image.png

任意の名前を入力し、パラメータ(管理用アカウントのAWSアカウントID)を入力して次へ。
スクリーンショット 2023-12-12 19.54.24.png

スタックオプションの設定では、タグ(キー:ManagedResource、値:true)を指定します。
ここで指定したタグがCloudFormationで作成されるリソースに付与され、先に用意したIAMロールによる制御対象とすることが出来ます。
image.png

デプロイオプションの設定では、デプロイ先のAWSアカウントIDとリージョンを指定します。
AWSアカウントIDには開発用アカウントのAWSアカウントID×2、リージョンは利用するリージョン(今回は東京リージョンとします)を指定します。

スクリーンショット 2023-12-12 19.59.43.png

image.png

設定内容を確認して送信を押下します。
image.png

スタックの作成が完了したら次の手順へ進みます。

5. IAMユーザの作成

管理用アカウントにIAMユーザを作成します。
今回は、例として先のアーキテクチャ図で記載したsaburoさん(開発者ロール)を作成します。

ユーザの作成を押下します。
image.png

ユーザ名にsaburoと入力し、AWSマネジメントコンソールへのアクセスにチェックを入れて次へ。
image.png

先に作成した開発者用のIAMグループ(group-developer)を選択して次へ。
image.png

設定内容を確認してユーザーの作成を押下。
image.png

作成したsaburoユーザでAWSマネジメントコンソールへログインします。
画面右上のロールの切り替えからスイッチロール出来ることを確認します。
スクリーンショット 2023-12-12 20.14.48.png

スイッチロール先のAWSアカウントIDとロール名を入力して、ロールの切り替えを押下。
スクリーンショット 2023-12-12 20.16.26.png

ロールが切り替わったことが確認出来ます。
スクリーンショット 2023-12-12 20.17.56.png

動作確認

前の手順でスイッチロールした状態で、許可されていない操作が出来ないことを確認します。

まず、自分の権限の変更を試してみます。
自分のIAMロール(role-developer)を参照しようとした時点で権限がないことが確認出来ます。
スクリーンショット 2023-12-12 20.26.54.png

次に、StackSetsで作成されたCloudFormationスタックが削除出来るか確認します。
先の例と同じようにStackSetsで作成されたスタックを参照しようとした時点で権限がないことが確認出来ます。
スクリーンショット 2023-12-12 20.28.48.png

最後に、CloudTrail証跡の削除を試みました(記事には記載していませんが、あらかじめ有効にしておきました)。
上部に黄色く表記されていますが、削除権限が無いことが確認出来ます。
スクリーンショット 2023-12-12 20.42.10.png

このように、スイッチロール先のIAMロールに対してポリシーを適切に設定することで、OrganizationsにおけるSCPのように
ブラックリスト的な操作を指定することが出来ます。

最後に

  • AWSを使ってマルチアカウント構成を取る場合にはOrganizationsを使うことが広く知られており、本記事のような手順を採用することはレアかと思いますが、敢えてそれを使わない方法をまとめてみました。
  • 面倒な方法を試してみることで、サービスの持つ良し悪しがより分かる気がします。
2
0
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
2
0