Desktop and Application Streaming

Announcing the Amazon WorkSpaces dynamic inventory plugin for Ansible®

Customers use Amazon WorkSpaces to get a fully managed remote desktop solution in the AWS cloud, supporting Windows and Linux desktops. They often ask how they can perform bulk management tasks such as automating the installation of applications. Currently, this requires manual systems administration or third-party tools.

Ansible is a free and open-source IT automation platform giving systems administrators the tools to work with both Windows and Linux fleets at scale. Today I am happy to announce the release of the Amazon WorkSpaces dynamic inventory plugin for Ansible. The project is available now on GitHub.

With the WorkSpaces inventory provider for Ansible, you will be able to perform systems administrations tasks on your WorkSpaces without needing to manually configure a list of hostnames or IP addresses.

Time to read 30 minutes
Time to complete 45 minutes
Cost to complete (estimated)

Cost of the Ansible control instance on EC2. If using a t3.micro Ubuntu 22.04 instance in us-east-1, this is approximately $7.60 per month.

This does not include networking and WorkSpaces infrastructure, which should already be in place.

Learning level Expert (400)
Services used Amazon WorkSpaces
AWS Identity and Access Management (IAM)
Amazon Elastic Compute Cloud (Amazon EC2)
AWS Systems Manager

Overview of solution

Sometimes, customers ask us if there is a way to take mass administrative actions against their WorkSpaces. Examples of these tasks include:

  • Listing installed programs.
  • Installing and upgrading programs.
  • Performing system patching.
  • Verifying patching compliance.

In order to help with these tasks, I am announcing an Amazon WorkSpaces dynamic inventory plugin for Ansible. Ansible can be used to perform a wide variety of tasks on Windows and Linux hosts.

In this blog, you will install Ansible on an EC2 Linux instance running Ubuntu 22.04. You will then clone the GitHub repo to the instance and set up the Ansible dynamic inventory provider. Afterwards, you will run a sample Ansible playbook included in the repository.

Walkthrough

Prerequisites

  • An AWS Account.
  • An existing Amazon WorkSpaces deployment.
  • Necessary IAM permissions to create and manage the components in this blog.
  • An Amazon Virtual Private Cloud (Amazon VPC) with internet access and a DNS resolution and network access to your Amazon WorkSpaces.
    • In order to manage Windows instances, the Ansible server needs to be able to obtain a Kerberos token to manage Windows instances.
  • Windows WorkSpaces require WinRM enabled. This can be done with Group Policy, and is outside the scope of this blog post. Further information is available in the GitHub readme.
  • Linux WorkSpaces will need an SSH key and Ansible service user added into the image before deployment. This is outside the scope of this blog post. Further information is available in the GitHub readme.

Creating the IAM role

First, you will need to create an IAM role for the EC2. The role needs to permit AWS Systems Manager Session Manager connectivity to the instance. The role also needs to permit the instance to access the DescribeWorkSpaces API.

  1. From the IAM console, choose Roles, then choose Create role.
  2. On the Select trusted entity page, select AWS service. Select EC2 in the Service or use case dropdown menu. Under choose a use case for the specified service, select EC2. Then choose Next.
  3. On the Add permissions page, select Next without choosing any policies. You will create the IAM policy in a later step.
  4. On the Name, review, and create page, enter a name and description for the role. The name can be something like “AnsibleRole”. Optionally, add tags to the role. Select Create role.
  5. In the list of IAM roles, find the role you just created and select it.
  6. Select the Add permissions dropdown menu and choose Create inline policy.
  7. In the resulting Specify Permissions page, select the JSON tab. Delete the pre-existing contents of the JSON policy editor and replace them with the JSON below, and then choose Next.
  8. Enter a policy name, such as AnsibleInlinePolicy, and select Create policy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "workspaces:DescribeWorkspaces",
                "ssm:UpdateInstanceInformation",
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}

You now have an IAM role that you can attach to your Ansible control node. The role will permit you to connect to the node with SSM Session Manager, and to use the DescribeWorkSpaces API.

For more information, see the SSM documentation on the Session Manager permissions.

Networking setup

The Ansible EC2 instance will require access to your WorkSpaces. In order to facilitate this, you will create a new Security Group for the Ansible instance to use permitting access from this security group to your WorkSpaces.

To create the Ansible Security Group

  1. From the EC2 console under Networking & Security, select Security Groups, then select Create security group.
  2. Use the following options and values for the new Security Group.
    1. Security group name: AnsibleControl
    2. Description: Permit Ansible nodes to manage WorkSpaces.
    3. VPC: The VPC where your WorkSpaces are deployed.
    4. Inbound rules: Leave this empty.
    5. Outbound rules: Select Add rule. Select the dropdown under Type, select All traffic.
    6. Under the Tags section, add any tags as desired
  3. Select Create security group.

Permitting inbound access from the Ansible security group

In this section, you will modify your WorkSpaces security group to permit inbound management traffic from the Ansible security group.

  1. From the Amazon WorkSpaces console, select Directories. Locate the directory associated with the WorkSpaces you wish to manage, and note the Directory ID.
  2. From the EC2 console in the Networking & Security section, select Security Groups.
  3. Locate the default Security Group for your WorkSpaces. The security group for WorkSpaces has a name that consists of the directory identifier, followed by _workspacesMembers . Use the directory ID obtained from Step 1 to locate the default Security Group for your WorkSpaces.
    1. You can alternately create a custom Security Group for this, and use this blog to ensure all your WorkSpaces have the custom Security Group attached.
  4. Under the Inbound rules tab, select the Edit inbound rules button.
  5. Select Add rule.
  6. For Type, select SSH. Under the Source column, leave the dropdown on Custom. In the text field to the right, type AnsibleControl. This will prompt the dropdown to offer the Security Group ID of the AnsibleControl group. Select the group ID.
  7. Repeat steps 3 and 4, choosing the WinRM-HTTPS and WinRM-HTTP options for Type.
  8. Choose Save rules.

Your WorkSpaces security group will now permit inbound SSH, WinRM (HTTP), and WinRM (HTTPS) traffic, from EC2 instances using the AnsibleControl Security Group. This will enable your Ansible node to control your Windows and Linux based WorkSpaces.

Create the Ansible control server

To create the Ansible control server

  1. From the EC2 console, select Instances (running) then select Launch Instances.
  2. Provide a name for your instance. Example: AnsibleControlServer .
    From the Quick Start section, select Ubuntu then select Ubuntu Server 22.04 LTS (HVM), SSD Volume Type from the Amazon Machine Image (AMI) dropdown.
  3. Under Instance Type select t3.micro. If you desire, you may use a larger instance type, but the pricing example in the overview is based on t3.micro in the us-east-1 region.
  4. Key pair (login): Select a key pair you have access to or select Create a new key pair to create a new one.
  5. In the Network Settings section, use the following options:
    VPC: Choose the VPC for your Amazon WorkSpaces.
    Subnet: Choose a private subnet your WorkSpaces VPC.
    Auto-assign public IP: disabled
    Firewall (security groups): Choose the Select existing security group radio button and select the AnsibleControl security group created earlier.
  6. Configure storage: This can be left at the default volume size. Encryption is optional based on your organization’s policies.
  7. Expand the Advanced Details tab. In the IAM instance profile dropdown, select the IAM role you created in the previous section, “Creating an IAM Role”.
  8. Select Launch instance.

The instance will take approximately 5 minutes to create and become accessible.

Connecting to the server

  1. From the EC2 console select the AnsibleControlServer instance and select Connect.
  2. In the resulting window, select the Session Manager tab, then select Connect.

You should now be connected to the instance with the SSM Session Manager. Session Manager uses the sh shell by default. Begin by typing bash and pressing Enter. This will start the bash shell, which has improved interactivity.

Installing Ansible

Run the following commands, making sure to run the pip3 command as written, not with sudo in front of it. The first command ensures the current working directory is your home directory.

cd ~
git clone https://github.com/aws-samples/workspaces-with-ansible
sudo add-apt-repository --yes ppa:ansible/ansible
sudo apt update
sudo apt-get install python3-pip ansible jq realmd krb5-user -y
pip3 install boto3

You will see a Configuring Kerberos Authentication pop-up, as shown below, as a result of installing the krb5-user package. Bypass this without entering anything by pressing enter.

This image depicts the "Configuring Kerberos Authentication" popup. This should be bypassed without entering anything, by pressing "enter".

If you get a popup like the below Daemons using outdated libraries example, remove any selections before pressing enter. To do this, use your arrow keys to navigate the list, and your spacebar to remove the asterisk from all the entries in the list. Then, press your enter key to finalize your selection. In the below screenshot, you would move your arrow key down to polkit.service, press spacebar, and then press enter to finalize your selection.

This image depicts the "Daemons using outdated libraries" popup during the `apt install` process, and it is asking which of the services should be restarted.

You have now installed Ansible, along with important prerequisites it will require for use with WorkSpaces. You have also cloned the GitHub repository for this project into your home directory. The repository includes some example Ansible playbooks for Windows and Linux hosts that you can review.

Listing WorkSpaces

At this stage, you can now utilize the Ansible inventory provider in order to list your WorkSpaces.

  1. Begin by marking your Ansible inventory provider as executable:
    chmod +x ~/workspaces-with-ansible/workspaces_inventory_provider.py
  2. Specify the region for your WorkSpaces deployment using an environment variable. Replace us-west-2 with your desired region.
    export AWS_REGION=us-west-2
  3. You can now test run the inventory provider in one of two ways:
    1. Execute the inventory provider Python script by itself, using the –list argument.
      ~/workspaces-with-ansible/workspaces_inventory_provider.py --list
    2. Execute the ansible-inventory command, specifying the Python script as the inventory provider.
      ansible-inventory -i ~/workspaces-with-ansible/workspaces_inventory_provider.py --graph

Here is a screenshot showing the ansible-inventory command with the --graph argument. Note that the output separates the WorkSpaces based on their Operating System.

This picture depicts the `ansible-inventory` command when used with the WorkSpaces dynamic inventory provider module Python script.

Here is an example using the Python script directly. This image shows fewer WorkSpaces in an active state, as the Python script’s direct output is much more verbose. One thing to note in the direct script output is that Windows WorkSpaces have their hostnames overridden in place of the IP addresses. This is because the default behavior for Windows and Kerberos is to reject connection requests made directly to IP addresses.

This picture depicts output from using the `workspaces_inventory_provider.py` Python script directly, instead of through the `ansible-inventory` command.

Obtaining a Kerberos token

In order to manage Windows instances using WinRM, you will need to obtain a Kerberos token. The syntax to obtain a token looks like this:

kinit user@EXAMPLE.COM

Note: The domain name must be in all caps. You can then validate the token is working with the klist command. For example, see the below output.

ssm-user@ip-10-0-2-235:~$ kinit dan1@EXAMPLE.COM
Password for dan1@EXAMPLE.COM:
ssm-user@ip-10-0-2-235:~$ klist
Ticket cache: FILE:/tmp/krb5cc_1001
Default principal: dan1@EXAMPLE.COM

Valid starting     Expires            Service principal
04/18/24 00:32:22  04/18/24 10:32:22  krbtgt/EXAMPLE.COM@EXAMPLE.COM
        renew until 04/19/24 00:32:19
ssm-user@ip-10-0-2-235:~$

Utilizing the dynamic inventory provider

Now that initial setup is complete, you can proceed to utilize your existing Ansible playbooks for Windows and Linux, using this dynamic inventory provider to target WorkSpaces. To do this, use the -i argument to specify the WorkSpaces dynamic inventory provider, and the -e argument to specify the target_hosts. Valid arguments for target_hosts are windows_workspaces , amazonlinux_workspaces , and ubuntu_workspaces .

Cleanup

To remove the solution, perform the following steps:

  1. Delete the EC2 instance serving as the Ansible control server.
  2. Remove the Ansible IAM role. This will also delete the in-line policy.
  3. Remove the WinRM changes to your default WorkSpaces security group.

Conclusion

You have finished setting up the EC2 instance with Ansible, and performed initial setup for the WorkSpaces dynamic inventory provider. If you have existing Ansible playbooks, you can proceed to use them as normal.

If you do not have any existing Ansible playbooks, the GitHub repo comes with some sample playbooks for Windows and Linux hosts. Please see the Ansible documentation for more information. Ansible documents have a specific section for Windows. The GitHub repo also contains further setup and use information, will be updated, and can be used to report issues or make feature requests.

Dan is a Senior AWS End User Compute Solutions Architect, focusing on helping customers configure and optimize end-user computing solutions. Dan also focuses on EC2, Microsoft, and Linux based workloads. Dan has been at AWS since March 2016, and was a Premium Support escalation engineer and Specialist Technical Account Manager prior to becoming a specialist Solutions Architect.