Desktop and Application Streaming

Automatically create customized Amazon WorkSpaces Windows images

Customers often ask how to streamline the management and maintenance of their Amazon WorkSpaces and Amazon WorkSpaces Core images and bundles. The WorkSpaces service includes a rich set of API operations to programmatically interact with the service. A common customer struggle is remotely interacting with the operating system within the WorkSpace to install and configure applications and customize their image. In this blog, you will set up a serverless automation pipeline and create a customized WorkSpaces Windows OS image without manual actions on the WorkSpace. This solution works whether you are building an image for WorkSpaces Personal, WorkSpaces Pools, or WorkSpaces Core.

Overview

The solution is driven by an AWS Step Function which takes in a set of JSON parameters to configure the workflow. It creates a WorkSpace that is used to build the customized image. The WorkSpace is deployed with the AutoStop running mode to optimize costs. The Step Function establishes remote access using credentials that are randomly generated and stored in AWS Systems Manager (SSM) Parameter Store. These credentials are new and unique every time the workflow runs. They are accessed by the AWS Lambda functions directly and the WorkSpace via an Amazon API Gateway rest API at run time. By default, that API is only available while an active Step Function state machine is running, and is automatically deactivated when the pipeline completes. Additionally, the local administrator account on the WorkSpace is automatically removed on every shutdown. Once complete, the pipeline then sends a notification email via Amazon Simple Notification Service (SNS) with a summary of the results.

In this blog, you learn how to use two different methods to deploy application installers to the WorkSpace. First, using Amazon Simple Storage Service (Amazon S3) hosted install packages. These files are delivered to the WorkSpace instance via a short-lived Amazon S3 pre-signed URL, which is automatically generated by an AWS Lambda function. Second, an application installer is downloaded directly from the vendor’s source repository or website to the image builder WorkSpace. Another option, if your WorkSpace instance has access to network file shares, is to obtain source files for the pipeline directly from those shares.

Diagram depicting the AWS services used by the solution.

Walkthrough

In this article, you complete the following tasks:

  1. Use an AWS CloudFormation template to create the required components to build the WorkSpaces image creation automation pipeline.
  2. Deploy a Group Policy object to configure the image builder WorkSpace to accept remote commands.
  3. Run the pipeline to build a fully automated and customized WorkSpaces image.
  4. Learn how to modify input parameters to customize the pipeline to meet your needs.

Additional details not covered in this blog are available on the project’s GitHub repository.

Prerequisites

This article assumes that you have the following in place:

Step 1: Place workshop deployment files into an Amazon S3 bucket

This bucket will host the Lambda script packages and layer required by the CloudFormation template when deploying the solution. You may remove the files and bucket after successfully importing the CloudFormation template.

  1. Navigate to the Amazon S3 console.
  2. Choose Create bucket.
  3. Enter a unique name for the bucket, and select the AWS Region. The Region does not have to be the same Region where the WorkSpaces reside.
  4. Keep the defaults for the rest of the options.
  5. Choose Create bucket.
  6. Select the newly created bucket.
  7. Choose Upload.
  8. Choose Add files. Select the entire contents of the INSTALL folder extracted to your desktop from the release ZIP file downloaded from the project’s GitHub repository. Include the seven .ZIP files containing the Lambda function code as well as eighth .ZIP containing the pywinrm library Lambda layer.
  9. Choose Upload.
  10. Once complete, choose Close.

Step 2: Windows Updates and Organizational Unit considerations

AWS recommends creating an Organizational Unit (OU) dedicated to creating WorkSpaces images. This allows you to attach specific Group Policy Objects (GPOs) to only those WorkSpaces instances used for image creation. Additionally, create an AD Connector that is dedicated to image creation to place WorkSpaces into that OU. Refer to the Amazon WorkSpaces administration guide for details on selecting an organizational unit for your AD Connector. See the custom image best practices page for more detailed guidance on image creation recommendations.

