Automate your Amazon WorkSpaces Personal Entra ID join deployment
In this article, we show how to automate Amazon WorkSpaces Personal provisioning by using Microsoft Entra ID group membership as the single control plane, synchronized to AWS via SCIM and reconciled by a scheduled Lambda function. The result is a hands-off workflow where adding or removing a user from an Entra ID group automatically creates or terminates their Amazon WorkSpace - no AWS console interaction required.
Introduction
Organizations adopting Amazon WorkSpaces Personal with Microsoft Entra ID join face a common operational challenge: manually provisioning WorkSpaces for every user is tedious, error-prone, and doesn't scale. What if adding a user to an Entra ID group was all it took to trigger a fully automated WorkSpaces deployment? with no access to AWS Console?
In this post, we walk through a solution that bridges Microsoft Entra ID group membership with Amazon WorkSpaces provisioning using AWS IAM Identity Center (SCIM synchronization) and an AWS Lambda function. The result is a hands-off, event-driven workflow: add a user to a group in Entra ID, and a WorkSpace is automatically created for them. Remove the user, and the WorkSpace is cleaned up.
Before diving into the automation, let's review the prerequisites for running Entra ID-joined WorkSpaces - because the automation only works when the foundation is solid.
Goal
The objective is simple: reduce the Entra ID administrator's workflow to a single action - adding a user to a group.
Today, provisioning an Entra ID-joined WorkSpace involves multiple manual steps across both Microsoft and AWS consoles. The administrator must ensure the user is synced to IAM Identity Center, navigate to the WorkSpaces console, select the right directory and bundle, and launch the WorkSpace. Multiply that by dozens or hundreds of users, and it becomes a significant operational burden.
With this solution, the administrator's only responsibility is managing group membership in Microsoft Entra ID. Everything downstream is automated:
- Add a user to the designated Entra ID group → a WorkSpace is automatically provisioned for them.
- Remove a user from the group → their WorkSpace is automatically terminated.
No AWS console interaction required. No tickets. No manual provisioning steps. The Entra ID group becomes the single control plane, and the administrator stays in the tool they already know - Microsoft Entra ID.
This is especially valuable for organizations where the identity team (managing Entra ID) and the cloud infrastructure team (managing AWS) are separate. The identity team can onboard and offboard users without needing AWS access or knowledge, while the infrastructure team maintains the automation pipeline.
Prerequisites: Entra ID-joined WorkSpaces
Launching Entra ID-joined personal WorkSpaces requires a specific set of configurations across both AWS and Microsoft environments. These are documented in the AWS WorkSpaces Admin Guide , and we summarize the key requirements here.
Microsoft side
- Microsoft Entra ID P1 plan or higher - required for group-based features and conditional access.
- Microsoft Intune enabled - WorkSpaces use Windows Autopilot user-driven mode for Entra join and Intune enrollment.
- Role assignments:
- Intune Administrator - to manage Autopilot deployment profiles.
- Global Administrator - to grant admin consent for the API permissions on the registered Entra ID application.
- Windows 11 VDA E3 or E5 user subscription licenses assigned to each WorkSpaces user.
- A registered Entra ID application with the correct Microsoft Graph API permissions for Windows Autopilot.
- A Windows Autopilot deployment profile configured in user-driven mode.
AWS side
- Bring Your Own License (BYOL) enabled on your AWS account with a valid Windows 11 BYOL image imported. Entra ID directories only support BYOL WorkSpaces.
- Supported OS versions: Windows 11 Enterprise (22H2, 23H2, 24H2, 25H2).
- DCV protocol only - Entra ID directories do not support PCoIP.
- AWS Secrets Manager secret containing the Entra ID Application ID and password.
- IAM Identity Center enabled and synchronized with your Entra ID tenant via SCIM.
- A dedicated WorkSpaces directory of type Microsoft Entra ID, linked to your IAM Identity Center instance and Entra tenant.
- Network connectivity - subnets must have internet access, and firewalls must allow outbound traffic to Microsoft Intune endpoints and Windows Autopilot endpoints .
Important limitations
- UPNs (UserPrincipalName) cannot exceed 63 characters. Changing a UPN after WorkSpace assignment breaks connectivity.
- Government Community Cloud High (GCCH) and DoD Entra ID tenants are not supported.
- The WorkSpaces directory name must match the
OrderIDused in the Autopilot dynamic device group query.
> Tip: Complete all five steps in the official guide - from enabling IAM Identity Center through creating the Entra ID WorkSpaces directory - before implementing the automation described below.
Solution overview
The automation relies on three pillars:
- Microsoft Entra ID - the source of truth for user identity and group membership.
- AWS IAM Identity Center (SCIM) - the bridge that synchronizes Entra ID users and groups into AWS.
- AWS Lambda - the engine that reconciles group membership with WorkSpaces state.
How it works

