Amazon Web Services ブログ

Azure AD 連携された IAM Identity Center の SCIM イベントを用いて Amazon QuickSight のユーザーとグループのメンバーシップ管理をする

この記事は、Professional Services team の Principal Bigdata Consultant である Takeshi Nakatani と Amazon QuickSight の Specialist Solution Architect である Wakana Vilquin-Sakashita によって書かれた Manage users and group memberships on Amazon QuickSight using SCIM events generated in IAM Identity Center with Azure AD (記事公開日: 2023 年 3 月 22 日) を翻訳したものです。

Amazon QuickSight は、ID フェデレーションをサポートするクラウドネイティブでスケーラブルなビジネスインテリジェンス (BI) サービスです。AWS Identity and Access Management (IAM) により、組織はエンタープライズ ID プロバイダー (IdP) で管理されている ID を使用し、シングルサインオン (SSO) を QuickSight に統合できます。オンプレミスアプリ、サードパーティアプリ、AWS 上のアプリケーションなど、すべてのアプリケーションを使用して一元化されたユーザー ID ストアを構築する組織が増えているため、これらのアプリケーションへのユーザープロビジョニングを自動化し、その属性を一元化されたユーザー ID ストアと同期させるソリューションが必要です。

ユーザーのリポジトリを構築する際、組織によっては、ユーザーをグループにまとめたり、属性 (部署名など) を使用したり、あるいはその両方を組み合わせたりします。組織で一元管理された認証に Microsoft Azure Active Directory (Azure AD) を使用し、そのユーザー属性を利用してユーザーの構成を管理している場合は、すべての QuickSight アカウント間のフェデレーションを有効にできるだけでなく、AWS プラットフォームで生成されたイベントを使用して QuickSight のユーザーとそのグループメンバーシップを管理できます。これにより、システム管理者は Azure AD からユーザー権限を一元管理できます。このソリューションにより、QuickSight のユーザーやグループのプロビジョニング、更新、削除を、QuickSight 上で管理する必要がなくなり、自動同期にて Azure AD の情報と一貫性を保つことができるようになります。

この記事では、Azure AD の自動プロビジョニングが有効になっている AWS アイデンティティセンター (AWS Single Sign-On の後継) を介して QuickSight と Azure AD 間のフェデレーション SSO を設定するために必要な手順について説明します。また、クロスドメインID管理システム (SCIM) イベントを使用して、ユーザーとグループのメンバーシップを自動的に更新するデモも行います。

ソリューション概要

次の図は、ソリューションのアーキテクチャとユーザーフローを示しています。

この記事では、IAM Identity Center を使用してユーザーと AWS アカウントやクラウドアプリケーションへのアクセスを一元管理できます。Azure AD はユーザーリポジトリであり、IAM Identity Center で外部 IdP として設定されています。このソリューションでは、特に Azure AD での 2 つのユーザー属性 (department, jobTitle) の使用方法を示します。IAM Identity Center は、SCIM v2.0 プロトコルを使用して Azure AD から IAM Identity Center へのユーザーおよびグループ情報の自動プロビジョニング (同期) をサポートしています。このプロトコルでは、Azure AD の属性が IAM Identity Center に渡され、IAM Identity Center で定義されたユーザープロファイルの属性に継承されます。IAM Identity Center は、SAML (Security Assertion Markup Language) 2.0 とのアイデンティティフェデレーションもサポートしています。これにより、IAM Identity Center は Azure AD を使用して ID を認証できます。その後、ユーザーは QuickSight などの SAML をサポートするアプリケーションに SSO で接続できます。この記事の前半では、これをエンドツーエンドで設定する方法に焦点を当てています (図の Sign-In Flow を参照)。

次に、ユーザー情報は SCIM プロトコルを介して Azure AD と IAM Identity Center の間で同期され始めます。Amazon EventBridge でキャプチャされた IAM Identity Center から発生した CreateUser SCIM イベントによってトリガーされる AWS Lambda 関数を使用して、QuickSight でのユーザーの作成を自動化できます。同じ Lambda 関数で、指定したグループ (名前が department-jobTitle という2つのユーザー属性で構成されるもの) に追加することでユーザーのメンバーシップも更新できます。グループが存在しない場合は、メンバーシップを追加する前にグループを作成してください。

