Desktop and Application Streaming

Automate AppStream 2.0 Elastic fleet application updates with AWS Systems Manager

With Amazon AppStream 2.0 Elastic fleets you can stream portable applications to users without having to manage AppStream 2.0 images, configure scaling policies, or predict utilization. A portable application is an application that can have all of its dependencies reside in a single mounted path. Elastic fleets download a virtual hard disk (VHD) that contains your business applications. You can automate how the VHD is created. By automating the workflow, you can use your existing code pipeline/compilation process to update applications for Elastic fleets.

In this blog, I walk you through using AWS Systems Manager to run commands on a managed Amazon Elastic Compute Cloud (EC2) instance. The commands create a new VHD, install an application on the VHD, and then upload the VHD to an S3 bucket. If you package your own application, ensure it can run as a portable application. A portal application is an application that can have all of its dependencies reside in a single mounted path. After completing this blog, you can use the VHD you created to create an AppStream 2.0 app block.

Solution overview

This solution takes you through automating the process of packaging an application on a VHD.  A PowerShell script creates a new VHD, install an example application, detach the VHD, and then upload it to an S3 bucket. The script invocation is done remotely using an AWS Systems Manager Run Command to run on a managed EC2 instance. The provided script’s example application is Google Chrome for a Windows AppStream 2.0 instance. While this blog’s example is for Microsoft Windows, the GitHub repository includes a script for AppStream 2.0 Linux instances. Amazon Linux 2 streaming instances have a lower hourly rate for the same instance type and size, and avoids the user fee associated with Microsoft Windows streaming instances.

Solution architecture

Solution architecture depicting an administrator sending an Systems Manager Run Command from their local machine. The Run Command is executed on a managed EC2 instance. The result of the Run Command is a created VHD file, which is shown to be uploaded to Amazon S3. All egress network traffic flows through a NAT gateway and out to the internet.


The provided script goes through five main phases. It is recommended that you review the GitHub repository, and the README file that is included, to understand how it works. You can modify it to fit your use case.

  1. Validate parameters
  2. Build VHD configuration
  3. Run VHD configuration
  4. Application installation
  5. Detach the VHD, and upload to S3


This post assumes you have the following:

  1. An AWS account.
  2. Familiarity with AppStream 2.0.
  3. Familiarity with the Elastic fleets type and its application and app block resources.
  4. Windows EC2 instance managed by Systems Manager.
  5. An existing S3 bucket to host your automation script and published VHD.
  6. Access to and familiarity with Systems Manager.
  7. Familiarity with PowerShell.
  8. IAM permissions to access all of the components mentioned.

Step 1: Upload your script to an existing S3 bucket

Systems Manager needs a centralized location to reference when running the configuration script. The provided Elastic fleet packaging script is as an example. If you want to use your own application, modify the script with the automation steps specific to your application. You may need to change the disk size to meet your requirements. The recommended maximum size of the VHD is 1.5 gigabytes.

  1. Download Create-ChromeVHDX.ps1.
  2. (Optional) change the application installation section.
  3. Open the S3 console.
  4. Navigate to your S3 bucket.
  5. Upload your script object. You can drag the file into your S3 bucket browser window, or use other S3 upload methods.

Note: With bucket versioning enabled, you are able to keep previous versions of your scripts and VHDs. With object versioning, you can revert the script change in case an issue occurs. You pay for every object version that is stored. Consider using lifecycle policies to delete earlier versions after some period. When versioning is disabled, uploaded objects will overwrite existing objects that have the same name.

Step 2: Packaging your application

In this step, the script is run on your managed Windows EC2 instance via an AWS-RunRemoteScript Run Command. The Run Command can be invoked via the AWS Command Line Interface (AWS CLI), or the AWS Management Console for Systems Manager. Learn more about running commands from the AWS Management Console for Systems Manager by reviewing running commands from the console. If you do not have the AWS CLI available, you can also use the AWS CloudShell.


aws ssm send-command \

--document-name "AWS-RunRemoteScript" \

--targets "Key=instanceids,Values=i-XXXXXXXXXXXXX" \

--parameters '{"sourceType":["S3"],"sourceInfo":["{\"path\":\"\"}"],"commandLine":["Create-ChromeVHDX.ps1 -installSize 650 -vhdName Chrome -vhdS3Bucket BUCKET-NAME -vhdMountPath \"C:\\Program Files\\Google\\\" -force $true"]}'

Using the AWS Systems Manager Run Command console

  1. Navigate to the AWS Systems Manager Run Command console.
  2. Choose Run Command.
  3. Within Command Documents, select AWS-RunRemoteScript.
  4. For Source Type, choose S3.
  5. For Source Info, input you bucket with the following syntax:
    • {"path":""}
  6. For Command Line, input the following:
    • Create-ChromeVHDX.ps1 -installSize 650 -vhdName Chrome -vhdS3Bucket BUCKET-NAME -vhdMountPath "C:\Program Files\Google\" -force $true
  7. For Targets, select Choose instances manually. Select your managed EC2 instance.
  8. (Optional) under Output options, choose a S3 bucket to store the log of the Run Command invocation.
  9. Select Run.

Note: The script can be used many different ways to meet your application’s requirements. The example application installs to a specific path on the C: drive. This install type prevents simply mounting the VHD to a drive letter. Instead, mount the VHD to a specific folder, then install the application. To mount the VHD to a specific folder, use the -vhdMountPath parameter.

Step 3: Validate the install and configure bucket permissions

Finally, verify that the VHD was successfully created and validate the permissions on the S3 bucket. You can monitor command statuses.

  1. Navigate to the S3 Console.
  2. Choose the bucket you supplied to the Run Command.
  3. The bucket contains the VHD. For this scripted example, this is Chrome.vhdx.
  4. Apply a bucket policy to your S3 bucket to allow the AppStream 2.0 service access. The permissions are detailed in the store application icon, setup script, and VHD in S3 bucket administration guide.
  5. Create an Elastic Fleets App Block that targets your VHD.

Cleaning up

In this blog, you created two billable S3 objects, and one VHD file in your EC2 instance. In your specified S3 bucket, the two billable files are the VHD that was created, and the script that was invoked. The two files are charged standard S3 pricing. To avoid that cost, delete the VHD and script objects. The script that ran does not delete the VHD on the associated EC2 instance. This VHD does not incur additional costs because the Amazon Elastic Block Store (Amazon EBS) volume has already been provisioned, however it is taking up space on that volume. If you want to reclaim the space, navigate to the file location at either your $env:TEMP directory, or the provided -vhdLocation parameter path. If you launched an EC2 instance for this blog, power it off, or terminate it and delete the underlying Amazon EBS volume to prevent continuing charges for the resources.


During this post, you automate an AppStream 2.0 Elastic fleet’s application deployment. The example script can be altered and reused to reduce the administrative overhead of maintaining your workload for application deployments and updates. More information on managing applications associated to an elastic fleet is in the Administration Guide section on how to update a fleet.  You can also review the process to update the app block, VHD, and setup script section. You can use this process within AWS Step Functions, or other automation mechanisms, to create the managed EC2 instance programmatically. Then, remove those instances after the package has been completed to reduce costs. If your business already has an established software compilation pipeline, it can be integrated to streamline the entire workflow. Thanks for reading and happy building!