AWS Builder Center

WorkSpaces Pulse: Automate Inventory and Health Reporting for Amazon WorkSpaces Personal

This article shows how to deploy WorkSpaces Pulse — a serverless solution that automatically scans your entire WorkSpaces fleet and generates a comprehensive inventory and health report with actionable recommendations organised by AWS Well-Architected pillars.

Amazon WorkSpaces Personal provides a managed desktop-as-a-service solution, but as fleets scale, maintaining visibility into fleet health, cost efficiency, security posture, and capacity becomes increasingly difficult. Administrators often lack a consolidated view across multiple regions and directories.
This article shows how to deploy WorkSpaces Pulse — a serverless solution that automatically scans your entire WorkSpaces fleet and generates a comprehensive inventory and health report with actionable recommendations organized by AWS Well-Architected pillars - Security, Reliability, Cost Optimization, Performance Efficiency, and Operational Excellence..
Each run produces a downloadable CSV inventory of every WorkSpace across all regions and an email summary with findings and recommended actions. Administrators can use these outputs to identify cost optimization gaps, security compliance issues, capacity risks, and operational inefficiencies before they impact users or budgets.
WorkSpaces Pulse doesn't replace your existing observability tools — it complements them. CloudWatch dashboards  provide real-time operational monitoring, and the End User Computing Well-Architected Lens  provides architectural best-practice guidance. WorkSpaces Pulse bridges that gap: a periodic, fleet-wide health assessment that surfaces actionable findings — delivered as an email you can act on immediately or share with stakeholders.

How it works

A Lambda function runs on a configurable schedule via EventBridge (weekly by default). It scans all WorkSpaces regions, collecting detailed metadata for each WorkSpace.
The function then evaluates the fleet against a set of best-practice checks aligned to AWS Well-Architected pillars, generating findings and recommendations. It uploads a full CSV inventory to S3 and sends an email summary via SMTP or Amazon SNS.

Components

  • Lambda - Core reporting logic
  • EventBridge - Weekly schedule trigger (default: Mondays at 6 AM UTC)
  • S3 - Stores CSV reports with 90-day lifecycle retention
  • CloudWatch - Logs, plus a failure alarm on the Lambda
  • SMTP (recommended, optional) - Delivers full HTML email with styled tables and color-coded findings
  • SNS - Delivers plain-text email notifications

What it reports

Findings are organized under AWS Well-Architected  pillars. Pillars with no findings are omitted from the report, and each pillar shows a finding count with recommended actions.

Summary statistics

Every report opens with a fleet-wide summary: total WorkSpaces and directories, inactive and active-user counts, connection health, running-mode / OS / protocol and AZ composition, WorkSpace age, encryption status, and more.

Security

  • Unencrypted volumes (root and user)
  • Directories with ineffective IP access controls (no group attached or group with no rules)
  • Directories allowing clients that bypass trusted-device certificate controls
  • Directories without effective MFA (no RADIUS, RADIUS failed, or Simple AD without SAML)
  • Directories without client-side LDAPS encryption
  • WorkSpaces security groups with open inbound (0.0.0.0/0)
  • Trusted-device certificate expiry (CRITICAL <30 days / WARNING <90 days)
  • Internet egress path per subnet and WorkSpaces in public subnets

Reliability

  • WorkSpaces in ERROR, UNHEALTHY, or MAINTENANCE state
  • Recently rebuilt or restored WorkSpaces (last 30 days)
  • Undersized volumes (>80% used)
  • Directories with WorkSpaces in a single AZ (no AZ spread)
  • Capacity planning: usage vs. quotas with per-directory breakdown
  • Subnet exhaustion (>90% IP addresses used)
  • Directories without cross-region redirection (DR posture)

Cost Optimization

  • Inactive WorkSpaces (30+ / 60+ / 90+ days)
  • AlwaysOn WorkSpaces inactive 7+ days or 90+ days
  • AutoStop candidates (AlwaysOn, inactive 30+ days)
  • AutoStop WorkSpaces with long timeout (> 60 min — billing continues after disconnect)
  • Never-connected WorkSpaces older than 30 days
  • Oversized volumes (<20% used)
  • Orphaned directories (no WorkSpaces, still incurring cost)

Performance Efficiency

  • High round-trip time (>200 ms)
  • UDP packet loss (>5%)
  • Connection failures
  • Slow session launch (>60 seconds)

Operational Excellence

  • Outdated bundles (WorkSpace older than bundle update)
  • Stale bundles (>365 days old)
  • Directories without maintenance mode enabled

CSV Report:


How to deploy