この記事では、この自動化の部分は、次のセクションで説明する内容と重複するため、省略しています。

この記事では、Azure AD でのユーザープロファイルの更新によってトリガーされる UpdateUser SCIM イベントについて説明し、そのデモを行います。イベントは EventBridge でキャプチャされ、Lambda 関数を呼び出して QuickSight のグループメンバーシップを更新します (図の Update Flow を参照)。この例では、特定のユーザーは一度に 1 つのグループにのみ所属することになっているため、この関数はユーザーの現在のグループメンバーシップを新しいグループメンバーシップに置き換えます。

パート I では、IAM Identity Center 経由で Azure AD から QuickSight への SSO を設定します。(サインインフロー)

  1. Azure AD を IAM Identity Center の外部 IdP として設定します。
  2. Azure AD に IAM Identity Center アプリケーションを追加して設定します。
  3. IAM Identity Center の設定を完了します。
  4. Azure AD と IAM Identity Center の両方で SCIM 自動プロビジョニングを設定し、IAM Identity Center 上でその動作を確認します。
  5. IAM Identity Center に QuickSight アプリケーションを追加して設定します。
  6. SAML IdP と SAML 2.0 フェデレーション IAM ロールを設定します。
  7. QuickSight アプリケーションで属性を設定します。
  8. AWS コマンドラインインターフェイス (AWS CLI) または API を使用して、ユーザー、グループ、およびグループのメンバーシップを手動で作成します。
  9. IAM Identity Center ポータルから QuickSight にログインして、設定を確認します。

パート II では、SCIM イベント時にグループのメンバーシップを変更する自動化を設定します。(更新フロー)

  1. EventBridge の SCIM イベントとイベントパターンについて理解しましょう。
  2. グループ名の属性マッピングを作成します。
  3. Lambda 関数を作成します。
  4. イベントをトリガーする EventBridge ルールを追加します。
  5. Azure AD のユーザー属性値を変更して構成を確認します。

前提条件

このチュートリアルでは、次の前提条件を満たしている必要があります。

  • IAM Identity Center の設定。手順については、AWS IAM Identity Center のユーザーガイドの「はじめに」のステップ 1 ~ 2 を参照してください。
  • QuickSight アカウントのサブスクリプション。
  • IAM に関する基本的な知識と、IAM IdP の作成に必要な権限、ロール、およびポリシーの理解。
  • Azure AD のサブスクリプション。Azure AD 上に以下の属性をもつ少なくとも一人のユーザが登録されている必要があります。
    • userPrincipalName – Azure AD ユーザーの必須フィールド。
    • displayName – Azure AD ユーザーの必須フィールド。
    • Mail – IAM Identity Center が QuickSight と連携するための必須フィールド。
    • jobTitle – ユーザーをグループに割り当てるのに使用。
    • department – ユーザーをグループに割り当てるのに使用。
    • givenName – オプションフィールド。
    • surname – オプションフィールド。

パート I: IAM Identity Center 経由で Azure AD から QuickSight に SSO をセットアップする

このセクションでは、サインインフローを設定する手順を示します。

IAM Identity Center で外部 IdP を Azure AD として設定する

外部 IdP を設定するには、次の手順を実行します。

  1. IAM Identity Center のコンソールで、Settings を選択します。
  2. Identity source タブで Actions を選択し、Change identity source を選択します。
  3. External identity provider を選択し、Next を選択します。

IdP メタデータが表示されます。このブラウザタブは開いたままにしてください。

Azure AD での IAM Identity Center アプリケーションの追加と設定

