Automating AWS WorkSpaces Tier Management with CloudFormation
Tags: aws, cloud
Published: 2023-09-06 19:23:58



## Introduction

Managing resources efficiently is crucial in any cloud environment. In the context of AWS WorkSpaces, keeping track of CPU utilization and making timely tier changes can help in optimizing costs and performance. This article presents a CloudFormation template that automatically manages AWS WorkSpaces tiers based on CPU utilization.

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  # CloudWatch Alarms for CPU Utilization
  CpuUtilizationAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: CpuHighUtilizationAlarm
      AlarmDescription: Trigger when CPU Utilization is high
      Namespace: AWS/WorkSpaces
      MetricName: CPUUtilization
      Statistic: Average
      Period: 300
      EvaluationPeriods: 1
      Threshold: 80
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - Ref: TierManagementSNSTopic

  CpuUtilizationAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: CpuLowUtilizationAlarm
      AlarmDescription: Trigger when CPU Utilization is low
      Namespace: AWS/WorkSpaces
      MetricName: CPUUtilization
      Statistic: Average
      Period: 300
      EvaluationPeriods: 1
      Threshold: 20
      ComparisonOperator: LessThanOrEqualToThreshold
      AlarmActions:
        - Ref: TierManagementSNSTopic

  # SNS Topic to be triggered by CloudWatch Alarms
  TierManagementSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: WorkSpaceTierManagement

  # Lambda function to change WorkSpace tier
  WorkSpaceTierChangeLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: WorkSpaceTierChange
      Handler: index.handler
      Role: arn:aws:iam::your-account-id:role/execution_role
      Code:
        ZipFile: |
          import boto3
          import json

          workspaces_client = boto3.client('workspaces')

          def handler(event, context):
              sns_message = json.loads(event['Records'][0]['Sns']['Message'])
              alarm_name = sns_message.get('AlarmName', 'default-alarm')

              # Fetch all WorkSpaces in a specific directory
              directory_id = "your-directory-id-here"
              workspaces = workspaces_client.describe_workspaces(DirectoryId=directory_id)['Workspaces']

              for workspace in workspaces:
                  workspace_id = workspace['WorkspaceId']

                  if 'High' in alarm_name:
                      change_workspace_tier(workspace_id, 'POWERPRO')
                  elif 'Low' in alarm_name:
                      change_workspace_tier(workspace_id, 'POWER')

          def change_workspace_tier(workspace_id, new_tier):
              try:
                  response = workspaces_client.modify_workspace_properties(
                      WorkspaceId=workspace_id,
                      WorkspaceProperties={
                          'ComputeTypeName': new_tier
                      }
                  )
                  print(f"Changed tier of {workspace_id} to {new_tier}")
              except Exception as e:
                  print(f"Failed to change tier: {e}")
              
      Runtime: python3.8
      Timeout: 5

  # SNS Subscription to Lambda
  SNSTopicSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: lambda
      TopicArn: !Ref TierManagementSNSTopic
      Endpoint: !GetAtt [WorkSpaceTierChangeLambdaFunction, Arn]
```


The CloudFormation template comprises the following key components:

### 1. CloudWatch Alarms

Two CloudWatch Alarms are defined:

- `CpuUtilizationAlarmHigh`: Triggers when CPU Utilization is above 80%.
- `CpuUtilizationAlarmLow`: Triggers when CPU Utilization is below 20%.

### 2. SNS Topic

The `TierManagementSNSTopic` is an SNS Topic that will receive notifications from the CloudWatch Alarms.

### 3. Lambda Function

The `WorkSpaceTierChangeLambdaFunction` is triggered when an SNS notification is received. It changes the tier of WorkSpaces based on the alarm conditions.

### 4. SNS Subscription

The `SNSTopicSubscription` subscribes the Lambda function to the SNS Topic, allowing the function to be invoked when an alarm triggers.

## Pre-requisites

- AWS CLI installed and configured
- A valid AWS WorkSpaces setup
- IAM role with sufficient permissions for CloudWatch and WorkSpaces (`execution_role`)

## Deployment Instructions

Follow these steps to deploy the CloudFormation template:

### 1. Validate the Template

First, validate the CloudFormation template to ensure it is well-formed.

```bash
aws cloudformation validate-template --template-body file://path/to/template.yaml
```

### 2. Upload the Template to S3 (Optional)

You can upload the template to an S3 bucket if it's too large or if you prefer to keep it centralized.

```bash
aws s3 cp path/to/template.yaml s3://your-s3-bucket/
```

### 3. Deploy the Stack

You can deploy the CloudFormation stack using the AWS CLI.

```bash
# If template is local
aws cloudformation create-stack --stack-name WorkSpacesTierManagement --template-body file://path/to/template.yaml

# Or if template is in S3
aws cloudformation create-stack --stack-name WorkSpacesTierManagement --template-url https://s3.amazonaws.com/your-s3-bucket/template.yaml
```

### 4. Monitor the Stack

You can monitor the status of the stack in the AWS CloudFormation console or via the AWS CLI.

```bash
aws cloudformation describe-stacks --stack-name WorkSpacesTierManagement
```

## Conclusion

This CloudFormation template offers an automated approach to manage AWS WorkSpaces tiers based on CPU utilization, thus optimizing resource usage. Deploying this stack in your AWS environment can significantly streamline your WorkSpaces management process.