Desktop and Application Streaming

Amazon AppStream 2.0 Updates: Image Sharing APIs, Clipboard enhancement, and DescribeSessions API with client IP

I’m excited to share three new features we added to Amazon AppStream 2.0 recently. These features enable you to programmatically copy your images between AWS accounts within the same AWS Region, improve the text copy and paste experience, and enable you to identify the IP addresses your streaming instances are using in your Amazon VPC.

  • Image Sharing APIs – You can now programmatically share your images with other AWS accounts within the same AWS Region. You do so by specifying whether these accounts can use your image for image builders, fleets, or both.
  • Clipboard enhancement – You can now use keyboard shortcuts to copy and paste text between your local device and your AppStream 2.0 streaming sessions when using Google Chrome.
  • DescribeSessions API with client IP – You can now call the DescribeSessions API to find the Amazon VPC private IP address and elastic network interface (ENI) ID of your users’ streaming session.

Image Sharing APIs

AppStream 2.0 launched APIs that enable you to programmatically share images with other AWS accounts within the same AWS Region. Sharing AppStream 2.0 images between accounts is helpful when you separate your development and production resources by using different AWS accounts. For example, you can create your AppStream 2.0 image in your development account and then share it with your production account. Or, if you’re an ISV, you can share with your customer an optimized AppStream 2.0 image with your application already installed and configured. With your optimized image, they can get started with your applications quickly, without having to install and configure them.

When sharing an image with another AWS account, you specify whether the destination account can use the image in a fleet or generate new images by creating an image builder. You continue to maintain ownership of images you share, and can modify or remove permissions as needed, even after sharing.

You use the UpdateImagePermissions API to share a private image with other AWS accounts by adding permissions to use that image with fleets or image builders.  Fleet permissions allow the destination account to create or update a fleet with your image. If you later revoke the fleet permission, the destination account can no longer use the image. Existing fleets using the shared image will have the desired capacity set to 0, which prevents new instances from being created. Existing sessions continue until the streaming session ends.

Image builder permissions enable the destination account to create image builders and images from your image. If you later revoke the image builder permission, existing image builders and images created from your image are not impacted. You cannot control image builders or images in the destination account created from your image. So set this permission only if you want to permit the destination account to make a copy of your image and retain access to it even after you have stopped sharing your image.

To share an image with another account with fleet-only permissions, use the following:

aws appstream update-image-permissions --name "Test_Image" --shared-account-id <destination_account_id> --image-permissions allowFleet=True,allowImageBuilder=false

And then the destination account sees the following:

aws appstream describe-images --arns "arn:aws:appstream:us-west-2:<source_account_id>:image/Test_Image"
 {
     "Images": [
         {
             "Name": "Test_Image",
             "Arn": "arn:aws:appstream:us-west-2:<source_account_id>:image/Test_Image",
             "DisplayName": "Test_Image",
             "State": "AVAILABLE",
             "Visibility": "SHARED",
             "ImageBuilderSupported": true,
             "Platform": "WINDOWS",
             "Applications": [
              <removed_app_list>
             ],
             "CreatedTime": 1517531813.589,
             "PublicBaseImageReleasedDate": 1504625452.0,
             "ImagePermissions": {
                 "allowFleet": true,
                 "allowImageBuilder": false
             }
         }
     ]
 }


I can then update a fleet in the destination account to use the shared image. Because the destination account doesn’t own the image, I need to use the Amazon Resource Name (ARN) instead of the name, as shown in the following example:

aws appstream update-fleet --image-arn "arn:aws:appstream:us-west-2:<source_account_id>:image/Test_Image" --name "Test_Fleet"
 {
     "Fleet": {
         "Arn": "arn:aws:appstream:us-west-2:<destination_account_id>:fleet/Test_Fleet",
         "Name": "Test_Fleet",
         "ImageName": "Test_Image",
         "ImageArn": "arn:aws:appstream:us-west-2:<source_account_id>:image/Test_Image",
         "InstanceType": "stream.compute.large",
         "FleetType": "ALWAYS_ON",
         "ComputeCapacityStatus": {
             "Desired": 5,
             "Running": 5,
             "InUse": 2,
             "Available": 5
         },
         "MaxUserDurationInSeconds": 57600,
         "DisconnectTimeoutInSeconds": 900,
         "State": "RUNNING",
         "CreatedTime": 1530658609.703,
         "FleetErrors": [],
         "EnableDefaultInternetAccess": false
     }
 }