IAM Identity Center アプリケーションをセットアップするには、次の手順を実行します。

  1. 新しいブラウザタブを開きます。
  2. Azure 管理者の認証情報を使用して Azure AD ポータルにログインします。
  3. Azure servicesAzure Active Directory を選択します。
  4. ナビゲーションペインの Manage で、Enterprise applications を選択し、New application を選択します。
  5. Browse Azure AD Galley セクションで IAM Identity Center を検索し、AWS IAM Identity Center (AWS Single Sign-On の後継) を選択します。
  6. アプリケーションの名前を入力し (この記事では IIC-QuickSight を使用しています)、Create を選択します。
  7. Manage セクションで、Single sign-on を選択し、次に SAML を選択します。
  8. Assign users and groups セクションで、Assign users and groups を選択します。
  9. Add user/group を選択し、少なくとも 1 人のユーザーを追加します。
  10. 役割として User を選択します。
  11. Set up single sign on セクションで、Get started を選択します。
  12. Basic SAML Configuration セクションで、Edit を選択し、次のパラメータと値を入力します。
    • IdentifierIAM Identity Center issuer URL フィールドの値。
    • Reply URLIAM Identity Center Assertion Consumer Service (ACS) URL フィールドの値。
    • Sign on URL – 空欄のままにしておきます。
    • Relay State – 空欄のままにしておきます。
    • Logout URL – 空欄のままにしておきます。
  13. Save を選択します。

設定は次のスクリーンショットのようになるはずです。

SAML Certificates セクションで、Federation Metadata XML ファイルと Certificate (Raw) ファイルをダウンロードします。

これで、Azure AD SSO の設定は完了です。後でこのページに戻って自動プロビジョニングを設定するので、このブラウザタブは開いたままにしておいてください。

IAM Identity Center の設定を完了

次の手順で IAM Identity Center の設定を完了します。

  1. 前のステップで開いたままにしておいた IAM Identity Center コンソールのブラウザタブに戻ります。
  2. Identity provider metadata プロバイダーメタデータセクションの IdP SAML metadata については、Choose file を選択します。
  3. 以前にダウンロードしたメタデータファイル (IIC-QuickSight.xml) を選択します。
  4. Identity provider metadata セクションにある IdP certificate については、Choose file を選択します。
  5. 以前にダウンロードした証明書ファイル (IIC-QuickSight.cer) を選択します。
  6. Next を選択します。
  7. ACCEPT と入力し、Change Identity provider source を選択します。

Azure AD と IAM Identity Center の両方に SCIM 自動プロビジョニングをセットアップ

プロビジョニング方法はまだ Manual (non-SCIM) に設定されています。このステップでは、IAM Identity Center がユーザーを認識できるように自動プロビジョニングを有効にします。これにより、QuickSight への ID フェデレーションが可能になります。

  1. Automatic provisioning セクションで、Enable を選択します。
  2. Access token を選択してトークンを表示します。
  3. Step 1 で開いたままにしていたブラウザータブ (Azure AD) に戻ります。
  4. Manage セクションで、Enterprise applications を選択します。
  5. IIC-QuickSight を選択し、次に Provisioning を選択します。
  6. Provisioning ModeAutomatic を選択し、次の値を入力します。
    • Tenant URLSCIM endpoint フィールドの値。
    • Secret TokenAccess token フィールドの値。
  7. Test Connection を選択します。
  8. テスト接続が正常に完了したら、Provisioning StatusOn に設定します。
  9. Save を選択します。
  10. SCIM プロトコルを使用して自動プロビジョニングを開始するには、Start provisioning を選択します。

プロビジョニングが完了すると、1 人以上のユーザーが Azure AD から IAM Identity Center に伝達されます。次のスクリーンショットは、IAM Identity Center 上にプロビジョニングされたユーザーを示しています。

この SCIM プロビジョニングでは、IAM Identity Center から発生したイベントによってトリガーされる Lambda 関数を使用して QuickSight のユーザーを作成する必要があることに注意してください。この記事では、AWS CLI を使用してユーザーとグループのメンバーシップを作成します (Step 8)。

IAM Identity Center での QuickSight アプリケーションの追加と設定

このステップでは、IAM Identity Center で QuickSight アプリケーションを作成します。また、アプリケーションが動作するように IAM SAML プロバイダー、ロール、およびポリシーを設定します。次の手順を実行してください。

  1. IAM Identity Center コンソールの Applications ページで、Add Application を選択します。
  2. Select an applicationPre-integrated applicationquicksight と入力します。
  3. Amazon QuickSight を選択し、Next を選択します。
  4. Display nameAmazon QuickSight などの名前を入力します。
  5. IAM Identity Center SAML metadata file の下の Download を選択し、コンピューターに保存します。
  6. 他のフィールドはすべてそのままにして、設定を保存します。
  7. 作成したアプリケーションを開いて、Assign Users を選択します。

