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.
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.
- About: https://aws.amazon.com/workspaces/
- Documentation: https://docs.aws.amazon.com/workspaces/
- Pricing: https://aws.amazon.com/workspaces/pricing/
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.
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.