Enable Remote Work or Learning for Employees and Students in minutes using AWS WorkSpaces
Remote Work and Learning

Enable Remote Work or Learning for Employees and Students in minutes using AWS WorkSpaces

There are scenarios when companies need to take quick actions in order to support the business. Currently, there is a growing demand for IT resources and services that can allow people to learn and work remotely.

One of these services is AWS WorkSpaces. It gives you an opportunity to provision a virtual, cloud-based Microsoft Windows or Amazon Linux desktops which users can access remotely from Windows, Mac or Linux (Ubuntu) computers, Chromebooks, iPads, Fire tablets, Android tablets, and the Chrome and Firefox web browsers.

Remote Work and Learning connectivity options

In this post, I would like to introduce you briefly to this service, demonstrate several ways how you can quickly configure and start using it.

No alt text provided for this image

General information about AWS WorkSpaces service:

OS:

  • Amazon Linux 2 LTS
  • Windows 10 desktop, powered by Windows Server 2016

Apps:

Amazon Linux WorkSpaces: come with a curated selection of applications at no additional cost that includes LibreOffice, Firefox Web Browser, Evolution mail, Pidgin IM, GIMP, and other desktop utilities and tools. You can always add more software from the Amazon Linux repositories using yum.

Windows WorkSpaces: Internet Explorer 11, and Firefox. You can choose to add “Plus” application bundles to your Amazon WorkSpaces with Windows 10 which include Microsoft Office Professional 2016, and Trend Micro Worry-Free Business Security, for an additional monthly fee.

You can also create a custom image from one of your WorkSpaces to create your own installed software bundle.

Storage:

Service provides each user with access to varying amounts of persistent storage (SSD Volumes). Data that users store on the ‘user volume’ attached to the WorkSpace is automatically backed up to Amazon S3 (99.999999999% durability) on a regular basis. If necessary, you can always increase the size of the root and user volumes attached to your WorkSpaces at any time.

If Amazon WorkDocs Sync is enabled on a WorkSpace, the folder a user chooses to sync will be continuously backed up and stored in Amazon WorkDocs.

Security:

WorkSpaces lets you manage which client devices can access it based on:

  • IP address;
  • Client device type;
  • Through the use of your digital certificates;

Integrated with KMS and allows you to use KMS customer master keys (CMK) to encrypt the storage volumes. Data encrypted both in transit and at rest. Compliance: SOC, PCI, FedRAMP, HIPAA, and others


Let’s start WorkSpaces service configuration:

1. Check if AWS WorkSpaces service is available in your region. You can always choose another region closest to you if your region is not present. If you are located more than 2000 miles from the regions where Amazon WorkSpaces is currently available, you can still use the service, but your experience may be less responsive. Check performance here: https://clients.amazonworkspaces.com/Health.html

2. Decide which managed directory service you would like to use and if it is available in your region: AWS Managed Microsoft AD or Simple Active Directory. (not covered by this post, but you also have an option to use AD Connector which is a proxy for redirecting directory requests to your existing Microsoft Active Directory without caching any information in the cloud).

Note: Simple AD and AD Connector are made available to you free of cost to use with WorkSpaces, WorkMail, or WorkDocs.

3. Create AWS resources on which AWS WorkSpaces service will rely on, such as VPC, Private and Public Subnets, InternetGateway, EIPs, NAT Gateways, RouteTables, RouteTableAssociations, and finally AWS Managed Directory service.

AWS Security best practice is to avoid using default VPC and make sure you always create and configure your own AWS infra resources depending on your needs and company requirements.

In order to provision necessary AWS resources, you can use this CloudFormation template.

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS resources required for WorkSpaces service

Parameters:

  ADName:
    Description: AWS managed Directory Name
    Type: String
    Default: "corp.example.com"
  DirAdmninPass:
    NoEcho: true
    Description: AD Admin Password (must not contain the word admin, and include three of these four categories lowercase, uppercase, numeric, and special characters)
    Type: String
    MinLength: 8
    MaxLength: 64
  VPCCIDRBlock:
    Type: String
    Default: "172.30.0.0/16"
  NATSubnetA:
    Type: String
    Default: "172.30.254.0/24"
  NATSubnetB:
    Type: String
    Default: "172.30.255.0/24"
  PriSubnetA:
    Type: String
    Default: "172.30.1.0/24"
  PriSubnetB:
    Type: String
    Default: "172.30.2.0/24"

  # ADNetBIOSName:
  #   Description: Directory NetBIOS Name
  #   Type: String
  #   Default: "CORP"

