Teleport Workload Identity with SPIFFE: Achieving Zero Trust in Modern Infrastructure
May 23
Virtual
Register Today
Teleport logoTry For Free
Fork me on GitHub

Teleport

Ansible

Ansible uses the OpenSSH client by default. Teleport supports SSH protocol and works as SSH jumphost.

In this guide we will configure OpenSSH client to work with Teleport Proxy and run a sample ansible playbook.

Prerequisites

  • A running Teleport cluster version 15.2.4 or above. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl admin tool and tsh client tool.

    On Teleport Enterprise, you must use the Enterprise version of tctl, which you can download from your Teleport account workspace. Otherwise, visit Installation for instructions on downloading tctl and tsh for Teleport Community Edition.

  • ssh openssh tool
  • ansible >= 2.9.6
  • Optional tool jq to process JSON output.
  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. tctl is supported on macOS and Linux machines. For example:
    tsh login --proxy=teleport.example.com --user=[email protected]
    tctl status

    Cluster teleport.example.com

    Version 15.2.4

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.

Step 1/3. Login and configure SSH

Log into Teleport with tsh:

tsh login --proxy=example.com

Generate openssh configuration using tsh config shortcut:

tsh config > ssh.cfg
Tip

You can edit matching patterns used in ssh.cfg if something is not working out of the box.

Step 2/3. Configure Ansible

Create a folder ansible where we will collect all generated files:

mkdir -p ansible
cd ansible

Create a file ansible.cfg:

[defaults]
host_key_checking = True
inventory=./hosts
remote_tmp=/tmp

[ssh_connection]
scp_if_ssh = True
ssh_args = -F ./ssh.cfg

You can create an inventory file hosts manually or use a script below to generate it from your environment. Set your cluster name (e.g. teleport.example.com or in the form mytenant.teleport.sh for Teleport Enterprise Cloud) and this script will generate the host names to match the openssh configuration:

tsh ls --format=json | jq '.[].spec.hostname + ".teleport.example.com"' > hosts

Step 3/3. Run a playbook

Finally, let's create a simple ansible playbook playbook.yaml.

The playbook below runs hostname on all hosts. Make sure to set the remote_user parameter to a valid SSH username that works with the target host and is allowed by Teleport:

- hosts: all
  remote_user: ubuntu
  tasks:
    - name: "hostname"
      command: "hostname"

From the folder ansible, run the ansible playbook:

ansible-playbook playbook.yaml

PLAY [all] *****************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************

ok: [terminal]

TASK [hostname] ************************************************************************************************************************************

changed: [terminal]

PLAY RECAP *****************************************************************************************************************************************

terminal : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

You are all set. You are now using short-lived SSH certificates and Teleport can now record all ansible commands in the audit log.

Troubleshooting

In case if ansible can not connect, you may see error like this one:

example.host | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname example.host: Name or service not known",
    "unreachable": true
}

You can examine and tweak patterns matching the inventory hosts in ssh.cfg.

Try the SSH connection using ssh.cfg with verbose mode to inspect the error:

ssh -vvv -F ./ssh.cfg [email protected]

If ssh works, try running the playbook with verbose mode on:

ansible-playbook -vvvv playbook.yaml