🦈

JAWS FESTA 2025 in 金沢で登壇しました!

に公開

はじめに

2025年10月11日に開催された JAWS FESTA 2025 in 金沢で、「AWS Control Tower に学ぶ!
権限設計の第一歩
」というタイトルで登壇の機会をいただきましたので、本記事ではその内容について紹介します。

イベント概要

JAWS FESTA は年2回開催される JAWS-UG 主催の全国規模のイベントの一つです。春には東京で JAWS DAYS というものが開催され、秋には東京以外の地方で JAWS FESTA が開催されます。今年の開催は金沢で、北陸地方での開催は初だそうです。

イベント詳細については下記をご覧ください。
https://jawsfesta2025.jaws-ug.jp/

登壇内容

AWS Control Tower が展開する IAM Identity Center の権限構造に着目して、IAM Identity Center の権限設計時にどのような点が参考になるかと、その実践例について紹介しました。

ここでは「グループ分割」と「許可セット」の構成についてと、弊社での具体的な適用例を抜粋して紹介します。

AWS Control Tower が展開する IAM Identity Center の構成

グループ分割の考え方

AWS Control Tower では大きく分けて下記の2種類のグループ分割がなされています。

  • 全アカウントに及ぶ基本グループ
    • アカウント横断的な権限を許可する際に利用
  • 役割別グループ
    • 個別のアカウントや関心ごとに絞った権限が必要な場合に利用

作成されるIAM_Identity_Centerのリソース詳細_整理

許可セットの設計

グループ数より許可セット数の方が少なく、許可セットも再利用性が高い単位で分割されています。

作成される_IAM_Identity_Center_のリソース詳細_許可セット

AWS Control Tower の構成を参考にした適用例

弊社では AWS Contol Tower の管理者と組織横断のインフラの管理者の役割を分離していません。そのため、AWSAccountFactory 等の一部の AWS Control Tower が展開するグループは運用の実態に合わせて統合する形をとりました。

After_見直し後のIAM_Identity_Center_グループ

CloudFormation による IaC 化

ユーザーやその割り当てはもともと手動で作成しており、その IaC 化を考えると少し複雑となるので、下記のみを IaC 化としました。

  • グループ
  • アサインメント
  • 許可セット

CloudFormation化の範囲

登壇資料では割愛しましたが、下記が参考の CloudFormation テンプレートです。
AWS::LanguageExtensions を有効化し、Fn::ForEach 使用することで、アサインメント作成の手間を軽減しています。

グループおよびアサインメント用 CloudFormation
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Description: Configure IAM Identity Center Groups and Permission Sets.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Identity Center Configuration
        Parameters:
          - IdentityStoreId
          - InstanceArn


Parameters:
  # ============================================================
  # Identity Center configurations
  # ============================================================
  IdentityStoreId:
    Type: String
    Description: The globally unique identifier for the identity store.
    # パターンについては下記の公式ドキュメントのものを使用
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-identitystore-group.html#cfn-identitystore-group-identitystoreid
    AllowedPattern: ^d-[0-9a-f]{10}$|^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$

  InstanceArn:
    Type: String
    Description: The ARN of the IAM Identity Center instance under which the operation will be executed.
    # パターンについては下記の公式ドキュメントのものを使用
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sso-permissionset.html#cfn-sso-permissionset-instancearn
    AllowedPattern: arn:(aws|aws-us-gov|aws-cn|aws-iso|aws-iso-b):sso:::instance/(sso)?ins-[a-zA-Z0-9-.]{16}