先に SCIM 経由でプロビジョニングされたユーザーが一覧表示されます。

  1. アプリケーションに割り当てるユーザーをすべて選択します。

SAML IdP と SAML 2.0 フェデレーション IAM ロールの設定

IAM Identity Center の IAM SAML IdP と、 IAM ロールをセットアップするには、以下の手順を実行します。

  1. IAM コンソールのナビゲーションペインで Identity providers を選択し、Add provider を選択します。
  2. Provider type として SAML を選択し、Provider name として Azure-IIC-QS を入力します。
  3. Metadata documentChoose file を選択し、以前にダウンロードしたメタデータファイルをアップロードします。
  4. Add provider を選択して設定を保存します。
  5. ナビゲーションペインで Roles を選択し、次に Create role を選択します。
  6. Trusted entity type で、SAML 2.0 federation を選択します。
  7. Choose a SAML 2.0 provider で、作成した SAML プロバイダーを選択し、Allow programmatic and AWS Management Console access を選択します。
  8. Next を選択します。
  9. Add Permission ページで、Next を選択します。

この記事では、AWS CLI コマンドを使用して QuickSight ユーザーを作成しているため、許可ポリシーは作成しません。ただし、QuickSight のセルフプロビジョニング機能が必要な場合は、(QuickSight ユーザーのロールに応じて) CreateReader
CreateUserCreateAdmin アクションの許可ポリシーが必要です。

  1. Name, review, and create ページの Role details に、ロールとして qs-reader-azure と入力します。
  2. Create role を選択します。
  3. ロールの ARN をメモしておきます。

ARN を使用して IAM Identity Center アプリケーションの属性を設定します。

QuickSight アプリケーションでの属性の設定

IAM SAML IdP と IAM ロールを IAM Identity Center の QuickSight アプリケーションに関連付けるには、以下の手順を実行します。

  1. IAM Identity Center コンソールのナビゲーションペインで、Applications を選択します。
  2. Amazon QuickSight アプリケーションを選択し、Actions メニューで Edit attribute mappings を選択します。
  3. Add new attribute mapping を選択します。
  4. 次の表でマッピングを設定します。
User attribute in the application Maps to this string value or user attribute in IAM Identity Center
Subject ${user:email}
https://aws.amazon.com/SAML/Attributes/RoleSessionName ${user:email}
https://aws.amazon.com/SAML/Attributes/Role arn:aws:iam::<ACCOUNTID>:role/qs-reader-azure,arn:aws:iam::<ACCOUNTID>:saml-provider/Azure-IIC-QS
https://aws.amazon.com/SAML/Attributes/PrincipalTag:Email ${user:email}

次の値に注意してください。

  • <ACCOUNTID> をAWS アカウント ID に置き換えてください。
  • PrincipalTag:Email は、QuickSight 管理ページで有効にする必要があるセルフプロビジョニングユーザー向けのメール同期機能用です。この記事では、ユーザーを AWS CLI コマンドで登録するので、この機能を有効にしないでください。
  1. Save changes を選択します。

AWS CLI を使用してユーザー、グループ、およびグループメンバーシップを作成する

前述のように、このソリューションでは QuickSight のユーザーとグループが手動で作成されます。これらを以下の AWS CLI コマンドで作成します。

最初のステップは、以前に作成した IAM ロールと Azure AD に登録されているメールアドレスを指定して QuickSight でユーザーを作成することです。2 番目のステップでは、最初のステップで作成したユーザーのために、Azure AD の属性値を組み合わせた名称でグループを作成します。3 番目のステップは、以前に作成したグループにユーザーを追加することです。member-name は、QuickSight で作成された <IAM Role name>/<session name> で構成されるユーザー名を示します。次のコードを参照してください。

aws quicksight register-user \
--aws-account-id <ACCOUNTID> --namespace default \
--identity-type IAM --email <email registered in Azure AD> \
--user-role READER --iam-arn arn:aws:iam::<ACCOUNTID>:role/qs-reader-azure \
--session-name <email registered in Azure AD>

 aws quicksight create-group \
--aws-account-id <ACCOUNTID> --namespace default \
--group-name Marketing-Specialist

 aws quicksight create-group-membership \
--aws-account-id <ACCOUNTID> --namespace default \
--member-name qs-reader-azure/<email registered in Azure AD> \
–-group-name Marketing-Specialist