Resources:

  # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---  
  # create VPC, Private and Public Subnets, InternetGateway, EIPs, NAT Gateways, RouteTables, RouteTableAssociations

  AttachGateway:
    Properties:
      InternetGatewayId: !Ref 'InternetGateway'
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::VPCGatewayAttachment
  InternetGateway:
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-ig
    Type: AWS::EC2::InternetGateway
  MainRouteTable:
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PublicRouteTable-Main
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::RouteTable
  NATRoutePriSubnet1a:
    DependsOn: NATa
    Properties:
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref 'NATa'
      RouteTableId: !Ref 'PrivateRouteTablePriSubnet1a'
    Type: AWS::EC2::Route
  NATRoutePriSubnet1b:
    DependsOn: NATb
    Properties:
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref 'NATb'
      RouteTableId: !Ref 'PrivateRouteTablePriSubnet1b'
    Type: AWS::EC2::Route
  NATa:
    Properties:
      AllocationId: !GetAtt 'NatEipa.AllocationId'
      SubnetId: !Ref 'PubSubnetNATa'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-NATa
    Type: AWS::EC2::NatGateway
  NATb:
    Properties:
      AllocationId: !GetAtt 'NatEipb.AllocationId'
      SubnetId: !Ref 'PubSubnetNATb'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-NATb
    Type: AWS::EC2::NatGateway
  NatEipa:
    Properties:
      Domain: vpc
    Type: AWS::EC2::EIP
  NatEipb:
    Properties:
      Domain: vpc
    Type: AWS::EC2::EIP
  PriSubnet1a:
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}a"
      CidrBlock: !Ref PriSubnetA
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PriSubnet1a
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::Subnet
  PriSubnet1b:
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}b"
      CidrBlock: !Ref PriSubnetB
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PriSubnet1b
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::Subnet
  PrivateRouteTablePriSubnet1a:
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PrivateRouteTablePriSubnet1a
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::RouteTable
  PrivateRouteTablePriSubnet1b:
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PrivateRouteTablePriSubnet1b
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::RouteTable
  PubSubnetNATa:
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}a"
      CidrBlock: !Ref NATSubnetA
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PubSubnetNATa
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::Subnet
  PubSubnetNATb:
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}b"
      CidrBlock: !Ref NATSubnetB
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-PubSubnetNATb
      VpcId: !Ref 'VPC'
    Type: AWS::EC2::Subnet
  Route:
    DependsOn: AttachGateway
    Properties:
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref 'InternetGateway'
      RouteTableId: !Ref 'MainRouteTable'
    Type: AWS::EC2::Route
  SubnetRouteTableAssociationPriSubnet1a:
    Properties:
      RouteTableId: !Ref 'PrivateRouteTablePriSubnet1a'
      SubnetId: !Ref 'PriSubnet1a'
    Type: AWS::EC2::SubnetRouteTableAssociation
  SubnetRouteTableAssociationPriSubnet1b:
    Properties:
      RouteTableId: !Ref 'PrivateRouteTablePriSubnet1b'
      SubnetId: !Ref 'PriSubnet1b'
    Type: AWS::EC2::SubnetRouteTableAssociation
  SubnetRouteTableAssociationPubSubnetNATa:
    Properties:
      RouteTableId: !Ref 'MainRouteTable'
      SubnetId: !Ref 'PubSubnetNATa'
    Type: AWS::EC2::SubnetRouteTableAssociation
  SubnetRouteTableAssociationPubSubnetNATb:
    Properties:
      RouteTableId: !Ref 'MainRouteTable'
      SubnetId: !Ref 'PubSubnetNATb'
    Type: AWS::EC2::SubnetRouteTableAssociation
  VPC:
    Properties:
      CidrBlock: !Ref VPCCIDRBlock
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Name
          Value: workspaces-vpc
    Type: AWS::EC2::VPC
  # --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---  

  # create AWS managed Simple Directory
  SimpleAD: 
    Type: AWS::DirectoryService::SimpleAD
    Properties: 
      Name: !Ref ADName
      Password: 
        Ref: DirAdmninPass
      Size: Small # or Large
      VpcSettings: 
        SubnetIds: 
          - Ref: PriSubnet1a
          - Ref: PriSubnet1b
        VpcId: 
          Ref: VPC

  # # create AWS managed Microsoft Active Directory
  # MicrosoftAD: 
  #   Type: AWS::DirectoryService::MicrosoftAD 
  #   Properties: 
  #       Name: !Ref ADName
  #       Password: 
  #         Ref: DirAdmninPass
  #       Edition: Standard # or Enterprise
  #       ShortName: 
  #         Ref: ADNetBIOSName
  #       VpcSettings: 
  #         SubnetIds: 
  #             - Ref: PriSubnet1a
  #             - Ref: PriSubnet1b
  #         VpcId: 
  #             Ref: VPC