The flow is straightforward:
- An administrator (or an automated process) adds a user to a designated Entra ID group.
- SCIM provisioning between Entra ID and IAM Identity Center synchronizes the group membership into the IAM Identity Center Identity Store.
- An Amazon EventBridge rule triggers an AWS Lambda function on a schedule (e.g., every hour).
- The Lambda function:
- Lists group members from the Identity Store.
- Describes existing WorkSpaces in the target directory.
- Compares the two sets.
- Creates WorkSpaces for users in the group who don't have one.
- Terminates WorkSpaces for users no longer in the group.
This creates a closed-loop system: group membership is the single control plane for WorkSpaces lifecycle.
Deep dive: the SCIM synchronization layer
Before the Lambda function can do its job, users and groups must be visible in AWS. This is where SCIM (System for Cross-domain Identity Management) comes in.
Setting up SCIM between Entra ID and IAM Identity Center
- Enable IAM Identity Center in the same Region as your WorkSpaces directory (or configure cross-Region integration).
- Configure automatic provisioning in Microsoft Entra ID by following the Microsoft tutorial for IAM Identity Center SCIM provisioning .
- Scope the synchronization - you can sync all users or only users assigned to specific groups. For this solution, ensure the target group and its members are in scope.
- Verify synchronization - confirm that users appear in the IAM Identity Center Identity Store with correct attributes (first name, last name, display name, UPN).
What gets synchronized
| Entra ID Object | IAM Identity Center Object | Key Attribute |
|---|---|---|
| User | Identity Store User | UserName (mapped from UPN) |
| Group | Identity Store Group | GroupId |
| Group Membership | Group Membership | MemberId → UserId |
The Lambda function queries the Identity Store group memberships - not Entra ID directly. This keeps the solution entirely within AWS and avoids the need for Microsoft Graph API credentials in the Lambda.
Deep dive: the automation logic
The Lambda function is the core of the automation. It runs on a schedule and performs a reconciliation loop. Let's break down the approach.
The reconciliation pattern
The function follows a simple but effective pattern: desired state vs. actual state.
- Desired state = the set of users in the Identity Store group (synced from Entra ID).
- Actual state = the set of users who currently have a WorkSpace in the target directory.
On each invocation, the function computes the difference and acts on it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
┌─────────────────────────────────────────────┐
│ Scheduled Invocation │
└──────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 1. Query Identity Store │
│ List all members of the target group │
│ Resolve each member to a UserName (UPN) │
│ → Result: desired_users │
└──────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 2. Query WorkSpaces │
│ List all WorkSpaces in the directory │
│ Extract UserName from each WorkSpace │
│ → Result: actual_users │
└──────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 3. Reconcile │
│ to_create = desired_users - actual_users│
│ to_remove = actual_users - desired_users│
└──────────────────┬──────────────────────────┘
│
┌────────┴────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Create WS for │ │ Terminate WS │
│ new members │ │ for removed │
│ (batch of 25) │ │ members │
└──────────────────┘ └──────────────────┘Step 1 - Resolve group members
The function needs to answer: who should have a WorkSpace?
- Call
ListGroupMembershipson the Identity Store to enumerate all members of the target group. - For each membership, extract the
UserId. - Call
DescribeUserto resolve eachUserIdto aUserName(the UPN synced from Entra ID). - Collect all resolved
UserNamevalues into a set - this is the desired state. - Handle pagination - groups can have hundreds of members, and the API returns results in pages.
Here is an example of how to list group memberships and resolve usernames:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# List all members of the target group
idc_paginator = idc_client.get_paginator('list_group_memberships')
for result in idc_paginator.paginate(
IdentityStoreId=store_id, GroupId=target_group_id
):
for entry in result['GroupMemberships']:
member_id = entry['MemberId']['UserId']
# Resolve member ID to UserName (UPN)
member_detail = idc_client.describe_user(
IdentityStoreId=store_id, UserId=member_id
)
expected_users.add(member_detail['UserName'])Step 2 - Inventory existing WorkSpaces
Next, the function answers: who already has a WorkSpace?
- Call
DescribeWorkspacesfiltered by the target directory ID. - Extract the
UserNameandWorkspaceIdfrom each WorkSpace object. - Collect all
UserNamevalues into a set - this is the actual state. - Handle pagination for large directories.
1
2
3
4
5
6
# List all existing WorkSpaces in the Entra ID directory
ws_paginator = ws_client.get_paginator('describe_workspaces')
for result in ws_paginator.paginate(DirectoryId=ws_directory_id):
for item in result['Workspaces']:
current_users[item['UserName']] = item['WorkspaceId']Step 3 - Compare and act
With both sets in hand, the reconciliation is a straightforward set difference:
- Compute
users_to_provision= users in the group who don't have a WorkSpace yet. - Compute
users_to_deprovision= users with a WorkSpace who are no longer in the group.
1
2
3
# Set comparison - the core of the reconciliation
users_to_provision = expected_users - set(current_users.keys())
users_to_deprovision = set(current_users.keys()) - expected_usersStep 4 - Provision and clean up
- Create WorkSpaces for each user in
users_to_provision, batching up to 25 per API call. - Terminate WorkSpaces for each user in
users_to_deprovision, batching up to 25 per API call.
1
2
3
4
5
6
7
8
9
10
11
12
# Batch create WorkSpaces for new group members
provision_requests = [{
'DirectoryId': ws_directory_id,
'UserName': upn,
'BundleId': ws_bundle_id,
'WorkspaceProperties': {
'RunningMode': 'AUTO_STOP',
'RunningModeAutoStopTimeoutInMinutes': 60
}
} for upn in chunk]
result = ws_client.create_workspaces(Workspaces=provision_requests)1
2
3
4
5
6
7
8
9
# Batch terminate WorkSpaces for removed members
deprovision_requests = [
{'WorkspaceId': current_users[upn]}
for upn in users_to_deprovision
]
result = ws_client.terminate_workspaces(
TerminateWorkspaceRequests=deprovision_requests
)When creating a WorkSpace, the function specifies:
- The directory ID - the Entra ID-joined directory.
- The bundle ID - the BYOL Windows image.
- The UserName - the UPN from the Identity Store.
- A running mode - for example,
AUTO_STOPwith a timeout, to control costs for intermittent users.
Required IAM permissions
The Lambda execution role needs a focused set of permissions:
| Permission | Purpose |
|---|---|
identitystore:ListGroupMemberships | Enumerate group members |
identitystore:DescribeUser | Resolve UserId to UserName |
workspaces:DescribeWorkspaces | List existing WorkSpaces |
workspaces:CreateWorkspaces | Provision new WorkSpaces |
workspaces:TerminateWorkspaces | Clean up removed users |
No admin-level permissions are needed. The role follows least privilege.
Scheduling
An Amazon EventBridge rule triggers the Lambda on a configurable schedule. The default recommendation is once per hour, which accounts for the SCIM synchronization delay (Entra ID SCIM provisioning can take up to 40 minutes to propagate changes to IAM Identity Center).
For faster provisioning, you can reduce the interval - but be mindful of API throttling at scale.
Operational considerations
SCIM sync delay
The end-to-end time from "user added to Entra ID group" to "WorkSpace available" depends on two factors:
- SCIM propagation - typically 20–40 minutes for Entra ID to push the change to IAM Identity Center.
- Lambda schedule - the next scheduled invocation after the SCIM sync completes.
- WorkSpace provisioning - creating an Entra ID-joined WorkSpace takes additional time for Autopilot enrollment.
In practice, expect roughly 1–2 hours end-to-end with a 1-hour schedule.
Error handling
In a production deployment, consider:
- Logging failed requests - the
CreateWorkspacesAPI returns aFailedRequestsarray. Log these to Amazon CloudWatch for visibility. - Alerting - send notifications via Amazon SNS when provisioning failures occur.
- UPN mismatches - if a user's UPN doesn't match between Entra ID and the Identity Store, WorkSpace creation will fail silently for that user. Validate SCIM sync health regularly.
Cost implications
- Each WorkSpace incurs hourly or monthly charges depending on the running mode.
AUTO_STOPmode helps control costs for intermittent users. - The Lambda function itself costs fractions of a cent per invocation at this scale.
- EventBridge rules are free for scheduled expressions.
Security
- The Lambda IAM role follows least privilege - only the five permissions listed above.
- No Microsoft credentials are stored or used in the Lambda. All identity data comes from the IAM Identity Center Identity Store, populated via SCIM.
- The solution operates entirely within AWS boundaries after the initial SCIM sync.
Summary
By combining Microsoft Entra ID group management, SCIM synchronization to IAM Identity Center, and a scheduled Lambda function, you can fully automate the lifecycle of Entra ID-joined Amazon WorkSpaces Personal. The group becomes the single source of truth: add a user, they get a WorkSpace; remove them, it's cleaned up.
This approach reduces manual effort, minimizes provisioning errors, and scales naturally with your organization.
Ideas for extension
- Multi-group mapping - support multiple Entra ID groups, each mapped to a different WorkSpaces bundle or directory, enabling tiered offerings (e.g., standard vs. power users).
- Notifications - integrate Amazon SNS to alert administrators on provisioning events, failures, or capacity thresholds.
- Near-real-time provisioning - instead of polling on a schedule, explore using Amazon EventBridge with IAM Identity Center events to trigger the Lambda closer to real time.
- Self-service integration - combine with AWS Service Catalog to let users request group membership through an approval workflow.
- Tagging and reporting - tag WorkSpaces with metadata (group name, provisioning date) for cost allocation and audit trails.
For the full prerequisites and step-by-step Entra ID directory setup, see Create a dedicated Microsoft Entra ID directory with WorkSpaces Personal .
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article