この時点で、Azure AD、IAM Identity Center、IAM、および QuickSight のエンドツーエンド構成は完了しています。

IAM Identity Center ポータルから QuickSight にログインして設定を確認します。

これで、IdP が開始する SSO フローを使用して QuickSight にログインする準備ができました。

  1. ブラウザで新しいプライベートウィンドウを開きます。
  2. IAM Identity Center ポータル (https://d-xxxxxxxxxx.awsapps.com/start) にログインします。

Azure AD のログインプロンプトにリダイレクトされます。

  1. Azure AD の認証情報を入力します。

IAM Identity Center ポータルにリダイレクトされます。

  1. IAM Identity Center ポータルで、Amazon QuickSight を選択します。

QuickSight ホームに自動的にリダイレクトされます。

パート II: SCIM イベント発生時のグループメンバーシップ変更の自動化

このセクションでは、更新フローを設定します。

EventBridge の SCIM イベントとイベントパターンを理解する

Azure AD 管理者が特定のユーザープロファイルの属性に変更を加えると、その変更は SCIM プロトコル経由で IAM Identity Center のユーザープロファイルと同期され、アクティビティは sso-directory.amazonaws.com (IAM Identity Center) をイベントソースとして、UpdateUser という名前のイベントで AWS CloudTrail に記録されます。同様に、CreateUser イベントは Azure AD でユーザーが作成されたときに記録され、DisableUser イベントはユーザーが無効になったときに記録されます。

Event history ページの次のスクリーンショットは、2 つの CreateUser イベントを示しています。1 つは IAM Identity Center によって記録され、もう 1 つは QuickSight によって記録されます。この記事では、IAM Identity Center のものを使用します。

EventBridgeがフローを適切に処理できるようにするには、イベントパターンと一致させたいイベントのフィールドを各イベントで指定する必要があります。次のイベントパターンは、SCIM 同期時に IAM Identity Center で生成される UpdateUser イベントの例です。

{
  “source”: [“aws.sso-directory”],
  “detail-type”: [“AWS API Call via CloudTrail”],
  “detail”: {
    “eventSource”: [“sso-directory.amazonaws.com”],
    “eventName”: [“UpdateUser”]
  }
}

この記事では、UpdateUser SCIM イベントによってトリガーされる QuickSight のグループメンバーシップの自動更新について説明します。

グループ名の属性マッピングを作成

Lambda 関数が QuickSight のグループメンバーシップを管理するには、2 つのユーザー属性 (departmentjobTitle) を取得する必要があります。プロセスを簡単にするために、Azure AD の属性マッピング機能を使用して、Azure AD の 2 つの属性 (department, jobTitle) を IAM Identity Center の 1 つの属性 (title) にまとめています。次に、IAM Identity Center は title 属性をこのユーザーの指定グループ名として使用します。

  1. Azure AD コンソールにログインし、Enterprise ApplicationsIIC-QuickSight、および Provisioning に移動します。
  2. Edit attribute mappings を選択します。
  3. Mappings で、Provision Azure Active Directory Users を選択します。
  4. Azure Active Directory Attributes のリストから jobTitle を選択します。
  5. 次の設定を変更します。
    1. Mapping TypeExpression
    2. ExpressionJoin("-", [department], [jobTitle])
    3. Target attributetitle
  6. Save を選択します。
  7. これで、プロビジョニングの設定は完了です。

属性は IAM Identity Center で自動的に更新されます。更新されたユーザープロファイルは、次のスクリーンショットのようになります (最初の図は Azure AD、その次の図が IAM Identity Center)。

Lambda 関数を作成する

次に、SCIM イベント時に QuickSight グループのメンバーシップを更新する Lambda 関数を作成します。この機能の中核となるのは、トリガーされたイベント情報に基づいて IAM Identity Center でユーザーの title 属性値を取得し、そのユーザーが QuickSight に存在することを確認することです。グループ名がまだ存在しない場合は、QuickSight でグループを作成し、ユーザーをグループに追加します。次の手順を実行してください。

  1. Lambda コンソールで、Create function を選択します。
  2. NameUpdateQuickSightUserUponSCIMEvent と入力します。
  3. Runtime には Python 3.9 を選択します。
  4. Time Out には、15 秒に設定します。
  5. Permissions については、以下の権限を含む IAM ロールを作成してアタッチします (信頼できるエンティティ (プリンシパル) は lambda.amazonaws.com でなければなりません)。
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "MinimalPrivForScimQsBlog",
                "Effect": "Allow",
                "Action": [
                    "identitystore:DescribeUser",
                    "quicksight:RegisterUser",
                    "quicksight:DescribeUser",
                    "quicksight:CreateGroup",
                    "quicksight:DeleteGroup",
                    "quicksight:DescribeGroup",
                    "quicksight:ListUserGroups",
                    "quicksight:CreateGroupMembership",
                    "quicksight:DeleteGroupMembership",
                    "quicksight:DescribeGroupMembership",
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "*"
            }
        ]
    }
  6. IdentityStoreQuickSight 用の Boto3 SDK を使用して Python コードを記述します。以下はサンプルの Python コード全体です。
