Desktop and Application Streaming

Automatically create customized AppStream 2.0 Windows images

Customers often ask how they can streamline the management and maintenance of their Amazon AppStream 2.0 images and fleets. In this blog, I walk you through automatically creating customized AppStream 2.0 Windows images.

The AppStream 2.0 service includes a rich set of API operations with which you can programmatically interact with the service. Also, the Image Assistant utility within the image builder instances supports command line interface (CLI) operations for adding applications to the fleet and creating images. A customer struggle, is linking the two together. First, interacting with the service externally to the image builder. Then, running commands programmatically within the Microsoft Windows guest operating system in the image builder. In this blog, I walk you through how to set up a serverless automation pipeline to create a customized AppStream 2.0 Windows OS based image.

Overview

The automation supports both domain and non-domain joined image builders. It creates a fresh image builder instance and establishes remote access using credentials that are automatically created and stored in AWS Secrets Manager. Then, it installs software packages and runs the Image Assistant utility to create an AppStream 2.0 image. Once complete, it then sends a notification email with the results.

In this blog, I provide two examples of using install packages. First, using Amazon Simple Storage Service (Amazon S3) hosted sample install packages. Second, application installers downloaded directly from the vendor’s source repository. There is also guidance on creating your own installation packages, or modifying existing wrappers and installation routines to support the AppStream 2.0 Image Assistant utility.

Solution Diagram

Time to read 20 minutes
Time to complete 1 hour
Cost to complete (estimated) $5
Learning level Advanced (300)
Services used Amazon AppStream 2.0
Amazon EventBridge
Amazon Simple Notification Service
Amazon Simple Storage Service (Amazon S3)
AWS CloudFormation
AWS Lambda
AWS Secrets Manager
AWS Step Functions

Walkthrough

In this article, you complete the following tasks:

  1. Use a CloudFormation template to create the required components to build the AppStream 2.0 image creation automation pipeline.
  2. Configure the image builder to accept remote commands.
  3. Run the automation to build a fully automated and customized AppStream 2.0 image.
  4. Learn how to create or modify software installation packages to be compatible with the automation pipeline.

Prerequisites

This article assumes that you have the following already in place:

  • An AWS account setup for Amazon AppStream 2.0 and IAM permissions to create AppStream 2.0 image builders and images.
  • Permissions to create the following service components:
    • AWS IAM roles and policies
    • AWS Lambda functions
    • AWS Secrets Manager secrets
    • AWS Step Functions
    • Amazon EventBridge rules
    • Amazon Simple Notification Service topics and subscriptions
    • Amazon S3 buckets
  • Permissions to run AWS CloudFormation templates.
  • Connectivity to the internet from the image builder subnets or VPC endpoints with requisite DNS entries and routing for Amazon S3 and AWS Secrets Manager.
  • Download and extract the files required in this guide from the project’s latest release on GitHub to your desktop.

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

  1. Navigate to the Amazon S3 console.
  2. Choose Create bucket.
  3. Enter a unique name for the bucket, and select the Region. The Region does not have to be the same Region where AppStream 2.0 resides.
  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. Be sure to include the four .ZIP files containing the Lambda function code as well as fifth .ZIP containing the pywinrm library Lambda layer. Do not unzip these files.
  9. Choose Upload.
  10. Once complete, choose Close.

Step 2: Create policies for Remote WinRM and local Windows account

The key to the entire application automation process is to obtain a set of known remote credentials within the image builder operating system. These credentials are used to issue remote commands from the Lambda functions. Select your appropriate scenario.

Scenario 1: Domain joined image builder

For domain joined image builders, this process is accomplished by applying a Group Policy. The Group Policy runs a PowerShell script to retrieve the credentials from Secrets Manager, and creates a local administrator account. The IAM role created by the CloudFormation template and assigned to the Image Builder grants the permission to retrieve the account information from Secrets Manager. The GPO script then configures the Windows Firewall and Windows Remote Management (WinRM) service to accept remote commands.

  1. Launch a Windows Group Policy Management Console.
  2. Navigate to the Organizational Unit (OU) where the image builder machines will be placed.
  3. Select the context menu on the OU.
  4. Select Create a GPO in this domain, then Link it here…
  5. Name the GPO, for example [AppStream-Image-Builders], choose OK.
  6. Select the context menu of the newly created GPO object. Choose Edit.
  7. 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 script named AS2_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 AS2_Builder_startup.ps1. This script is found within the RUN folder previously extracted to your desktop from the release .ZIP file.
    6. Choose OK. Then choose OK again.
    7. You can now exit the group policy editor.