By default, your Windows WorkSpaces are configured to receive updates from Windows Update over the internet. If you do not configure any Windows Updates settings via a GPO or other methods, your WorkSpaces will continue to receive available updates from Microsoft. This pipeline will then initiate the WorkSpace to look for and install all available updates if you set the SkipWindowsUpdates parameter to false. Alternatively, configure your own update mechanisms for Windows. See the documentation for Windows Server Update Services (WSUS) or the systems management platform you use for details.

Step 3: Deploy the AWS CloudFormation template

A CloudFormation template deploys the WorkSpaces image creation pipeline. It creates all the components and security definitions required.

  1. Navigate to the AWS CloudFormation console in the Region where your WorkSpaces environment resides.
  2. Choose Create stack then With new resources (standard).
  3. Select Upload a template file then Choose file.
  4. Select WKS-Automation-Windows-CloudFormation.yaml extracted from the release .ZIP.
  5. Choose Next.
  6. For Stack name, enter WorkSpaces-Windows-Image-Pipeline.
  7. Complete the template parameters.
    • CloudFormationSourceS3Bucket – the name of the Amazon S3 bucket created in Step 1 that contains the uploaded ZIP files.
    • SNSEmailSubscriptionEndPoint – Email address to receive completion notification.
    • LambdaVPCId – select the VPC where the Lambda functions that require network connectivity to your WorkSpaces are deployed.
    • LambdaVPCSubnet1 and LambdaVPCSubnet2 – select the two subnets where the Lambda functions are deployed.
    • DefaultDirectoryId – enter the directory id where WorkSpaces used for image creation are deployed. This directory should place the WorkSpaces into the dedicated OU created in Step 2 that has the Group Policy object created in Step 4 linked. (d-xxxxxxxxxx)
    • DefaultBundleId – enter the default bundle id to use when creating the image builder WorkSpaces. Bundle ids are different for each Region, search the WorkSpaces console for the id that matches your base image requirements. (wsb-xxxxxxxxx)
    • DefaultWorkSpaceUser– enter the user account which the image creation WorkSpace is deployed to. This user must exist in your directory and should not have an existing WorkSpace deployed in that directory. This user account does not log into the WorkSpace during the process and just serves as the placeholder to allow a WorkSpace to be created.
    • DefaultComputeType – The compute type of the image builder WorkSpace. Default is set when you deploy the CloudFormation template.
    • WorkSpaceVPCId – enter the VPC id where image builder WorkSpaces are deployed. This should be the VPC id that matches where your DefaultDirectoryId deploys WorkSpaces into.
  8. Choose Next.
  9. On the Configure stack options page, choose Next.
  10. On the review page, select the box I acknowledge that AWS CloudFormation might create IAM resources with custom names.
  11. Choose Create stack.
  12. The email address entered into SNSEmailSubscriptionEndPoint will receive a subscription notification email from AWS Notifications.
  13. Select Confirm subscription in that email before to receive email notifications from this solution.

Step 4: Create policy for Windows Remote Management (WinRM) and local Windows account

The key to the entire automation process is to obtain a set of known credentials with administrative privileges within the image builder WorkSpace operating system. These credentials are used to issue remote commands from the Lambda functions. This process is accomplished by applying a Group Policy object to the OU containing your image builder WorkSpace. The GPO script configures the Windows Firewall and Windows Remote Management (WinRM) service to accept remote commands. It also configures PowerShell startup and shutdown scripts. The startup script retrieves the credentials from Systems Manager parameter store via an API Gateway REST API, and creates a local administrator account. The shutdown script removes that local account, ensuring it does not exist on WorkSpaces deployed from your image.