import sys
import boto3
import json
import logging
from time import strftime
from datetime import datetime

# Set logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
  '''
  Modify QuickSight group membership upon SCIM event from IAM Identity Center originated from Azure AD.
  It works in this way:
    Azure AD -> SCIM -> Identity Center -> CloudTrail -> EventBridge -> Lambda -> QuickSight
  Note that this is a straightforward sample to show how to update QuickSight group membership upon certain SCIM event.
  For example, it assumes that 1:1 user-to-group assigmnent, only one (combined) SAML attribute, etc. 
  For production, take customer requirements into account and develop your own code.
  '''

  # Setting variables (hard-coded. get dynamically for production code)
  qs_namespace_name = 'default'
  qs_iam_role = 'qs-reader-azure'

  # Obtain account ID and region
  account_id = boto3.client('sts').get_caller_identity()['Account']
  region = boto3.session.Session().region_name

  # Setup clients
  qs = boto3.client('quicksight')
  iic = boto3.client('identitystore')

  # Check boto3 version
  logger.debug(f"## Your boto3 version: {boto3.__version__}")

  # Get user info from event data
  event_json = json.dumps(event)
  logger.debug(f"## Event: {event_json}")
  iic_store_id = event['detail']['requestParameters']['identityStoreId']
  iic_user_id = event['detail']['requestParameters']['userId']  # For UpdateUser event, userId is provided through requestParameters
  logger.info("## Getting user info from Identity Store.")
  try:
    res_iic_describe_user = iic.describe_user(
      IdentityStoreId = iic_store_id,
      UserId = iic_user_id
    )
  except Exception as e:
    logger.error("## Operation failed due to unknown error. Exiting.")
    logger.error(e)
    sys.exit()
  else:
    logger.info(f"## User info retrieval succeeded.")
    azure_user_attribute_title = res_iic_describe_user['Title']
    azure_user_attribute_userprincipalname = res_iic_describe_user['UserName']
    qs_user_name = qs_iam_role + "/" + azure_user_attribute_userprincipalname
    logger.info(f"#### Identity Center user name: {azure_user_attribute_userprincipalname}")
    logger.info(f"#### QuickSight group name desired: {azure_user_attribute_title}")
    logger.debug(f"#### res_iic_describe_user: {json.dumps(res_iic_describe_user)}, which is {type(res_iic_describe_user)}")

  # Exit if user is not present since this function is supposed to be called by UpdateUser event
  try:
    # Get QuickSight user name
    res_qs_describe_user = qs.describe_user(
      UserName = qs_user_name,
      AwsAccountId = account_id,
      Namespace = qs_namespace_name
    )
  except qs.exceptions.ResourceNotFoundException as e:
    logger.error(f"## User {qs_user_name} is not found in QuickSight.")
    logger.error(f"## Make sure the QuickSight user has been created in advance. Exiting.")
    logger.error(e)
    sys.exit()
  except Exception as e:
    logger.error("## Operation failed due to unknown error. Exiting.")
    logger.error(e)
    sys.exit()
  else:
    logger.info(f"## User {qs_user_name} is found in QuickSight.")

  # Remove current membership unless it's the desired one
  qs_new_group = azure_user_attribute_title  # Set "Title" SAML attribute as the desired QuickSight group name
  in_desired_group = False  # Set this flag True when the user is already a member of the desired group
  logger.info(f"## Starting group membership removal.")
  try:
    res_qs_list_user_groups = qs.list_user_groups(
      UserName = qs_user_name,
      AwsAccountId = account_id,
      Namespace = qs_namespace_name
    )
  except Exception as e:
    logger.error("## Operation failed due to unknown error. Exiting.")
    logger.error(e)
    sys.exit()
  else:
    # Skip if the array is empty (user is not member of any groups)
    if not res_qs_list_user_groups['GroupList']:
      logger.info(f"## User {qs_user_name} is not a member of any QuickSight group. Skipping removal.")
    else:
      for grp in res_qs_list_user_groups['GroupList']:
        qs_current_group = grp['GroupName']
        # Retain membership if the new and existing group names match
        if qs_current_group == qs_new_group:
          logger.info(f"## The user {qs_user_name} already belong to the desired group. Skipping removal.")
          in_desired_group = True
        else:
          # Remove all unnecessary memberships
          logger.info(f"## Removing user {qs_user_name} from existing group {qs_current_group}.")
          try:
            res_qs_delete_group_membership = qs.delete_group_membership(
              MemberName = qs_user_name,
              GroupName = qs_current_group,
              AwsAccountId = account_id,
              Namespace = qs_namespace_name
            )
          except Exception as e:
            logger.error(f"## Operation failed due to unknown error. Exiting.")
            logger.error(e)
            sys.exit()
          else:
            logger.info(f"## The user {qs_user_name} has removed from {qs_current_group}.")

  # Create group membership based on IIC attribute "Title"
  logger.info(f"## Starting group membership assignment.")
  if in_desired_group is True:
      logger.info(f"## The user already belongs to the desired one. Skipping assignment.")
  else:
    try:
      logger.info(f"## Checking if the desired group exists.")
      res_qs_describe_group = qs.describe_group(
        GroupName = qs_new_group,
        AwsAccountId = account_id,
        Namespace = qs_namespace_name
      )
    except qs.exceptions.ResourceNotFoundException as e:
      # Create a QuickSight group if not present
      logger.info(f"## Group {qs_new_group} is not present. Creating.")
      today = datetime.now()
      res_qs_create_group = qs.create_group(
        GroupName = qs_new_group,
        Description = 'Automatically created at ' + today.strftime('%Y.%m.%d %H:%M:%S'),
        AwsAccountId = account_id,
        Namespace = qs_namespace_name
      )
    except Exception as e:
      logger.error(f"## Operation failed due to unknown error. Exiting.")
      logger.error(e)
      sys.exit()
    else:
      logger.info(f"## Group {qs_new_group} is found in QuickSight.")

    # Add the user to the desired group
    logger.info("## Modifying group membership based on its latest attributes.")
    logger.info(f"#### QuickSight user name: {qs_user_name}")
    logger.info(f"#### QuickSight group name: {qs_new_group}")
    try: 
      res_qs_create_group_membership = qs.create_group_membership(
        MemberName = qs_user_name,
        GroupName = qs_new_group,
        AwsAccountId = account_id,
        Namespace = qs_namespace_name
    )
    except Exception as e:
      logger.error("## Operation failed due to unknown error. Exiting.")
      logger.error(e)
    else:
      logger.info("## Group membership modification succeeded.")
      qs_group_member_name = res_qs_create_group_membership['GroupMember']['MemberName']
      qs_group_member_arn = res_qs_create_group_membership['GroupMember']['Arn']
      logger.debug("## QuickSight group info:")
      logger.debug(f"#### qs_user_name: {qs_user_name}")
      logger.debug(f"#### qs_group_name: {qs_new_group}")
      logger.debug(f"#### qs_group_member_name: {qs_group_member_name}")
      logger.debug(f"#### qs_group_member_arn: {qs_group_member_arn}")
      logger.debug("## IIC info:")
      logger.debug(f"#### IIC user name: {azure_user_attribute_userprincipalname}")
      logger.debug(f"#### IIC user id: {iic_user_id}")
      logger.debug(f"#### Title: {azure_user_attribute_title}")
      logger.info(f"## User {qs_user_name} has been successfully added to the group {qs_new_group} in {qs_namespace_name} namespace.")
  
  # return response
  return {
    "namespaceName": qs_namespace_name,
    "userName": qs_user_name,
    "groupName": qs_new_group
  }