Scenario 2: Non-domain image builder

For non-domain joined image builders, there is a one-time manual process to create a new base image that future launches of the automation will use.

A Windows Scheduled Task is configured to run at computer startup. This script will automatically pull the local administrator credentials from Secrets Manager. It will then create a local admin account, and configure the WinRM service for remote connections. This one-time manual process will result in a new base image, created in your account. You can use this base image for future automation runs.

Stop the scheduled task that configures WinRM for fleet instances. Also, reconfigure the remote WinRM service as required by your security standards.

Step a: Create an image builder

  1. Follow the launch image builder steps.

Step b: Deploy the image startup script

  1. Once the image builder enters the Running status, select the radio button and choose Connect.
  2. Choose Administrator to connect to the instance with administrative rights.
  3. Select the option to upload a file on the AppStream 2.0 toolbar.

  1. Select AS2_Builder_startup.ps1 script. Choose Open. This script is found within the RUN folder previously extracted to your desktop from the release .ZIP file.
  2. Once uploaded you will see the file listed in the Temporary Files folder. Close the My Files interface.
  3. In Windows Explorer on the image builder, copy C:\Users\ImageBuilderAdmin\My Files\Temporary Files\AS2_Builder_startup.ps1 to C:\AppStream\AS2_Builder_startup.ps1.
  4. Launch Windows Task Scheduler.
  5. Choose Action, Create task…
  6. For Name, you can enter AS2 Automation Image Builder Startup Script. The automation pipeline will automatically disable the task before creating an image for your fleets.
  7. Choose Change User or Group….
  8. Enter System into the box, and choose OK.
  9. On the Triggers tab, choose New.
  10. For Begin the task select At startup from the dropdown.
  11. Chose OK.
  12. On the Actions tab, choose New…
  13. In the Program/script box, enter:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  14. In the Add arguments box, enter: -ExecutionPolicy bypass -File C:\AppStream\AS2_Builder_startup.ps1
  15. Choose OK.
  16. On the Conditions tab, select the box for Start only if the following network connection is available. Then select, Any connection.
  17. Choose OK to complete the task creation.

Step c: Create a base image

The Image Assistant utility requires a dummy application in order to proceed with the creation of an image. In this blog, we will use notepad.exe and automatically remove it before creating an image.

  1. Launch the Image Assistant utility from the desktop.
  2. Choose Add App.
  3. For file name, enter C:\Windows\notepad.exe.
  4. For Name, enter DummyApp.
  5. For Display Name, enter DummyApp.
  6. Choose Save.
  7. Finish the Image Assistant utility to create an image by following the steps in the Amazon AppStream 2.0 Administration Guide.

Step 3: Deploy the AWS CloudFormation template

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

  1. Navigate to the AWS CloudFormation console in the Region with the AppStream 2.0 image.
  2. Choose Create stack then With new resources (standard).
  3. Select Upload a template file then Choose file.
  4. Select AS2-Automation-Windows-CloudFormation.yaml from the release .ZIP.
  5. Choose Next.
  6. For name, enter AppStream2-Windows-Pipeline.
  7. Complete the template parameters.
    1. AS2DefaultImage – enter the name of the default base AppStream 2.0 image to use for automations. For a domain-joined image builder, this can be an AWS provided base or a customer base. For non-domain-joined image builders, this should be the customized image created in step 2.
    2. AS2VPCId – select the VPC where the image builder and Lambda functions will be deployed into.
    3. AS2VPCSubnet1 and AS2VPCSubnet2 – select the two subnets where the Lambda functions will be deployed into.
    4. DefaultDomain (optional) – enter the FQDN for the Active Directory domain to join the image builders to. Keep blank or enter ‘none’ to use non-domain joined image builders.
    5. DefaultOU (optional) – enter the distinguished name of the Active Directory OU to where the image builders will reside when joined to your Active Directory domain. Keep blank or enter ‘none’ to use non-domain joined image builders.
    6. SNSEmailSubscriptionEndPoint – Email address to receive completion notification.
    7. SourceS3Bucket – the name of the Amazon S3 bucket created in step 1.
  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. After a few moments, the email address entered into SNSEmailSubscriptionEndPoint will receive a subscription notification email from AWS Notifications.
  13. Select Confirm subscription in that email before the final email from the automations can be sent.

Step 4: Prepare and upload application install packages to Amazon S3

This bucket will host the sample installation packages that will be used by the automation workflow. These samples contain the required installation wrapper code, but do not contain the source application installers. You will need to download that information from the software vendors. Additionally, if the image builder has access to the internet, the sample automation flow will download and add draw.io to the application catalog. This is an example of how to include applications directly from their online source repository.

Prepare installation packages

  1. Inside the RUN folder of the extracted release from the project GitHub repository is a Sample Applications folder. This folder contains the sample install scripts for Notepad++ and PuTTY.
  2. Download the latest PuTTY MSI installer, rename it to putty-installer.msi, and place it inside the PuTTY folder.

Screenshot of PuTTY folder structure

  1. Download the latest Notepad++ EXE installer, rename it to npp-installer.exe, and place it inside the NotepadPP folder.

Screenshot of Notepad++ folder structure
Upload Installation Packages

  1. Once the CloudFormation template is in the CREATE_COMPLETE stage, select Outputs.
  2. Take note of the Amazon S3 bucket created by the template (as2-automation-blog-########).
  3. Navigate to the Amazon S3 console and browse into the bucket noted above.
  4. Choose Upload.
  5. Add the entire contents of the Sample Applications folder, which includes the downloaded application installers.
  6. Choose Upload.
  7. Once complete, the as2-automation-blog bucket should contain two folders, with the script and install source for each application contained within.

Step 5: Test the image creation pipeline

Now that all of the required components for the automation pipeline are in place, the workflow can be run.

  1. Navigate to the AWS Step Functions console.
  2. Under State machines, select the AS2_Automation_Windows state machine created by the CloudFormation template and choose View details.
  3. Choose Start execution.
  4. For Name, enter AS2-Automation-Windows-Test.
  5. Replace the contents of the Input field with the following JSON statement.
{
    "ImageBuilderName": "AS2_Automation_Windows_Test",
    "ImageBuilderType": "stream.standard.medium",
    "ImageOutputPrefix": "AS2_Automation_Windows_Test",
    "DeleteBuilder": true
}
  1. These parameters will run the AWS Step Functions state machine resulting in an AppStream 2.0 private image named AS2_Automation_Windows_Test-<timestamp>. Once complete the state machine will delete the image builder used to create the image.
  2. Choose Start execution.
  3. The state machine status can be monitored 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 AppStream 2.0 console under Images. Additionally, if the automation encounters an issue that results in a failed status, this event will trigger an Amazon EventBridge rule to notify you.

For greater flexibility, the automation workflow accepts additional parameters by adding them to the JSON statement in step 5. For more 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 the following resources.

  1. Remove the S3 buckets used to store the .zip files containing the Lambda function code. Also remove the S3 bucket holding the software installation packages.
    1. Navigate to the Amazon S3 console.
    2. Select the bucket created in step 1.
    3. Select all the objects inside the bucket and choose Delete.
    4. Confirm the deletion and choose Delete objects.
    5. Once the bucket is empty, return to the Amazon S3 bucket page.
    6. Select the bucket and choose Delete.
    7. Confirm the deletion and choose Delete bucket.
    8. Repeat these steps to remove the bucket containing the software installation packages. This bucket will be named similar to as2-automation-blog-#######.
  2. Remove any AppStream 2.0 images created from the automation.
    1. Navigate to the AppStream 2.0 console.
    2. Select Images.
    3. Filter the image registry to custom images: Visibility = Private.
    4. Select the image to delete and click Action then Delete.
    5. Repeat for any additional images created using the automation that are no longer needed.
  3. Remove any AppStream 2.0 image builders created by the automation.
    1. Navigate to the AppStream 2.0 console.
    2. Select Images.
    3. Select the Image Builder tab.
    4. Select the image builder to delete and click Action then Delete.
    5. Repeat for any additional image builders left behind from the automation that are no longer needed.
  4. Remove all the remaining resources created by the CloudFormation template:
    1. Navigate to the CloudFormation console.
    2. Select the stack created in step 3, AppStream2-Windows-Pipeline.
    3. Choose Delete. This will automatically delete the other resources used in the solution.

Conclusion

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

You now have a fully automated pipeline to create Microsoft Windows based AppStream 2.0 images for both domain and non-domain joined scenarios. While the sample applications included as part of this article are useful in demonstrating the workflow, you should now update the packages and scripts to reflect the applications required in your images. For more information on customizing the packages, visit the project GitHub repository.

For additional guidance on keeping your customized images up to date, refer to the article reduce image maintenance overhead with Managed Image Updates for Amazon AppStream 2.0.