Mappings:
  AccountMaps:
    Management:
      AccountId: '123456789012'
    LogArchive:
      AccountId: '234567890123'
    Audit:
      AccountId: '345678901234'
    AI:
      AccountId: '456789012345'
    XXXXXXProduction:
      AccountId: '567890123456'
    XXXXXXTesting:
      AccountId: '678901234567'

  IdentityCenterMaps:
    Group:
      Names:
        - Admins
        - Editors
        - Viewers
        - SecurityAdmins
        - SecurityEditors
        - AIUsers
        - XXXXXXEngineers

  # CloudFormationの拡張構文でまとめてグループおよび割り当てを追加できるように対応関係をMappingsで定義
  IdentityCenterGroupMaps:
    Admins:
      GroupDescription: 全アカウントの管理グループ。
      PermissionSets:
        - AdministratorAccess
      Accounts:
        - Management
        - LogArchive
        - Audit
        - XXXXXProduction
        - XXXXXTesting

    Editors:
      GroupDescription: 全アカウントの編集グループ。
      PermissionSets:
        - PowerUserAccess
      Accounts:
        - Management
        - LogArchive
        - Audit
        - XXXXXProduction
        - XXXXXTesting

    Viewers:
      GroupDescription: 全アカウントの閲覧グループ。
      PermissionSets:
        - ReadOnlyAccess
      Accounts:
        - Management
        - LogArchive
        - Audit
        - XXXXXProduction
        - XXXXXTesting

    SecurityAdmins:
      GroupDescription: Security OUの管理グループ。
      PermissionSets:
        - AdministratorAccess
      Accounts:
        - Audit
        - LogArchive
    SecurityEditors:
      GroupDescription: Security OUの編集グループ。
      PermissionSets:
        - PowerUserAccess
      Accounts:
        - Audit
        - LogArchive
    AIUsers:
      GroupDescription: AI利用者グループ。
      PermissionSets:
        - AIOnlyAccess
      Accounts:
        - AI
    XXXXXEngineers:
      GroupDescription: XXXXXX関連アカウントの管理・編集グループ。
      PermissionSets:
        - AdministratorAccess
        - PowerUserAccess
      Accounts:
        - XXXXXProduction
        - XXXXXTesting


Resources:
  # ============================================================
  # Group
  # ============================================================
  'Fn::ForEach::Group':
    - GroupName
    - !FindInMap [ IdentityCenterMaps, Group, Names ]
    - '${GroupName}Group':
        Type: AWS::IdentityStore::Group
        Properties:
          DisplayName: !Ref GroupName
          Description: !FindInMap [ IdentityCenterGroupMaps, !Ref GroupName, GroupDescription ]
          IdentityStoreId: !Ref IdentityStoreId

  # ============================================================
  # Assignment
  # ============================================================
  # 論理IDは${グループ名}${許可セット名}${アカウント名}の組み合わせとして命名
  'Fn::ForEach::GroupAssignment':
    - GroupName
    - !FindInMap [ IdentityCenterMaps, Group, Names ]
    - 'Fn::ForEach::PermissionSetAssignment':
      - PermissionSetName
      - !FindInMap [ IdentityCenterGroupMaps, !Ref GroupName, PermissionSets ]
      - 'Fn::ForEach::AccountAssignment':
        - Account
        - !FindInMap [ IdentityCenterGroupMaps, !Ref GroupName, Accounts ]
        - '${GroupName}${PermissionSetName}${Account}':
            Type: AWS::SSO::Assignment
            Properties:
              InstanceArn: !Ref InstanceArn
              PermissionSetArn:
                Fn::ImportValue : !Sub ${PermissionSetName}PermissionSet-Arn
              PrincipalId: !GetAtt
                - !Sub ${GroupName}Group
                - GroupId
              PrincipalType: GROUP
              TargetType: AWS_ACCOUNT
              TargetId: !FindInMap [ AccountMaps, !Ref Account, AccountId ]
許可セット用 CloudFormation
AWSTemplateFormatVersion: 2010-09-09
Description: Configure IAM Identity Center Groups and Permission Sets.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Identity Center Configuration
        Parameters:
          - InstanceArn

Parameters:
  # ============================================================
  # Identity Center configurations
  # ============================================================
  InstanceArn:
    Type: String
    Description: The ARN of the IAM Identity Center instance under which the operation will be executed.
    # パターンについては下記の公式ドキュメントのものを使用
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sso-permissionset.html#cfn-sso-permissionset-instancearn
    AllowedPattern: arn:(aws|aws-us-gov|aws-cn|aws-iso|aws-iso-b):sso:::instance/(sso)?ins-[a-zA-Z0-9-.]{16}


Resources:
  # ============================================================
  # PermissionSet
  # ============================================================
  AdministratorAccessPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: AdministratorAccess
      Description: Provides full access to AWS services and resources
      InstanceArn: !Ref InstanceArn
      SessionDuration: PT1H # ISO-8601による継続時間表記 (1時間)
      ManagedPolicies:
        - arn:aws:iam::aws:policy/AdministratorAccess

  PowerUserAccessPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: PowerUserAccess
      Description: Provides full access to AWS services and resources, but does not allow management of Users and groups
      InstanceArn: !Ref InstanceArn
      SessionDuration: PT1H
      ManagedPolicies:
        - arn:aws:iam::aws:policy/PowerUserAccess
        - arn:aws:iam::aws:policy/IAMReadOnlyAccess

  ReadOnlyAccessPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: ReadOnlyAccess
      Description: Provide read-only access to AWS services and resources, but do not allow downloading S3 objects, except for the Log Archive account.
      InstanceArn: !Ref InstanceArn
      SessionDuration: PT1H
      ManagedPolicies:
        - arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
        - arn:aws:iam::aws:policy/IAMReadOnlyAccess
        - arn:aws:iam::aws:policy/AmazonGuardDutyReadOnlyAccess
        - arn:aws:iam::aws:policy/AWSSecurityHubReadOnlyAccess
        - arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess
      # カスタマー管理ポリシーにすると事前に各アカウントにポリシーを配布する必要があるためインラインポリシーを指定
      InlinePolicy: !Sub |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "LogArchiveS3Policy",
              "Effect": "Allow",
              "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:Describe*"
              ],
              "Resource": "*",
              "Condition": {
                "ArnLike": {
                  "aws:PrincipalArn": "arn:${AWS::Partition}:iam::234567890123:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_ReadOnlyAccess_*"
                }
              }
            },
            {
              "Sid": "CostExplorePolicy",
              "Effect": "Allow",
              "Action": [
                "ce:GetCostCategories",
                "ce:GetDimensionValues",
                "ce:GetCostAndUsageWithResources",
                "ce:GetCostAndUsage",
                "ce:GetCostForecast",
                "ce:GetTags",
                "ce:GetUsageForecast",
                "ce:DescribeReport"
              ],
              "Resource": "*"
            }
          ]
        }


  AIOnlyAccessPermissionSet:
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: AIOnlyAccess
      Description: Provide access to AI resources, such as Amazon Bedrock invocation.
      InstanceArn: !Ref InstanceArn
      # AI用の許可セットについては頻繁にSSOしなくてよいようにSessionDurationを長く指定
      # 用途を限定しているため、SessionDurationが長いことを許容している
      SessionDuration: PT12H
      # カスタマー管理ポリシーにすると事前に各アカウントにポリシーを配布する必要があるためインラインポリシーを指定
      InlinePolicy: |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "bedrock:InvokeModel",
                "bedrock:InvokeModelWithResponseStream"
              ],
              "Resource": [
                "arn:aws:bedrock:*::foundation-model/*",
                "arn:aws:bedrock:*:*:application-inference-profile/*"
              ]
            }
          ]
        }

Outputs:
  AdministratorAccessPermissionSetArn:
    Description: ARN of the AdministratorAccess Permission Set
    Value: !GetAtt AdministratorAccessPermissionSet.PermissionSetArn
    Export:
      Name: AdministratorAccessPermissionSet-Arn

  PowerUserAccessPermissionSetArn:
    Description: ARN of the PowerUserAccess Permission Set
    Value: !GetAtt PowerUserAccessPermissionSet.PermissionSetArn
    Export:
      Name: PowerUserAccessPermissionSet-Arn

  ReadOnlyAccessPermissionSetArn:
    Description: ARN of the ReadOnlyAccess Permission Set
    Value: !GetAtt ReadOnlyAccessPermissionSet.PermissionSetArn
    Export:
      Name: ReadOnlyAccessPermissionSet-Arn

  AIOnlyAccessPermissionSetArn:
    Description: ARN of the AIOnlyAccess Permission Set
    Value: !GetAtt AIOnlyAccessPermissionSet.PermissionSetArn
    Export:
      Name: AIOnlyAccessPermissionSet-Arn

おわりに

初 JAWS FESTA かつ 初登壇で緊張しましたが、ワークショップや様々な方の発表に触れることができ、非常に学びが多い機会となりました。

イベントを支えてくださった皆様、本当にありがとうございました。

次にこのような機会がある場合には、今回よりも気持ち的にも余裕を持って取り組めるように励んでいきたいです。

BABY JOB  テックブログ

Discussion