この Lambda 関数には Boto3 1.24.64 以降が必要であることに注意してください。Lambda runtime に含まれている Boto3 がこれより古い場合は、Lambda レイヤーを使用して Boto3 の最新バージョンを使用してください。詳細については、How do I resolve “unknown service”, “parameter validation failed”, and “object has no attribute” errors from a Python (Boto 3) Lambda function を参照してください。

イベントをトリガーする EventBridge ルールの追加

以前に作成した Lambda 関数を呼び出すための EventBridge ルールを作成するには、以下の手順を実行します。

  1. EventBridge コンソールで、新しいルールを作成します。
  2. NameupdateQuickSightUponSCIMEvent と入力します。
  3. Event pattern には、次のコードを入力します。
    {
      "source": ["aws.sso-directory"],
      "detail-type": ["AWS API Call via CloudTrail"],
      "detail": {
        "eventSource": ["sso-directory.amazonaws.com"],
        "eventName": ["UpdateUser"]
      }
    }
  4. Targets については、作成した Lambda 関数 (UpdateQuickSightUserUponSCIMEvent) を選択します。
  5. ルールを有効にします。

Azure AD のユーザー属性値を変更して構成を確認

Azure AD でユーザーの属性を変更し、新しいグループが作成され、そのユーザーが新しいグループに追加されているかどうかを確認してみましょう。

  1. Azure AD コンソールに戻ってください。
  2. Manage から Users をクリックします。
  3. 以前に IAM Identity Center ポータルから QuickSight へのログインに使用したユーザーを 1 人選択します。
  4. Edit properties を選択し、Job titleDepartment の値を編集します。
  5. 設定を保存します。
  6. Manage から、Enterprise application、自身のアプリケーション名、Provisioning を選択します。
  7. Stop provisioning を選択し、次に Start provisioning を順番に選択します。

