Desktop and Application Streaming

How to use automation to optimize and control cost of Amazon AppStream 2.0

As the demand for applications grow, the need to optimize and control the cost of Amazon AppStream 2.0 Fleet resources evolves. Through automation of AWS serverless services, you can control the cost of AppStream 2.0 Fleets. In this blog I will discuss how to use a billing alarm to get an alert when AppStream cost hits a predefined threshold. I will show how an AppStream 2.0 Fleet is started and stopped on a desired schedule using tags and an AWS Lambda function.

The sample code illustrated in this blog is for testing purpose only. Customers are advised to write their own code for Lambda functions in production environments.

Time to read 10 minutes
Time to complete 1 hour
Learning level Advanced (300)
Services used Amazon AppStream 2.0, Amazon CloudWatch, Amazon EventBridge, AWS Lambda


In this guide, you will complete the following tasks:

  1. Configure and tag the AppStream 2.0 test fleet
  2. Create and configure an Amazon CloudWatch billing alarm
  3. Configure and test email notification using Amazon SNS
  4. Create a Lambda function to start and stop the AppStream fleet
  5. Configure Amazon EventBridge Scheduler to invoke the AWS Lambda function
Architecture diagram of the solution described in this blog.

Figure 1. Architecture diagram of the solution described in this blog. The major components are Amazon CloudWatch billing alarm, Amazon EventBridge Scheduler and a Lambda function to automate Amazon AppStream fleet.


This article assumes that you have the following:

  1. Familiarity with AWS management console
  2. An AWS account setup for Amazon AppStream 2.0.
  3. Familiarity with AWS Lambda

Step 1: Create sample AppStream 2.0 fleet and stack

Follow the Amazon AppStream 2.0 Getting Started procedure in the administration guide. You can choose to configure and test any open source application such as Notepad++ or browser such as Google Chrome. Once complete, you will have a fleet running and a Streaming URL available to be used.

Step 2: Create a billing alarm to monitor your estimated AWS charges

Billing metric data is stored in the US East (N. Virginia) Region and represents worldwide charges. This data includes the estimated charges for every service in AWS that you use, in addition to the estimated overall total of your AWS charges. The alarm triggers when your account billing exceeds the threshold you specify. It triggers only when the current billing exceeds the threshold. It doesn’t use projections based on your usage so far in the month.

Before you create a billing alarm, set your Region to US East (N. Virginia). Turn on billing alerts in the payer account using following instructions.

Open the CloudWatch console in payer account at

  • In the navigation pane, choose Alarms, and then choose All alarms.
  • Choose Create alarm.
  • Choose Select metric. In Browse, choose Billing, and then choose By Linked Account and Service
  • Choose appropriate LinkedAccount and ServiceName = AmazonAppStream
  • Create billing alarm named “myalarm” as per the instructions in the guide Activate billing alerts.

Step 3: Test the alarm

Assuming the alarm has not been triggered yet, the current status of the alarm is ‘OK’. Test the alarm by temporarily changing its status to ‘ALARM’ state using AWS CLI. To use the following example, ensure that you have the AWS CLI installed and configured. See the getting started guide in the AWS CLI User Guide for more information.

The following example uses the “set-alarm-state” command to temporarily change the state of a billing alarm named “myalarm” created earlier.

aws cloudwatch set-alarm-state --alarm-name "myalarm" --state-value ALARM --state-reason "testing purposes"

This command returns to the prompt if successful.

Once the alarm is in ‘ALARM’ state, you will receive an email notification via the Amazon SNS topic created previously in step 2. You can take appropriate action to avoid incurring additional charges beyond your monthly threshold.

After testing, you can change the status of alarm to ‘OK’ using the same command.

Step 4 : Automatic shutdown and start of AppStream fleet using Amazon Eventbridge Scheduler

EventBridge Scheduler is a serverless scheduler that allows you to create, run, and manage tasks from one central, managed service. The instructions below show how to configure EventBridge and Lambda. This example configures the AppStream fleet to start at 9 am and shutdown at 6 pm every weekday to optimize the usage and cost.