In case you would like to change something in the template as this networking stuff within CloudFormation looks confusing for you, please check one of my previous posts about Python script with troposphere library which creates a CloudFormation template for you. By using that troposphere script, you will be able to generate a new CloudFormation template quickly and easily by simply answering a few questions.


Now you should decide which path to choose …

Path #1 [Fast and Simple] — If you work in a small company with only few users and you need to enable them ASAP, I will probably recommend you to consider using AWS Management Console directly, at least for now.

  • Navigate to WorkSpaces
  • Select Directory that has been just created using CloudFormation template
  • Create users by providing necessary details
  • Select Bundle and WorkSpace configuration

As a result, users will receive an email with further step-by-step instructions on how to connect and start working. Path #1 is done, please find screenshots bellow.

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

Path #2 [Longer and more complex] Launch EC2 instance with necessary management tools installed using userdata and join instance to the domain. RDP to it and create users.

Install-WindowsFeature -Name GPMC,RSAT-AD-PowerShell,RSAT-AD-AdminCenter,RSAT-ADDS-Tools,RSAT-DNS-Server

As soon as users are created, you can either provision AWS WorkSpaces for them using CloudFormation template (please see example below) or use the combination of the same CloudFormation template and AWS Service Catalog. That will allow your AWS users create or delete their own WorkSpaces when they need.

AWSTemplateFormatVersion: '2010-09-09'
Description: WorkSpaces Template

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: "WorkSpace Configuration"
        Parameters:
          - Bundle
          - Directory
          - User
          - EncryptionKey
    ParameterLabels:
      Bundle:
        default: "WorkSpace Bundle"
      Directory:
        default: "WorkSpace Directory"
      User:
        default: "WorkSpace Owner"
      EncryptionKey:
        default: "Encryption Key"

Parameters:

  Bundle:
    Type: String
    Description: Select the bundle that should be deployed
    Default: "wsb-xxxxx" # aws workspaces describe-workspace-bundles --owner AMAZON
  Directory:
    Type: String
    Description: Enter the Directory ID for the WorkSpace (Directory Services or AD Connector)
    Default: "d-xxxxxx"
  User:
    Type: String
    Description: Enter the username who will use the WorkSpace
    AllowedPattern: ^[a-z0-9]{1,20}$
    ConstraintDescription: user must be entered using lower case letters and numbers and a maximum of 20 characters
  EncryptionKey:
    Type: String
    Description: Select the KMS encryption key to encrypt WorkSpace volumes
    Default: "arn:aws:kms:us-east-1:xxxxxxxxxx:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Resources:

  WorkSpace:
    Type: AWS::WorkSpaces::Workspace
    Properties:
      BundleId: !Ref Bundle
      DirectoryId: !Ref Directory
      UserName: !Ref User
      RootVolumeEncryptionEnabled: 'true'
      UserVolumeEncryptionEnabled: 'true'
      VolumeEncryptionKey: !Ref EncryptionKey

Outputs:
  WorkSpaceId:
    Description: ID of the WorkSpaces
    Value: !Ref WorkSpace

Path #3 [Longer, Complex, and Right :) ]

If you have experience automating stuff end-to-end, you probably already have your own plan how to accomplish it :) For those of you who just starting please consider using: GitHub + Jenkins + (CloudFormation+Jinja2 or AWS CDK or Terraform).


I hope you found this post clear and useful. I didn’t want to overload you with too much information. At the same time, I added links where it was necessary so you can easily find more details.

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics