Secure Inventory

What do you do if you need to have an Ansible inventory, but don’t want to reveal all of the hostnames?

You leverage two features of Ansible:

  1. Ansible supports a YAML inventory file

  2. The ansible-vault command encrypts YAML files

All of the examples in this post can be found in my Ansible layout repository.

The Setup

Setup the inventory file using the ansible-vault command.

Create a password file for ansible-vault

mkdir .vault
echo "some-rand-password" > .vault/password

Edit the ansible.cfg file to use the password file

<snip>
vault_password_file = .vault/password
<snip>

Create your encrypted inventory file

mkdir inv/secure/
ansible-vault create inv/secure/secure.yml

The contents of the inv/secure/secure.yml file:

---
all:
  vars:
    environ: prodsec
    environment_long: production_secure
  children:
    production_secure:

production_secure:
  children:
    web:
    app:
    db:
  vars:
    ansible_connection: local # remove for prod use

web:
  hosts:
    web-secure-01:

app:
  hosts:
    app-secure-01:

db:
  hosts:
    db-secure-01:

That file is now encrypted and looks like this on disk:

$ANSIBLE_VAULT;1.1;AES256
62363162626437633732323761646365663637346666376430323830313732323831353165373139
3237373133656263616139353838393263383965396131310a363364393166613063336439376464
36333263626361393063376261336539653830333636396239306433663163333230356530333265
6362656566616536630a666537333334616635383835613334386661383137383931623564363930
33633031323635646536616339353332343932643461373861636234386631623962633836396466
30663035323561323266356638623834393063653635633034376332653137646235633562626364
61613035373531363939333037313036336463393737326665636132386261633564623934386262
34656431366663376363323165353833383532373534396130326434626262633065613035343035
63333137336365333532353532646235626662653134373861623338383238313735373561336364
30626339393162326530306163326637363263376433343230313461643063313938356436396430
37393739326665333233396135626565353339653061663462333334336233373339316264373334
66643534623533613032333736306133323266656563356132616433653462383331336436323533
31316232356637323438393735666336313634326139326238613961366134363139373932623263
61663066393234333738376639626539326439336438626164613763343264353831383539616235
33613730646536383933366461346435613331393462616334363331613363623366663035333935
38373735663837393061306362306262363438643663313162646434323363303538623734333564
61633938616561353834383162353638643237376633333132393261393563346439383364333362
35313936313539623261343361393761623238376462623534316666616133343731643365343266
64663036356561393661666130336466643661316661316663336231616238613635383465306139
34383736313466353466613938393464303163313764383563376164313162633134386630643363
3734

Run the ansible-playbook command as you normally would.

[user@host]$ ansible-playbook -i inv/secure/ playbooks/app.yml

PLAY [app servers] ******************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************
ok: [app-secure-01]

TASK [this is app] ******************************************************************************************************************************************************
ok: [app-secure-01] => {
    "msg": "this is app server on production_secure"
}

PLAY RECAP **************************************************************************************************************************************************************
app-secure-01              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

That’s it, you have an encrypted inventory file which can be safely stored in a public git repo (if you don’t store the password file).