Now let’s see what happens when the source account removes permissions from the destination account:

Source account:
aws appstream delete-image-permissions --name "Test_Image" --shared-account-id <destination_account_id>
 Destination account:
 aws appstream describe-fleets --name "Test_Fleet"

 {
     "Fleets": [
         {
             "Arn": "arn:aws:appstream:us-west-2:<destination_account_id>:fleet/Test_Fleet",
             "Name": "Test_Fleet",
             "ImageName": "Test_Image",
             "ImageArn": "arn:aws:appstream:us-west-2:<source_account_id>:image/Test_Image",
             "InstanceType": "stream.compute.large",
             "FleetType": "ALWAYS_ON",
             "ComputeCapacityStatus": {
                 "Desired": 0,
                 "Running": 2,
                 "InUse": 2,
                 "Available": 0
             },
             "MaxUserDurationInSeconds": 57600,
             "DisconnectTimeoutInSeconds": 900,
             "State": "RUNNING",
             "CreatedTime": 1530658609.703,
             "FleetErrors": [
                 {
                     "ErrorCode": "SHARED_IMAGE_DELETED",
                     "ErrorMessage": "Image is not accessible. Update the fleet with a valid image"
                 }
             ],
             "EnableDefaultInternetAccess": false
         }
     ]
 }

The fleet’s desired capacity is set to 0, which causes existing unused streaming instances to terminate. The fleet is unable to create new streaming instances because the shared image is no longer available. Existing users with streaming sessions continue without an issue, but when they end, they cannot start a new streaming session to this fleet.

For more information, see the AppStream 2.0 API Reference documentation.

Clipboard Enhancement

Users can now copy and paste content between their local device and their streaming session, as they would between applications on their local device, including using keyboard shortcuts. This is supported through the W3C specification for enabling asynchronous clipboard operations in web applications, and is available when using Google Chrome version 66 or later to access applications on AppStream 2.0.

DescribeSessions API Enhancement

Sometimes it’s necessary to identify the IP address of the streaming instance your user is streaming from; for example to add access to a network resource for a user, or to audit access. You can now find your VPC private IP address and the elastic network interface ID that is associated with your users’ AppStream 2.0 streaming instance when you call the DescribeSessions API. You can also use AppStream 2.0 and EC2 APIs to modify the security groups for the instance in real-time, based on the user that is logged in, as shown in the following example:

aws appstream describe-sessions --stack-name TestStack --fleet-name TestFleet
 {
     "Sessions": [
         {
             "AuthenticationType": "API",
             "UserId": "janedoe",
             "FleetName": "TestFleet",
             "StackName": "TestStack",
             "State": "ACTIVE",
             "NetworkAccessConfiguration": {
                 "EniId": "eni-<redacted>",
                 "EniPrivateIpAddress": "10.0.3.229"
             },
             "Id": "<redacted>"
         }
     ]
 }
 aws ec2 modify-network-interface-attribute --network-interface-id "eni-<redacted>" --groups sg-<redacted> sg-<redacted>

 aws ec2 describe-network-interface-attribute --network-interface-id "eni-<redacted>" --attribute "groupSet"
 {
     "NetworkInterfaceId": "eni-<redacted>",
     "Groups": [
         {
             "GroupName": "VPC Allowed",
             "GroupId": "sg-<redacted>"
         },
         {
             "GroupName": "d-<redacted>_controllers",
             "GroupId": "sg-<redacted>"
         }
     ]
 }

For more information about the DescribeSessions API, see the AppStream 2.0 API Reference documentation.

We hope you enjoy using these features. Let us know on the Amazon AppStream 2.0 forum if you have any feedback.