AWS WorkSpaces may not be in direct competition with Citrix and VMware at the moment, but the service is growing. However, one of the main limitations in WorkSpaces is the lack of a non-persistent option. At the moment, each WorkSpace (guest VM) is assigned to a unique user. The assignment is 1:1 only, meaning desktop pools with dynamic assignment aren’t possible. However, the forced 1:1 assignment doesn’t neccessarily mean that all WorkSpaces can only be persistent. Rather, there’s no built-in functionality to rebuild the desktop when the user has logged out.
Using a combination of CloudWatch, SNS, and Lambda, I created a serverless process that automatically reverts a WorkSpace to its original image once a user either disconnects or logs out of their assigned WorkSpace. Here’s the high-level process diagram:
If you want to set this up, here are the details:
First, create a SNS topic that you’ll use to send out notifications from CloudWatch.
Next, create a CloudWatch alarm. CloudWatch has built-in metrics for WorkSpaces and one of the metrics is “SessionDisconnect” which returns the number of closed/failed connections in a given time period. A full list of CloudWatch metrics for WorkSpaces is here.
To create the Alarm, select the metric by WorkSpace ID.
Select the SessionDisconnect metric.
Set the criteria as needed.
Finally, select the SNS topic that you’ve already created for the notification.
Once the CloudWatch alarm is in place, it’s time for the fun part: Lambda. First, Lambda needs an IAM role to access other AWS services. Create an IAM role that will be used by Lambda to issue calls to the WorkSpaces API. The policies below allow full access to both WorkSpaces and CloudWatch and can probably be more restrictive if needed.
Create a new Lambda function with a unique name, set the runtime to Python 2.7, and use the existing IAM role.
The code for the Lambda function is triggered by the SNS notification held in the event object within the function. The function extracts the WorkSpace ID for the disconnected WorkSpace from the event object and then uses the boto3 library to issue a WorkSpaces API call. The boto3 documentation for WorkSpaces (really useful) is here. The Python script is also available from my GitHub repository here.
import boto3
import json
def lambda_handler(event, context):
workspaces_client = boto3.client('workspaces')
message_data = event['Records'][0]['Sns']['Message']
message_json = json.loads(message_data)
workspaceId = message_json.get('Trigger', {}).get('Dimensions', [{}])[0].get('value')
workspaces_client.rebuild_workspaces(
RebuildWorkspaceRequests=[
{
'WorkspaceId': workspaceId
},
]
)
return 'Workspace ' + workspaceId + ' is being rebuilt.'
Once the Lambda function is in place, logoff of the WorkSpace. If it’s setup properly, the WorkSpace will automatically rebuild to the latest AMI.