Teleport – How to use it with Ansible?
In modern IT environments, managing secure remote access to servers is essential. Teleport provides a secure framework for accessing servers and databases, and when integrated with Ansible, it enhances both the security and efficiency of deploying and managing software. This article will guide you through integrating Teleport with Ansible, combining their strengths to improve security and streamline access control in automation processes.
Prerequisites
- A running Teleport cluster version 15.4.0 or above.
- The
tsh
client tool. ssh
openssh toolansible
>= 2.9.6
Versions that I used:
- Teleport cluster version 15.4.7
- Ansible 2.15.10
- Openssh 3.0.13
Setting up Teleport
For connecting to servers integrated within a Teleport cluster, it’s first necessary to generate Teleport certificates using the tsh
command. We must verify that we have access to the servers we intend to configure with Ansible and with what user we can login in the server.
- Login into Teleport with the console, using tsh:
tsh login --proxy={teleport_proxy} --user={teleport_user}
- Generate openssh configuration using tsh:
tsh config > teleport.cfg
This command queries the Teleport cluster for the necessary configuration details and then outputs these settings directly into a file named teleport.cfg
. This file effectively captures the specific setup of your Teleport environment, including the SSH configurations and authentication parameters required for secure connections.
Example of teleport.cfg:
# Begin generated Teleport configuration for {teleport_proxy} by tsh # Common flags for all {teleport_proxy} hosts Host *.{teleport_proxy} {teleport_proxy} UserKnownHostsFile "/home/{user}/.tsh/known_hosts" IdentityFile "/home/{user}/.tsh/keys/{teleport_proxy}/{teleport_user}" CertificateFile "/home/{user}/.tsh/keys/{teleport_proxy}/{teleport_user}/{teleport_proxy}-cert.pub" HostKeyAlgorithms [email protected],[email protected],[email protected] # Flags for all {teleport_proxy} hosts except the proxy Host *.{teleport_proxy} !{teleport_proxy} Port 3022 ProxyCommand "/usr/local/bin/tsh" proxy ssh --cluster={teleport_proxy}--proxy={teleport_proxy}:443 %r@%h:%p
- Host matching: Applies settings for any host under the domain
{teleport_proxy}
and specifically for the{teleport_proxy}
itself. - UserKnownHostsFile: Specifies the location of the known hosts file, helping to verify the identity of the connected servers.
- Identity and Certificate Files: Points to the user’s private key and corresponding certificate for authentication, stored under the user’s home directory. These are specific to the
{teleport_proxy}
and{teleport_user}
. - HostKeyAlgorithms: Lists the secure host key algorithms that are accepted for connections, ensuring strong authentication standards.
- Excluding Direct Proxy Access: Configures settings for all hosts in the
{teleport_proxy}
domain, excluding direct connections to the proxy itself. - Port and ProxyCommand: Uses port 3022 and sets a
ProxyCommand
that facilitates SSH connections through Teleport’s proxy. This command uses Teleport’stsh proxy ssh
to handle secure connections by resolving hostnames within the{teleport_proxy}
cluster.
With this configuration, you can seamlessly connect to any server that is part of the cluster’s network. Once set up, these servers are accessible using a standardized naming convention: node-name.proxy-domain
. For example, if a node is named jenkins
and the Teleport domain is example.com
, you can access this server using the standardized address jenkins.example.com
.
Setting up Ansible
To leverage Teleport for managing server access in Ansible, it’s crucial to correctly set up the configuration files. The teleport.cfg
file, generated earlier, should be placed at the same level as the ansible.cfg
file in your project directory. This setup ensures that Ansible can easily reference the necessary Teleport configurations.
There are two primary ways to configure Ansible to use Teleport: setting it in the inventory or in the ansible.cfg
file. And then the execution of playbooks and ad-hoc commands are treated in the same way.
The choice between these two methods can impact how flexible your Ansible deployments are, especially when connecting to a mix of servers, some of which may not be managed by Teleport.
Configuring Teleport settings in the ansible.cfg
file applies these settings globally to all playbooks. This approach simplifies setup when all your servers are managed through Teleport but can become a complication if you need to connect to servers outside of the Teleport system. On the other hand, configuring Teleport in the Ansible inventory targets only a specific group of hosts. By defining Teleport settings for a designated group, you ensure that only those servers use the Teleport configuration.
Adding Host in the Inventory
Modify your Ansible inventory by creating a new group of hosts and define several variables to utilize the teleport.cfg
file. Here’s how you can set it up:
teleport: hosts: {node_name}.{teleport_proxy}: vars: ansible_user: {teleport_user} ansible_ssh_common_args: -F teleport.cfg ansible_scp_if_ssh: true
This configuration tells Ansible to use the specified Teleport configuration for SSH commands. With this setup, there is no need to adjust anything extra in your playbooks, making it straightforward and efficient.
Example:
We assume we have a cluster with the following name “example.com”, a node with the following name “test” and a teleport system user “teleport”.
inventory.yml
all: children: teleport_dp_dev: hosts: test.example.com: vars: ansible_user: devop ansible_ssh_common_args: -F teleport.cfg ansible_scp_if_ssh: true
Executing ad-hoc command: ansible all -i inventory.yml -m shell -a "sudo apt update && sudo apt upgrade -y" --become --limit test.example.com
Executing a playbook: ansible-playbook -i inventory.yml Ansible/playbooks/42m.example.yml --limit test.example.com
Adding Configuration in ansible.cfg
Directly incorporate the Teleport configuration into your ansible.cfg
file to apply it globally across all playbooks:
[ssh_connection] scp_if_ssh = True ssh_args = -F ./teleport.cfg
This method ensures that all SSH connections made by Ansible will utilize the Teleport configuration, providing a consistent approach to access management. The server names in your inventory will follow the naming convention used in Teleport, such as "name in teleport"."cluster name"
.
Additionally, it’s common to specify the remote_user
in your playbooks to dictate which user should execute the Ansible tasks. Take into account the users set on the servers and those to which your teleport user has permissions to enter the servers.
Example
We assume we have a cluster with the following name “example.com”, a node with the following name “test” and a teleport system user “teleport”.
inventory.yml
all: children: teleport_dp_dev: hosts: test.example.com:
ansible.cfg
[ssh_connection] scp_if_ssh = True ssh_args = -F ./teleport.cfg
Executing ad-hoc command: ansible all -i inventory.yml -m shell -a "sudo apt update && sudo apt upgrade -y" --become -u teleport --limit test.example.com
Executing a playbook: ansible-playbook -i inventory.yml Ansible/playbooks/42m.example.yml -u teleport --limit test.example.com
Conclusion
Setting up Teleport with Ansible is straightforward, requiring only minor configuration adjustments. By simply placing the teleport.cfg
file correctly and tweaking a few settings in Ansible, you can enhance the security of your server management without significantly altering your existing processes. This setup ensures that you can maintain your routine operations while implementing an added layer of security with minimal effort.