Azure AD では、SCIM のプロビジョニング間隔は 40 分に固定されています。すぐに結果を得るために、プロビジョニングを手動で停止して開始します。

  1. QuickSight コンソールに移動します。
  2. ドロップダウンユーザー名メニューで、Manage QuickSight を選択します。
  3. Manage groups を選択します。

これで、新しいグループが作成され、ユーザーがこのグループに割り当てられていることがわかります。

クリーンアップ

ソリューションを使い終わったら、環境をクリーンアップしてコストへの影響を最小限に抑えます。次のリソースを削除したい場合があります。

  • Lambda 関数
  • Lambda レイヤー
  • Lambda 関数用の IAM ロール
  • Lambda 関数用の CloudWatch ロググループ
  • EventBridge ルール
  • QuickSight アカウント
    • : AWS アカウントごとに作成できる QuickSight アカウントは 1 つだけです。そのため、QuickSight アカウントは組織内の他のユーザーによって既に使用されている可能性があります。QuickSight アカウントを削除するのは、このブログをフォローするように明示的に設定していて、他のユーザーがそのアカウントを使用していないことが確実である場合だけにしてください。
  • IAM Identity Center インスタンス
  • Azure AD 用の IAM ID Provider 設定
  • Azure AD インスタンス

サマリー

この記事では、QuickSight ユーザーを一元管理するために IAM Identity Center SCIM プロビジョニングと Azure AD から SAML 2.0 フェデレーションを設定する手順を段階的に説明しました。また、IAM Identity Center で生成された SCIM イベントを使用し、EventBridge と Lambda を使用して自動化を設定することで、Azure AD のユーザー属性に基づいて QuickSight でグループメンバーシップを自動的に更新するデモも行いました。

QuickSight でユーザーとグループをプロビジョニングするこのイベントドリブンアプローチにより、システム管理者は組織に応じてさまざまなユーザー管理方法を柔軟に決定できます。また、ユーザーがいつ QuickSight にアクセスしても、QuickSight と Azure AD 間でユーザーとグループの整合性が保たれます。

Quicksight のコミュニティに参加して、他のユーザーと一緒に質問したり、回答したり、学んだり、その他のリソースを調べたりしてみてください。


翻訳はソリューションアーキテクト 溝渕 匡 が担当しました。原文はこちらです。