Warning– Instructions in this step will cause Appstream fleet to shut down at the specified time and users will immediately lose access to their sessions.

  • Tagging the AppStream Fleet:
    • Open the AppStream 2.0 console at
    • From the navigation bar, select the Region that contains the fleet.
    • In the navigation pane, select ‘Fleets’
    • Select the fleet from the resource list.
    • Choose TagsEdit Tags, and then choose Add Tag:
      • Type the key ‘isoptimized’ and value ‘yes’ for the tag.
    • Choose Save.
  • Create IAM role for Lambda function
    • Sign in to the AWS Management Console and open the IAM console at
    • Choose Policies, choose Create Policy, choose JSON and paste following policy statement. Type your AWS account id where indicated. Your account id can be found at the top-right of the console window.


    "Version": "2012-10-17",

    "Statement": [


            "Sid": "VisualEditor0",

            "Effect": "Allow",

            "Action": [






            "Resource": "arn:aws:appstream:*:<AWS Account ID>:fleet/*"




This IAM policy provides the necessary permissions for the Lambda function to start and stop the AppStream fleet in the specified AWS account. Ensure that your AWS account id has been entered and choose Next.

    • Enter Policy Name and Choose Create Policy
    • In the navigation pane of the IAM console, choose Roles, and then choose Create role.
    • For Select trusted entity, choose AWS service, choose Lambda, choose Next
    • Choose the policy you created in earlier step
    • Enter Role Name and choose Create Role
  • Create Lambda function with console
    • Choose Author from scratch, enter a Function name of “AppStreamFleetScheduler”
    • For Runtime choose Python
    • For Execution Role, choose the existing IAM Role created in previous step
    • Choose Create Function
    • Paste below sample code which automates AppStream fleet based on the tag key ‘isoptimized’ which was used earlier to tag the AppStream fleet. Choose Deploy

import json

import boto3

from pprint import pprint

appstream_client = boto3.client('appstream')

def lambda_handler(event, context):

    # Describe Amazon AppStream Fleet

    appstream_fleet_response = appstream_client.describe_fleets()

    # Get the Fleet Arn

    for fleets in appstream_fleet_response['Fleets']:

        fleet_arns = fleets['Arn']

        # Get Tags for each Fleet

        fleet_tags = appstream_client.list_tags_for_resource(


        # pprint(fleet_tags['Tags'])

        # Check if Fleet is tagged with isoptimized Tag

        if (('isoptimized', 'yes') in fleet_tags['Tags'].items()):

            # Check if the Fleet is in Running State

            if fleets['State'] == 'STOPPED':


                # Start Fleet

                start_fleet_response = appstream_client.start_fleet(


                pprint("Fleet is started")

            elif fleets['State']=='RUNNING':


                #Stop Fleet

                stop_fleet_response = appstream_client.stop_fleet(


                print("Fleet is stopped")


            print('No valid Fleet available')

  • You can test your Lambda function in the console by invoking your function with a test event. Use an empty document {} as your test Event JSON.
  • Create Amazon Eventbridge Schedule :
    • Open the Amazon EventBridge console at
    • In the navigation pane, choose Schedule.
    • Choose Create schedule.
    • Enter a Name of “FleetStart” and, optionally, a Description for the rule.
    • Choose Default for Scheduler group
    • For Occurrence, choose Recurring schedule
    • For Schedule type, choose Cron-based schedule.
    • Choose following cron expression to start the AppStream fleet every weekday at 9:00 AM:

0 9 ? * MON-FRI *

Cron schedule example

You can find more information on cron based schedules in the documentation

    • For Flexible time window, choose Off
    • Choose your time zone.
    • Optionally choose Start/End date and time. Choose Next
    • Choose Templated targets
    • Choose AWS Lambda, Choose the function created in earlier step, Choose Next
    • Review and choose Create Schedule
  • Repeat above steps and create another schedule named ‘FleetStop’ for stopping the fleet every weekday at 6:00 PM. You can use following cron expression:

0 18 ? * MON-FRI *

                      Cron schedule example

You can test the automation by tweaking the expression to invoke the schedule as per your current local time. Depending on the current state of the fleet, the schedule will either start or stop.

For this specific schedule to work correctly, ensure that the fleet is in ‘Stopped’ state before 9 am on the next weekday.


In this blog you learned  how to control and optimize cost of Amazon AppStream 2.0. AWS Serverless services can be used to automate AppStream fleet startup and shutdown as per the business requirement. For further reading, see this blog post: Use AWS Lambda to adjust scaling steps and thresholds for Amazon AppStream 2.0 To know more about Amazon AppStream 2.0 cost optimisation, visit AWS documentation. If you have comments about this blog post, please submit them in the ‘Comments’ section below.

Pankaj Patil is a Partner Solutions Architect working with worldwide public sector in India at Amazon Web Services (AWS). He has over 17 years of experience in IT industry. He is passionate about  cloud adoption, cybersecurity and building highly available, secure and scalable solutions on AWS on behalf of partners and customers.