This is a very simple package which will use Teleport as a dynamic inventory source for Ansible. The script assumes you've logged in and have access to the teleport service. Examples of all the base requirements are provided within this readme.
Checkout https://cloudnull.io/2022/09/ansible-inventory-via-teleport for a more indepth review of integrating Teleport with Ansible.
The script will read machines and return JSON information from teleport. Once the return information is sourced, it will format the inventory using the node name as the target host and the labels as hostvars and groups.
Using teleport-ansible requires a little setup, mostly client side for Teleport itself.
Installing the teleport-ansible
inventory script can be accomplished with pip
.
pip install teleport-ansible
The teleport-inventory script can also be installed using the git repository directly.
pip install git+https://github.com/cloudnull/teleport-ansible
If you don't want to install the script, you can also simply download the script using the hard link and run it from wherever you want.
curl https://raw.githubusercontent.com/cloudnull/teleport-ansible/master/teleport-inventory.py -o teleport-inventory.py
Create a compatible SSH configuration for Teleport.
export TELEPORT_DOMAIN=teleport.example.com
export TELEPORT_USER=cloudnull
cat > ~/.ssh/teleport.cfg <<EOF
Host * !${TELEPORT_DOMAIN}
UserKnownHostsFile "${HOME}/.tsh/known_hosts"
IdentityFile "${HOME}/.tsh/keys/${TELEPORT_DOMAIN}/${TELEPORT_USER}"
CertificateFile "${HOME}/.tsh/keys/${TELEPORT_DOMAIN}/${TELEPORT_USER}-ssh/${TELEPORT_DOMAIN}-cert.pub"
PubkeyAcceptedKeyTypes +ssh-rsa-cert-v01@openssh.com
Port 3022
CheckHostIP no
ProxyCommand "$(which tsh)" proxy ssh --cluster=${TELEPORT_DOMAIN} --proxy=${TELEPORT_DOMAIN} %r@%h:%p
EOF
The above ssh configuration needs to have all variables replaced to work.
When running this inventory, Ansible requires some basic instructions which can be set via environment variables or through an Ansible config file.
export ANSIBLE_SCP_IF_SSH=False
export ANSIBLE_SSH_ARGS="-F ${HOME}/.ssh/teleport.cfg"
export ANSIBLE_INVENTORY_ENABLED=script
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_INVENTORY="$(command -v teleport-ansible)"
The ${HOME}/.ssh/teleport.cfg file is generated by using the
tsh config
command then customized based on individual needs.
tsh login --proxy=teleport.example.com --user=teleport-admin
If browser window does not open automatically, open it by clicking on the link:
http://127.0.0.1:42337/83facfc0-e899-44dc-aa6c-32179e3d5b0b
> Profile URL: https://teleport.example.com:443
Logged in as: teleport-admin
Cluster: teleport.example.com
Roles: access
Logins: root, ubuntu, debian, fedora, centos, -teleport-internal-join
Kubernetes: enabled
Valid until: 2022-09-16 08:03:05 -0500 CDT [valid for 12h0m0s]
Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty
The above tsh login will provide access to the teleport cluster, which will allow you to run inventory script which will return an Ansible inventory JSON.
Running the teleport inventory command teleport-inventory
will return something
like this.
>>> {
... "_meta": {
... "hostvars": {
... "alluvial-0": {
... "ansible_user": "ubuntu",
... "teleport_id": 1663292578982084621,
... "arch": "x86_64",
... "codename": "jammy",
... "environment": "dev"
... },
... "compute-0": {
... "ansible_user": "carter",
... "teleport_id": 1663292546493240726,
... "arch": "x86_64",
... "codename": "jammy",
... "environment": "prod"
... },
... "curator-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292584620339609,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "plexmediaserver-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292540612813467,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "rtmprelay-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292583673456110,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "teleport-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292588270337453,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "thelounge-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292533524229273,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "unbound-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292535344206453,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "unifi-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292528952201832,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... },
... "wireguard-0": {
... "ansible_user": "debian",
... "teleport_id": 1663292535570354336,
... "arch": "x86_64",
... "codename": "bullseye",
... "environment": "prod"
... }
... }
... },
... "all": {
... "hosts": [
... "alluvial-0",
... "compute-0",
... "curator-0",
... "plexmediaserver-0",
... "rtmprelay-0",
... "teleport-0",
... "thelounge-0",
... "unbound-0",
... "unifi-0",
... "wireguard-0"
... ],
... "children": []
... },
... "x86_64": {
... "hosts": [
... "alluvial-0",
... "compute-0",
... "curator-0",
... "plexmediaserver-0",
... "rtmprelay-0",
... "teleport-0",
... "thelounge-0",
... "unbound-0",
... "unifi-0",
... "wireguard-0"
... ],
... "children": []
... },
... "jammy": {
... "hosts": [
... "alluvial-0",
... "compute-0"
... ],
... "children": []
... },
... "dev": {
... "hosts": [
... "alluvial-0"
... ],
... "children": []
... },
... "teleport_cloudnull_dev": {
... "hosts": [
... "wireguard-0"
... ],
... "children": []
... },
... "prod": {
... "hosts": [
... "compute-0",
... "curator-0",
... "plexmediaserver-0",
... "rtmprelay-0",
... "teleport-0",
... "thelounge-0",
... "unbound-0",
... "unifi-0",
... "wireguard-0"
... ],
... "children": []
... },
... "bullseye": {
... "hosts": [
... "curator-0",
... "plexmediaserver-0",
... "rtmprelay-0",
... "teleport-0",
... "thelounge-0",
... "unbound-0",
... "unifi-0",
... "wireguard-0"
... ],
... "children": []
... }
... }
Once the ssh config is in place, the Ansible configuration is set, and teleport is logged in, Ansible can be run natively.
You'll notice that the command is SUPER basic. There's nothing special here.
ansible -m ping all
Just like the ad-hoc command, there's nothing special when running playbooks either.
ansible-playbook example-playbook.yaml