# 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.

## How it works

In the setup we describe in this guide, you generate an OpenSSH configuration that uses a Teleport-issued SSH certificate to connect to Teleport-protected servers. You then provide this OpenSSH configuration to your Ansible host, along with an inventory of Teleport-protected servers. Ansible then uses the OpenSSH configuration to present the Teleport-issued credentials in order to manage your servers.

## Prerequisites

- A running Teleport cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/ver/17.x/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/ver/17.x/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* `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. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  17.7.20
  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=teleport.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
Copy the openssh configuration from the previous step to the ansible dir
$ cp ssh.cfg 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 cases where Ansible cannot connect, you may see an error like this:

```
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 root@example.host
```

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

```
$ ansible-playbook -vvvv playbook.yaml
```

If your hostnames contain uppercase characters (like `MYHOSTNAME`), please note that Teleport's internal hostname matching is case sensitive by default, which can also lead to seeing this error.

If this is the case, you can work around this by enabling case-insensitive routing at the cluster level.

**Self-hosted Teleport**

Edit your `/etc/teleport.yaml` config file on all servers running the Teleport `auth_service`, then restart Teleport on each.

```
auth_service:
  case_insensitive_routing: true

```

**Managed Teleport Enterprise/Cloud**

Run `tctl edit cluster_networking_config` to add the following specification, then save and exit.

```
spec:
  case_insensitive_routing: true

```