This Group Policy that is attached to the image builder WorkSpace opens the machine to accepting remote commands. This OU should be separate from where WorkSpaces are deployed to your end users. WorkSpaces should be deployed into a different OU with policies that sufficiently lock down the operating system to meet your internal security guidelines.

  1. In the CloudFormation console, select the Outputs tab of the stack deployed in Step 3.
  2. Copy the Value of the APIInvokeURL key.
  3. Open the WKS_Builder_startup.ps1 script in a text editor. This script is found within the RUN folder extracted from the release .ZIP file.
  4. Update REPLACE_WITH_API_INVOKE_URL with the APIInvokeURL value from the previous step.
  5. Save the updated script.
  6. Launch the Windows Group Policy Management Console on a machine in your Active Directory domain.
  7. Navigate to the Organizational Unit (OU) where the image builder machines are placed. (This should be the OU configured on the AD Connector)
  8. Open the context (right-click) menu on the OU, and then choose Create a GPO in this domain, and Link it here….
  9. Name the GPO, for example [WorkSpaces-Image-Builder-Automation], then choose OK.
  10. Open the context (right-click) menu of the newly created GPO, then choose Edit.
  11. Select Computer Configuration, Policies, Windows Settings, Scripts (Startup/Shutdown).
    1. Choose Startup.
    2. Select the PowerShell Scripts tab.
    3. Choose Show Files to open the SYSVOL directory for this GPO object. Place the updated script named WKS_Builder_startup.ps1 into this location. This script is found within the RUN folder previously extracted to your desktop from the release .ZIP file.
    4. Once copied in place, back in the group policy editor, choose Add.
    5. Choose Browse and select the script WKS_Builder_startup.ps1.
    6. Choose OK, then OK.
  12. Still on Computer Configuration, Policies, Windows Settings, Scripts (Startup/Shutdown).
    1. Choose Shutdown.
    2. Select the PowerShell Scripts tab.
    3. Choose Show Files to open the SYSVOL directory for this GPO object. Place the workshop script named WKS_Builder_shutdown.ps1 into this location. This script is found within the RUN folder previously extracted to your desktop from the release .ZIP file.
    4. Once copied in place, back in the group policy editor, choose Add.
    5. Choose Browse and select the script WKS_Builder_shutdown.ps1.
    6. Choose OK, then OK.
  13. Select Computer Configuration, Policies, Windows Settings, Security Settings, Windows Defender Firewall with Advanced Security.
  14. Open the context (right-click) menu on Inbound Rules, choose New Rule….
  15. Select Predefined, then choose Windows Remote Management.
  16. Choose Next, then Next.
  17. Choose Allow the connection, then choose Finish.
  18. Select Computer Configuration, Policies, Administrative Templates, Windows Components, Windows Remote Management (WinRM), WinRM Service.
  19. Choose Allow remote server management through WinRM.
    1. Choose Enabled.
    2. For IPv4 filter and IPv6 filter, enter * or the IP range associated to the VPC and subnets assigned to your Lambda functions.
    3. Choose OK.
  20. Choose Allow Basic authentication. AWS recommends that this setting should be reviewed with your internal security teams and not left configured in this manner on your user facing WorkSpaces.
    1. Choose Enabled.
    2. Choose OK.
  21. Choose Allow unencrypted traffic. AWS recommends that this setting should be reviewed with your internal security teams and not left configured in this manner on your user facing WorkSpaces.
    1. Choose Enabled.
    2. Choose OK.
  22. Select Computer Configuration, Preferences, Control Panel Settings, Services.
  23. Open the context (right-click) menu, choose New then Service.
    1. For Startup, select Automatic.
    2. For Service name, enter WinRM.
    3. Choose OK.
  24. You may now close the Group Policy Management Editor.

Step 5: Upload a sample application installer to Amazon S3

