Streamline Application Deployment with AWS AppStream 2.0: A Complete Guide to Elastic Fleets Using Terraform and CloudFormation
What is AWS AppStream 2.0
AWS AppStream 2.0 is a service that lets you run desktop applications in the cloud, so users can access them from anywhere, without having to install the software on their own computers. It’s beneficial for businesses that want to make sure everyone has access to the same tools, whether they’re working remotely or in the office. With AppStream 2.0, everything is managed centrally, so software updates and security are easier to handle.
What is usually deployed with AWS AppStream2.0?
1. Applications
2. Images
3. Fleets
4. Stacks
5. User Access
When you set up AWS AppStream 2.0, you’re essentially creating a cloud-based system that streams applications to users. To do that, you create and manage applications, images, fleets, stacks, and user access to ensure everything runs smoothly and efficiently. This setup gives users easy access to their applications without worrying about installation or updates, while also providing flexibility and scalability for businesses.
Fleet Types in AWS AppStream 2.0
In AppStream 2.0, fleets are groups of virtual computers (instances) that run the applications users need. There are a few different types of fleets you can choose from, depending on how you want to manage resources and costs.
1. Always-On Fleets
2. On-Demand Fleets
3. Elastic Fleets (New)
Elastic fleets are great for businesses that need flexibility without the hassle of managing infrastructure, especially when the number of users can go up and down unexpectedly.
Difference Between Elastic Fleets and Image-Based Fleets in AWS AppStream 2.0
1. Elastic Fleet
2. Image-Based (On-Demand or Always-On) Fleet
Key differences:
Use Case: Comprehensive deployment of an Elastic Fleet with AppBlock using Windows OS in AWS AppStream 2.0
In this scenario, we will focus on setting up an Elastic Fleet within AWS AppStream 2.0 to deploy an application using an AppBlock. This use case specifically targets applications designed to run on a Microsoft Windows operating system, leveraging Windows-specific components. The AppBlock serves as a container that holds our use case essential resources, required to run the application, including:
For better understanding we will compile resource creation in ‘Steps’. *Deploy each ‘Step’ one after the other.
Step 1. To begin this process, we will provision an S3 bucket that will hold these files. This bucket will serve as the storage location for the components of the AppBlock. The S3 bucket will be created and managed using Terraform, providing a reliable, declarative approach to setting up the infrastructure needed to store and reference these files.
领英推荐
resource "aws_s3_bucket" "example-cs-client-prod" {
bucket = "appstream_bucket"
tags = {
owner = "test"
managedby = "Terraform"
}
}
We will also make the bucket ‘private’ and establish a bucket policy for better security.
resource "aws_s3_bucket_acl" "example-cs-client-acl" {
bucket = aws_s3_bucket.example-cs-client-prod.id
acl = "private"
}
resource "aws_s3_bucket_policy" "example-cs-client-access" {
bucket = aws_s3_bucket.example-cs-client-prod.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAppStream2.0ToRetrieveObjects",
"Effect": "Allow",
"Principal": {
"Service": [
"cloudformation.amazonaws.com",
"appstream.amazonaws.com"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-cs-client-prod/example-cs-client.vhdx",
"arn:aws:s3:::example-cs-client-prod/mount-vhd.ps1"
]
},
{
"Sid": "allowReadOnlyPlusAppStreamAllAccessEdit",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/readOnlyPlusAppStreamAllAccess"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-cs-client-prod/example-cs-client.vhdx",
"arn:aws:s3:::example-cs-client-prod/mount-vhd.ps1"
]
}
]
}
EOF
}
We then upload the .vhdx , .ps1 and .png files to the bucket.
Next, we’ll transition into the deployment of the AppBlock, the AppStream Application, and the Elastic Fleet. At the time of this writing, Terraform does not yet support direct deployment of Elastic Fleets in AWS AppStream 2.0. Therefore, we will leverage AWS CloudFormation to handle this portion of the deployment. CloudFormation will be used to:
Step 2. Deploy the AppBlock: This involves referencing the files from the S3 bucket we created, which are packaged in the AppBlock. The AppBlock will define how the application is streamed to the users in a Windows environment.
resource "aws_cloudformation_stack" "appstream_appblock" {
name = "Appstream-AppBlock-example"
template_body = <<STACK
"Resources" : {
"FQP23TI6": {
"Type": "AWS::AppStream::AppBlock",
"Properties": {
"Description" : "example description",
"DisplayName" : "example_display_name",
"Name" : "example_client",
"SourceS3Location" : {
"S3Bucket" : "appstream_bucket",
"S3Key" : "appstream_client.vhdx"
},
"SetupScriptDetails" : {
"ExecutableParameters" : "-File mount-vhdx.ps1",
"ExecutablePath" : "c:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"ScriptS3Location" : {
"S3Bucket" : "appstream_bucket",
"S3Key" : "mount-vhdx.ps1"
},
"TimeoutInSeconds" : 60
}
}
}
}
STACK
}
Important notes: Since we will deploy Cloudformation though Terraform , we would need to manually edit in a unique ‘Local ID’ for the cloudformation resource. In this example it is ‘ADC55MI8’ Again , this is a use case where we use a Virtual Hard Disk (.vhdx) and a PowerShell Script (.ps1)to build our AppBlock, as seen in the resource configuration.
Step 3. Create the Application: The Application defines the user-facing elements, such as the executable, the PowerShell script (to configure runtime behaviors), and the icon file.
resource "aws_cloudformation_stack" "appstream_application" {
name = "Appstream-Application-example"
depends_on = [
aws_cloudformation_stack.appstream_appblock
]
template_body = <<STACK
"Resources" : {
"BDF37HI7": {
"Type" : "AWS::AppStream::Application",
"Properties" : {
"AppBlockArn" : "arn:aws:appstream:eu-central-1:123456789012:app-block/example_client_appbl",
"Description" : "example description",
"DisplayName" : "example_display_name",
"IconS3Location" : {
"S3Bucket" : "appstream_bucket",
"S3Key" : "client.png"
},
"InstanceFamilies" : ["GENERAL_PURPOSE"],
"LaunchParameters" : "/c f:\\suiteClientShell.bat",
"LaunchPath" : "c:\\Windows\\system32\\cmd.exe",
"Name" : "example_client_app",
"Platforms" : ["WINDOWS_SERVER_2019"],
"WorkingDirectory" : "f:\\"
}
}
}
STACK
}
Important notes: Application supports Amazon Linux 2 and Microsoft Windows 2019 only. The ‘AppBlockArn’ you will get when the resources AppBlock gets created via cloudformation.
Step 4. Provision the Elastic Fleet: The Elastic Fleet will dynamically scale based on user demand. Unlike other fleet types, Elastic Fleets do not require manually managed images or the need to provision fixed-capacity instances. This fleet will automatically allocate resources as needed and terminate them when they are no longer required, ensuring cost-efficiency.
resource "aws_cloudformation_stack" "appstream_elasticfleet" {
name = "Appstream-ElasticFleet"
template_body = <<STACK
"Resources" : {
"DSF28RN8": {
"Type": "AWS::AppStream::Fleet",
"Properties": {
"Description": "Appstream-Elastic-Fleet-Terraform",
"DisconnectTimeoutInSeconds": 900,
"DisplayName": "Display example client description",
"EnableDefaultInternetAccess": false,
"FleetType": "ELASTIC",
"IdleDisconnectTimeoutInSeconds": 900,
"InstanceType": "stream.standard.medium",
"MaxConcurrentSessions": 10,
"MaxUserDurationInSeconds": 32400,
"Name": "example_elasticfleet_name",
"Platform": "WINDOWS_SERVER_2019",
"StreamView": "APP",
"VpcConfig": {
"SecurityGroupIds": [
"sg-a1b2c3d4e5f6g7"
],
"SubnetIds": [
"subnet-xxxxxxxxxxxx1234",
"subnet-abcdefghi1234566"
]
}
}
}
}
STACK
}
Important notes: Since elastic fleet uses what we have created in Application, again, bear in mind that ‘Platform’ could only be Amazon Linux 2 or Microsoft Windows. Stream View will be ‘APP’. Security group is the ‘Firewall’ for appstream’s connectivity.
After the AppBlock, Application, and Elastic Fleet are deployed via CloudFormation, we will return to Terraform for the next steps. Terraform will be used to:
Step 5. Create an AppStream Stack: The Stack is a critical component that defines how users interact with the fleet. It includes settings for the environment in which the application runs, such as session duration, clipboard settings, and whether users can upload or download files.
resource "aws_appstream_stack" "example_stack" {
name = "example_stack_name"
display_name = "Example client display"
user_settings {
action = "CLIPBOARD_COPY_FROM_LOCAL_DEVICE"
permission = "ENABLED"
}
user_settings {
action = "CLIPBOARD_COPY_TO_LOCAL_DEVICE"
permission = "ENABLED"
}
user_settings {
action = "FILE_UPLOAD"
permission = "DISABLED"
}
user_settings {
action = "FILE_DOWNLOAD"
permission = "ENABLED"
}
application_settings {
enabled = true
settings_group = "example_client_appbl" #name of the app_block in the cloudformation stack
}
access_endpoints {
endpoint_type = "STREAMING" #for streaming through internet only
}
storage_connectors { #The default destination for the client's log files is the user's home directory, this is
connector_type = "HOMEFOLDERS" #configured in the logging.properties file in the client's conf directory.There is no other data stored on it.
}
}
Important notes: ‘endpoint_type’ also allows Virtual Private Cloud (VPC) endpoints , which allow your users to stream from AppStream 2.0 through your VPC.
Step 6. Associate the Fleet with the Stack: Through this Fleet-Stack Association, we ensure that the Elastic Fleet is linked to the AppStream Stack, allowing users to access the application streamed from the Elastic Fleet.
resource "aws_appstream_fleet_stack_association" "example-fleet-stack-association" {
fleet_name = "example_elasticfleet_name"
stack_name = aws_appstream_stack.example_stack.name
}
Step 7.Create an AppStream User: Finally, we’ll use Terraform to create a user in AppStream, who will be given access to the application. This user will be associated with the previously created Stack, ensuring they can log in and utilize the applications provisioned by the Elastic Fleet.
resource "aws_appstream_user" "example" {
authentication_type = "USERPOOL"
user_name = "[email protected]"
first_name = "John"
last_name = "Smith"
}
resource "aws_appstream_user_stack_association" "example" {
authentication_type = aws_appstream_user.example.authentication_type
stack_name = aws_appstream_stack.example_stack.name
user_name = aws_appstream_user.example.user_name
}
Important notes: After user creation, you will receive an email from Amazon where you will get a ‘Login page: Link’ and a temporary password which you can use to access the associated apps you have for your user, right after you change the temporary password.
Step 8. Logging in procedure.
Using the ‘Login page: Link’ you got in AWS’s email you will be redirected to a login page like this one:
After logging in you will get a page with all the applications your user is associated with, in our case:
Selecting your application will change your page to the AppStream2.0 app menu and will start loading your application:
Conclusion
In this post, we covered the deployment of an application in AWS AppStream 2.0 using Elastic Fleets, leveraging AppBlocks with Windows-specific components like .vhdx and .ps1. We used Terraform to manage the S3 bucket, stack, and user associations, and CloudFormation to deploy the Elastic Fleet and AppBlock, providing a scalable, cost-efficient solution and ensuring your applications are ready to stream when users need them, with minimal infrastructure overhead.