Desktop and Application Streaming
AWS CloudFormation support for Amazon AppStream 2.0 resources and API enhancements
We’ve learned from our customers that they want to create AppStream 2.0 resources along with their AWS resources to support a workshop or event. Today, AWS is announcing that AWS CloudFormation now supports creating AppStream 2.0 resources. With a single template, you can automate the creation of your stacks, fleets, image builders, directory configurations, and user pool users. You can now create AppStream 2.0 resources in your AWS CloudFormation templates along with your other AWS resources.
AppStream 2.0 also released API operations that enable programmatic management of user pool users. With these API operations, you can now create, manage, and delete your AppStream 2.0 user pool users.
AWS CloudFormation support for AppStream 2.0 resources
AWS CloudFormation provides a common language for you to describe and provision all the infrastructure resources in your cloud environment. AWS CloudFormation lets you use a text file to model and provision, in an automated and secure manner, all the resources needed for your applications across all AWS Regions and accounts. You can now use AWS CloudFormation to create and manage your AppStream 2.0 image builders, stacks, fleets, directory configs, and user pool users.
The following is an example AWS CloudFormation YAML configuration for creating a demo stack, fleet, and user:
AWSTemplateFormatVersion: 2010-09-09
Description: "This CloudFormation Stack creates AppStream resources within the default VPC."
Resources:
AppStreamFleet:
Type: "AWS::AppStream::Fleet"
Properties:
Name: "DemoFleet"
Description: "This is a demo fleet that was created using CloudFormation"
DisplayName: "A demo fleet created in CloudFormation"
ImageName: "MySampleImage"
InstanceType: "stream.standard.medium"
FleetType: "ALWAYS_ON"
ComputeCapacity:
DesiredInstances: 5
VpcConfig:
SubnetIds:
- subnet-<redacted>
- subnet-<redacted>
SecurityGroupIds:
- sg-<redacted>
MaxUserDurationInSeconds: "57600"
DisconnectTimeoutInSeconds: "900"
EnableDefaultInternetAccess: False
CreationPolicy:
StartFleet: True
ScaleTarget:
Type: 'AWS::ApplicationAutoScaling::ScalableTarget'
Properties:
MinCapacity: 1
MaxCapacity: 5
ResourceId: !Join
- ''
- - 'fleet/'
- !Ref AppStreamFleet
RoleARN: >-
arn:aws:iam::<aws-account-number>:role/service-role/ApplicationAutoScalingForAmazonAppStreamAccess
ScalableDimension: 'appstream:fleet:DesiredCapacity'
ServiceNamespace: appstream
DependsOn:
- AppStreamFleet
ScaleInPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: !Join
- ''
- - 'ScaleIn-'
- !Ref AppStreamFleet
PolicyType: StepScaling
ScalingTargetId: !Ref ScaleTarget
StepScalingPolicyConfiguration:
AdjustmentType: ChangeInCapacity
Cooldown: 360
MetricAggregationType: Average
StepAdjustments:
- MetricIntervalUpperBound: 0.0
ScalingAdjustment: -1
DependsOn:
- ScaleTarget
ScaleOutPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: !Join
- ''
- - 'ScaleOut-'
- !Ref AppStreamFleet
PolicyType: StepScaling
ScalingTargetId: !Ref ScaleTarget
StepScalingPolicyConfiguration:
AdjustmentType: ChangeInCapacity
Cooldown: 120
MetricAggregationType: Average
StepAdjustments:
- MetricIntervalLowerBound: 0.0
ScalingAdjustment: 2
DependsOn:
- ScaleTarget
ScaleInAlarm:
Type: AWS::CloudWatch::Alarm
Properties :
AlarmActions :
- !Ref ScaleInPolicy
AlarmDescription : "Scale in the fleet when using 25% capacity"
AlarmName : !Join
- ''
- - 'ScaleInAlarm'
- !Ref AppStreamFleet
Dimensions :
- Name: Fleet
Value: !Ref AppStreamFleet
MetricName : CapacityUtilization
Namespace : AWS/AppStream
Period : 120
EvaluationPeriods : 10
Statistic : Average
Threshold : 25
ComparisonOperator : LessThanOrEqualToThreshold
Unit : Percent
DependsOn:
- ScaleInPolicy
ScaleOutAlarm:
Type: AWS::CloudWatch::Alarm
Properties :
AlarmActions :
- !Ref ScaleOutPolicy
AlarmDescription : "Scale out the fleet when using 75% capacity"
AlarmName : !Join
- ''
- - 'ScaleOutAlarm'
- !Ref AppStreamFleet
Dimensions :
- Name: Fleet
Value: !Ref AppStreamFleet
MetricName : CapacityUtilization
Namespace : AWS/AppStream
Period : 60
EvaluationPeriods : 3
Statistic : Average
Threshold : 75
ComparisonOperator : GreaterThanOrEqualToThreshold
Unit : Percent
DependsOn:
- ScaleOutPolicy
AppStreamStack:
Type: "AWS::AppStream::Stack"
Properties:
Name: "DemoStack"
Description: "This demo stack was created using CloudFormation"
StorageConnectors:
- ConnectorType: "HOMEFOLDERS"
ResourceIdentifier: "TestCloudFormationStackBucket"
AppStreamDemoStackFleetAssociation:
Type: 'AWS::AppStream::StackFleetAssociation'
Properties:
FleetName: !Ref AppStreamFleet
StackName: !Ref AppStreamStack
DependsOn:
- AppStreamFleet
- AppStreamStack
AppStreamUser:
Type: "AWS::AppStream::User"
Properties:
UserName: "user@email.com"
FirstName: "John"
LastName: "Smith"
AuthenticationType: "USERPOOL"
AppStreamStackUserAssociation:
Type: "AWS::AppStream::StackUserAssociation"
Properties:
UserName: "user@email.com"
StackName: !Ref AppStreamStack
SendEmailNotification: False
DependsOn:
- AppStreamStack
- AppStreamUser
In the previous example, the AppStream stack and fleet resource are created independently. To associate them, use the StackFleetAssociation AWS CloudFormation resource. To associate the fleet and stack at the right time, the StackFleetAssociation resource should have a dependency on the creation of the resources it is associating.
For more information about AppStream 2.0 resource creation with AWS CloudFormation templates, see the AWS CloudFormation user guide.
AppStream 2.0 user pool API operations
The user pool feature in AppStream 2.0 lets you efficiently create and manage users within the AppStream 2.0 console. Your users can use a persistent login link to set a password and stream the apps you have assigned to them. Our customers told us that they wanted to manage their user pool users via the API and SDK. With the API operations, you can create, assign to stacks, enable, disable, and delete users. You can also describe your user pool users and describe their stack associations.
The following is an example of creating a user, assigning the user to a stack, disabling the user, and then deleting the user.
Create the user’s account, by using the following:
aws appstream create-user --user-name "<email redacted>" --first-name "John" --last-name "Smith" --authentication-type "USERPOOL"
The user receives the welcome to AppStream 2.0 email that contains their initial password, and the login link. Now that the user’s account has been created, we must assign the account to a stack with apps. Assign the account to a stack by using the following:
aws appstream batch-associate-user-stack --user-stack-associations AuthenticationType="USERPOOL",SendEmailNotification=True,StackName="TestStack",UserName="<email redacted>"
The user receives the assignment email notifying them that they have new apps available. The user can now log in with their temporary password, set a permanent password, and stream apps!
When the user temporarily doesn’t need their applications, you can disable their account. Disabling their account keeps their stack associations and password; however, they can’t log in and stream until you enable them again. Disable an account by using the following:
aws appstream disable-user --user-name "<email redacted>" --authentication-type "USERPOOL"
Disabled users receive an error when they try to log in. When the user no longer needs access to their applications, you can delete their account. When you delete their account, the stack associations and their password are deleted. If the user needs access again, create a new account for them, and associate it to your stacks. The user must then use the temporary password to set a new permanent password. Delete an account by using the following:
aws appstream delete-user --user-name "<email redacted>" --authentication-type "USERPOOL"
Conclusion
That’s it! You can create your own AWS CloudFormation templates to create your AppStream 2.0 resources along with your other AWS resources and now use the user pool API operations to create and manage your users.