The CloudFormation template created a bucket in S3 to demonstrate how to host installation packages that will be used by the automation workflow. The IAM policy attached to the Lambda functions grants access to this bucket. As an example, you will place a MSI installer for a simple SSH client, PuTTY, into this bucket. This installer utilizes standard MSI switches to perform a silent installation. For other installers you add to this workflow, refer to the vendor’s guidance on how to silently install their software. For additional guidance on determining the correct switches for your installation, refer to guides such as this and this.

  1. Download the latest PuTTY x86 MSI installer, and rename it to putty-installer.msi.
  2. Once the CloudFormation template is in the CREATE_COMPLETE stage, select Outputs.
  3. Take note of the Amazon S3 bucket created by the template (wks-automation-installer-source-########). The Lambda function was granted access to this bucket to generate the pre-signed URLs the WorkSpace will use to download the file.
  4. Navigate to the Amazon S3 console and browse into the bucket noted above.
  5. Choose Create folder.
  6. For Folder name, enter putty. Choose Create folder.
  7. Select the newly create putty folder to browse into it.
  8. Choose Upload.
  9. Choose Add files.
  10. Browse to and select the putty-installer.msi you downloaded to your desktop.
  11. Choose Open.
  12. Choose Upload.

Step 6: Test the image creation pipeline

Now that all the required components for the automation pipeline are in place, perform a test run of the workflow.

  1. Navigate to the AWS Step Functions console.
  2. Under State machines, select the WKS_Automation_Windows_Image_Build state machine created by the CloudFormation template and choose View details.
  3. Choose Start execution.
  4. For Name, enter WKS-Automation-Blog-Windows-Test.
  5. Replace the contents of the Input field with the following JSON statement. Replace the XXXXXX with the S3 bucket you uploaded the PuTTY installer into.
{
  "DeleteBuilder": true,
  "CreateBundle": true,
  "SkipWindowsUpdates": true,
  "ImageNamePrefix": "WKS_Blog_Test",
  "ImageTags": [
    {
      "Key": "Automation",
      "Value": "Test run"
    },
    {
      "Key": "Blog",
      "Value": "pipeline test"
    }
  ],
  "BundleNamePrefix": "WKS_Blog_Test",
  "InstallRoutine": [
    [
      "DOWNLOAD_S3",
      "s3://wks-automation-installer-source-XXXXXX/putty/putty-installer.msi",
      "c:\\wks_automation\\putty\\"
    ],
    [
      "RUN_COMMAND",
      "msiexec /i c:\\wks_automation\\putty\\putty-installer.msi /qn"
    ],
    [
      "DOWNLOAD_HTTP",
      "https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.6.6/npp.8.6.6.Installer.x64.exe"
    ],
    [
      "RUN_COMMAND",
      "c:\\wks_automation\\npp.8.6.6.Installer.x64.exe /S"
    ],
    [
      "RUN_POWERSHELL",
      "New-Item -Path HKLM:\\Software\\AmazonBlog -Force"
    ],
    [
      "RUN_POWERSHELL",
      "New-ItemProperty -Path HKLM:\\Software\\AmazonBlog -Name Automated_Image -Value true -PropertyType String -Force"
    ]
  ]
}
  1. The previous parameters will run the AWS Step Functions state machine resulting in a customized WorkSpaces image and bundle named WKS_Blog_Test -<timestamp>. The image will have two tags applied to it, will have PuTTY and Notepad++ installed, and will have a registry key set. Once complete the state machine will delete the image builder WorkSpace used to create the image.
  2. Choose Start execution.
  3. Monitor the status of the state machine in the console.
  4. Once completed, you receive an email notification at the address specified when deploying the solution. The new image will be in the WorkSpaces console under Images, and the bundle under Bundles. Additionally, if the automation encounters an issue that results in a failed status, this event will set off an Amazon EventBridge rule to notify you.

For additional customization, the automation workflow accepts several extra parameters that are applied by adding them to the Start execution JSON statement. For more detailed information on customization and next steps, review the readme on the GitHub repository.

Cleanup

In this blog post, you created several components that may generate costs based on usage. To avoid incurring future charges, remove all resources deploy from and created by this solution. For detailed cleanup steps, see the cleanup section of the repository readme.

Conclusion

By using automation to streamline the process of creating images for your WorkSpaces environment you increase operational efficiency. You reduce human error and increase consistency. Most importantly, you can quickly build new images and bundles for end users.

You now have a fully automated pipeline to create Microsoft Windows based WorkSpaces images. The sample applications included as part of this article are useful in demonstrating the workflow. You should now update the packages and parameters to reflect the applications required in your images. For more information on customizing the pipeline, visit the project GitHub repository.

For general guidance and recommendations on WorkSpaces images and bundles, refer to the best practices whitepaper and administrative guide. For a similar automation solution for Amazon AppStream 2.0, see the following blogs:

Justin Grego is a Senior End User Computing Specialist Solutions Architect. As part of the EUC Service Aligned SA Team, he helps enable both customers and fellow SAs get up to speed on and be successful with new AWS EUC features and services.