Desktop and Application Streaming

Create a notification for changes to Amazon WorkSpaces gateway ranges

From time to time, the Amazon WorkSpaces service will add additional IP ranges to the service’s streaming gateways. This provides additional capacity to customers to give a first-rate streaming experience. When changes like this are staged, and deployed, we alert customers via email and the Personal Health Dashboard. A common customer ask is for a way to receive alerts for these changes that can be used programmatically.

Overview

In this blog, I show how you can set up an alert via email when a change is made to the gateway ranges. Services you use include Amazon CloudWatch, AWS Lambda, Amazon S3, and the Amazon Simple Notification Service.

Prerequisites

  • An AWS account and access to the AWS Management Console with permissions to create Amazon S3 buckets, Amazon SNS topics, and AWS Lambda functions.
  • Access to AWS Identity and Access Management (IAM), with permissions to create roles and policies.
  •  An IAM user with programmatic access, and permissions to create new Lambda functions.
  • AWS Tools for Windows PowerShell or AWS Tools for PowerShell Core.
  • The AWSPowerShell.NetCore PowerShellModule.
  • The AWSLambdaPSCore module PowerShell Module.
  • .NET Core 3.1 SDK installed.

Walkthrough

Step 1: Create an Amazon SNS topic and subscription

In this step, you create an SNS topic and subscription that alerts via email if gateways change.

  1. Open the Amazon SNS console
  2. Select Topics
  3. Choose Create Topic, and select “Standard” for topic type
  4. Provide a Name. Optionally provide a Display Name
  5. Choose Create Topic
  6. Make note of the topic ARN
  7. From the Amazon SNS console, choose “Subscriptions”
  8. Choose Create Subscription
  9. In Topic ARN, enter the ARN that you noted earlier
  10. In Protocol, choose Email
  11. Then enter the email addresses you want to get the notification.
  12. Choose Create Subscription

Step 2: Create an Amazon S3 Bucket

In this step, we are going to create the S3 Bucket that we will use to store and access our CSV files.

  1. Open the Amazon S3 console
  2. Choose Create bucket
  3. Provide a Bucket name
  4. Choose Object Ownership (It is recommended you use the default Object Ownership)
  5. Check the option for “Block Public Access for this Bucket”
  6. Optionally Enable Tags and versioning
  7. Optionally, enable encryption
  8. Choose Create bucket
  9. Make note of the Bucket name

Step 3: Create an IAM role for your Lambda function

Now we are going to create an IAM role for out Lambda Function.

  1. Open the IAM console
  2. In the navigation pane, choose Roles
  3. Choose Create Role
  4. For “Trusted entity type,” select “AWS service”
  5. For “Choose the service that will use this role,” select Lambda
  6. Select Next
  7. Choose Create policy
  8. In the JSON tab, enter the following. Replace “SNSARN” and “S3BucketName” with the names that you created in the Step 1 and Step 2:
    
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject",
                    "s3:GetObject",
                    "sns:Publish"
                ],
                "Resource": [
                    "arn:aws:s3:::S3BucketName",
                    "arn:aws:s3::: S3BucketName/*",
                    "SNSARN"
                ]
            }
        ]
    }
    
  9. Choose Next: Tags
  10. Choose Next: Review
  11. Provide a Name and Description
  12. Choose Create policy

Step 4: Create a new Lambda function

In this step, you create the Lambda function to check the WorkSpace IP gateway, and send an email.

  1. Open the Lambda console
  2. Choose Create function
  3. Select Author from scratch
  4. Give the function a name. In the example, I use wksrange
  5. Select .NET Core 3.1 (C#/PowerShell) as the Runtime
  6. For Permissions, expand Change  default execution role
  7. Select Create a new role with basic Lambda permissions
  8. Select Create function
  9. Select Configuration, then select the Environment variables option
  10. Select Edit, then Add environment variable
  11. Enter s3bucket as the Key. Provide the name of your S3 bucket as the Value
  12. Select Add environment variable
  13. Enter snstopic as the Key, provide the arn of your Amazon SNS topic as the Value
  14. Select Add environment variable
  15. Enter targetregion as the third Key, provide an AWS region as the Value (for example “us-east-1”)
  16. Select Save
  17. Choose Permissions
  18. In the Execution role section Choose your execution role name link
  19. This will open the IAM console. Select Add Permissions and choose Attach policies
  20. Find and select the policy you created in step 3
  21. Choose Attach policy

Step 5: Upload the Lambda code to the Lambda function

In this step, we will upload our Lambda code to the Lambda function.

    1. Open your PowerShell editor of choice. Create a new script. Give it a name. In my example I use wsrange-lambda.ps1.
    2. Enter the following code:
      #Requires -Modules AWS.Tools.Common, AWS.Tools.S3,AWS.Tools.SimpleNotificationService
      
      #Env Variables
      $s3Bucket = $($env:s3bucket)
      $snsTopic = $($env:snstopic)
      $targetRegion = $($env:targetregion)
      $tmp = "/tmp"
      
      try{$currentRanges = Get-AWSPublicIpAddressRange -Region $targetRegion -ServiceKey WORKSPACES_GATEWAYS -ErrorAction Stop}
      catch{write-host "ERROR: Unable to retrive ranges for the specified region"}
      $today = get-date -format 'MMddyy'
      $yesterday = ((get-date).adddays(-1)).ToString('MMddyy')
      
      #write current to S3
      $todayfile = "$targetRegion`_$today.csv"
      $currentRanges |export-csv "$tmp/$todayfile"
      try{Write-S3Object -BucketName $s3Bucket -File "$tmp/$todayfile" -ErrorAction Stop}
      catch{Write-Host "ERROR: Unable to write updated range to S3"}
      
      #retrive csv from prior day
      $yesterdayfile = "$targetRegion`_$yesterday.csv"
      try{Read-S3Object -BucketName $s3Bucket -File  "$tmp/$yesterdayfile" -Key $yesterdayfile -ErrorAction Stop}
      catch{Write-Host "ERROR: Unable to read previous object from S3. This is expected if this is the first run."}
      if(Test-Path "$tmp/$yesterdayfile" ){
          $yesterdaycsv = Import-Csv "$tmp/$yesterdayfile"
      
          #diff objects
          try{$difference = Compare-Object $yesterdaycsv.IpPrefix $currentRanges.IpPrefix -ErrorAction stop}
          catch{Write-Host "ERROR: An Error was encountered when trying to diff the range data"}
      
          $changes = @()
          Foreach($item in $difference){
              switch($item.SideIndicator){
                  "=>" {$changes += "$($item.InputObject) has been added to the WorkSpaces Gateway range in $targetRegion"}
                  "<=" {$changes += "$($item.InputObject) has been removed from the WorkSpaces Gateway range in $targetRegion"}
                  default {write-host "WARN: Unexpected behavior encountered in Diff operation"}
              }
          }
      
          If($changes){
              foreach ($change in $changes){
                  Write-Host "Sending to SNS"
                  try{Publish-SNSMessage -TopicArn $snsTopic -Message $change -Subject "A change to the Amazon WorkSpaces Gateway range has been detected in $targetRegion" -ErrorAction stop}
                  catch{Write-Host "ERROR: Unable to send to SNS"}
              }
          }
      }
      
    3. Save the file
    4. Open a PowerShell terminal
    5. Import the AWSLambdaPSCore module by typing the following:
    6. Import-Module AWSLambdaPSCore
    7. Publish your script to the Lambda function you created earlier with the following command.
      Publish-AWSPowerShellLambda -ScriptPath .\your-lambda-script-name.ps1 -Name your-function-name -Region your-region
    8. Select the IAM Role that you created in Step 4, and select Enter

Step 6: Create a CloudWatch Event Source

  1. Open the Lambda console
  2. Select Functions
  3. Select the Lambda function that you created in Step 5
  4. Choose + Add trigger
  5. For Trigger configuration select EventBridge (CloudWatch Events) in the combo box
  6. Select Create a new rule
  7. Provide a Rule name and Rule description
  8. Select Scheduled expression as the Rule type
  9. In the Schedule expression box enter “cron(0 */12 * * ? *)” without the quotation marks.
  10. Choose Add

Step 7: Test the Lambda Function and SNS topic

  1. Open the Lambda console
  2. Select Functions
  3. Select the Lambda function you created in Step 5
  4. Select the Test Tab
  5. Choose Test
  6. Once the test has been completed open your S3 bucket, and download the CSV file
  7. Open the CSV file, remove a row from the CSV file save CSV file
  8. Change the name of the file to a previous day date and upload the file back to your S3 bucket
  9. Repeat stages (1-5) in this Step once the test is complete to receive an email with the new IpPrefix.

Conclusion

In this blog, you set up an alert via email when a change is made to the Amazon WorkSpaces gateway ranges. You configured this using Amazon CloudWatch, AWS Lambda, Amazon S3, and the Amazon Simple Notification Service.

If you want to understand other WorkSpaces best practices, review the best practices for deploying Amazon WorkSpaces.