The steps below use the AWS CLI, but you can also deploy the stack through the AWS CloudFormation console by uploading the template and entering the parameters
Before you begin, ensure you have an S3 bucket to host the Lambda deployment ZIP.
Download the CloudFormation template WorkspacesPulse.yml and Lambda code workspaces-pulse.zip from the GitHub repository: https://github.com/aws-samples/sample-workspacespulse 
Upload the ZIP to your S3 bucket:
aws s3 cp workspaces-pulse.zip s3://YOUR_BUCKET/workspaces-pulse.zip
(SMTP only) Store your SMTP credentials in AWS Secrets Manager:
1
2
3
4
aws secretsmanager create-secret \
--name WorkSpacesPulse/smtp-creds \
--secret-string '{"username":"YOUR_SMTP_USERNAME","password":"YOUR_SMTP_PASSWORD"}' \
--region {{region}}
To update an existing secret:
1
2
3
4
aws secretsmanager put-secret-value \
--secret-id WorkSpacesPulse/smtp-creds \
--secret-string '{"username":"YOUR_SMTP_USERNAME","password":"YOUR_SMTP_PASSWORD"}' \
--region {{region}}
Deploy the CloudFormation stack:
1
2
3
4
5
6
7
8
9
10
11
12
aws cloudformation deploy \
--stack-name WorkSpacesPulse \
--template-file WorkSpacesPulse.yml \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
NotificationEmail=your@example.com \
LambdaZipS3Bucket=YOUR_BUCKET \
NotificationType=SMTP \
SmtpHost=smtp.example.com \
SmtpPort=587 \
SmtpPasswordArn=arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:WorkSpacesPulse/smtp-creds-XXXXXX \
MailFrom=noreply@example.com
If using SNS confirm the SNS subscription email you receive.

Stack parameters

ParameterRequiredDefaultDescription
NotificationEmailYes—Email for notifications
LambdaZipS3BucketYes—S3 bucket containing the Lambda ZIP
LambdaZipS3KeyNoworkspaces-pulse.zipS3 key of the Lambda ZIP
SnsTopicArnNoauto-createdName of an existing SNS topic ARN to publish to; leave blank to auto-create one
S3BucketNameNoauto-createdName of an existing S3 bucket to store reports; leave blank to auto-create one
ScheduleExpressionNocron(0 6 ? * MON *)EventBridge schedule (default: Mondays at 6:00 AM UTC)
NotificationTypeNoSMTPSNS, SMTP, or BOTH
SmtpHostNo—SMTP server hostname
SmtpPortNo587SMTP server port
SmtpPasswordArnNo—Secrets Manager ARN for SMTP credentials
MailFromNo—Sender email for SMTP
VpcSubnetIdsNo—Subnet IDs for VPC access (private SMTP)
VpcSecurityGroupIdsNo—Security group IDs for VPC access

Permissions

The CloudFormation template creates an IAM role with read-only access to WorkSpaces, EC2, Directory Service, CloudWatch, CloudTrail, Service Quotas, and SSM, plus write access to the S3 report bucket and SNS topic. No administrative or mutating permissions to WorkSpaces are granted.

Generating on-demand reports

Invoke the Lambda manually for an immediate report:
1
2
3
4
5
6
7
8
9
10
11
12
13
# All regions (default)
aws lambda invoke --function-name WorkSpacesPulse-Report \
--cli-binary-format raw-in-base64-out --payload '{}' /dev/stdout

# Specific regions only
aws lambda invoke --function-name WorkSpacesPulse-Report \
--cli-binary-format raw-in-base64-out \
--payload '{"regions": ["us-east-1", "eu-west-1"]}' /dev/stdout

# Override notification type
aws lambda invoke --function-name WorkSpacesPulse-Report \
--cli-binary-format raw-in-base64-out \
--payload '{"notification_type": "SMTP"}' /dev/stdout

Notification options

SMTP (recommended): Full HTML email with styled tables, color-coded findings grouped by Well-Architected pillar, and embedded recommended actions. Requires SMTP server details and credentials in Secrets Manager.
SNS: Plain-text summary delivered via SNS email subscription. No additional configuration needed, but limited formatting.
BOTH: Sends both SNS and SMTP notifications.

Common SMTP provider settings

ProviderHostPortUsernamePassword
Amazon SESemail-smtp.{{region}}.amazonaws.com587IAM SMTP credential Access KeySES-generated SMTP password
Microsoft 365smtp.office365.com587user@company.comAccount or app password
Exchange On-Premmail.company.com or smtp.company.com25 or 587DOMAIN\usernameService account password
Google Workspacesmtp.gmail.com587user@company.comApp password (16-char)

SMTP on a private network

If your SMTP server is on a private network (e.g., corporate Exchange relay):
  1. Provide VpcSubnetIds and VpcSecurityGroupIds parameters
  2. Ensure the subnets have a route to the SMTP server
  3. Ensure the Lambda can reach AWS APIs via NAT Gateway or VPC Endpoints
  4. Security group must allow outbound traffic to the SMTP port

Cost

The solution costs approximately $0.50/month running weekly against ~3,500 WorkSpaces.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article