Skip to content

Instantly share code, notes, and snippets.

  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JonTheNiceGuy/759130929cf68a649c1a5ce042300c95 to your computer and use it in GitHub Desktop.
This gist will be used in a blog post at https://jon.sprig.gs. It is to describe how I generate and store passwords.

Generate and Store Dynamic Data for Ansible Playbooks

In this example, we generate a per-host unique password, which we store for later use... And yes, there's the "password lookup" we could have used, but that negates the purpose of this demonstration :) There's no reason why you can't generate unique MACs per host with the same method, or retrieve and store host specific data for later re-runs of the playbook using the same method.

In this example...

This playbook will be used in an Ansible environment (not Ansible Tower because that typically flushes the cache on each build)

The first part of the playbook (vars -> password) looks up the passwords where they're stored, or generates new ones and adds a common suffix

Then we generate (in the control node) the host_vars directories per host we've generated passwords for.

Finally we store the passwords and print them out. Note that if you were using this for a production environment, you should store the generated passwords using something like HashiCorp Vault, Pass or even just pushing your SSH keys to the host as soon as it was built, and then flushing the passwords!

[defaults]
host_key_checking = False
display_skipped_hosts = False
retry_files_enabled = False
server[1:20]
server1 ansible_password=decafbad0123
---
- hosts: all
# Don't gather facts - for this test, we don't have access to any actual
# hosts. This replicates an "infrastructure build" environment where you
# might not have the hosts actually created at this point!
gather_facts: false
vars:
# This next block looks up or generates the passwords for each host.
# - ansible_password is defined as part of the inventory.
# - machine_password is the generated password, stored in host_vars.
# - PASSWORD is an environment variable, which can be specified on the
# command line.
# - project_password is a playbook-wide password, if all the machines
# need to have a common password.
# - Otherwise, generate a 12 character long password using A-Za-z0-9,
# and suffix it with _ and the common suffix (default "password").
password: |
{%- if ansible_password is defined -%}
{{ ansible_password }}
{%- elif machine_password is defined -%}
{{ machine_password }}
{%- elif lookup('env', 'PASSWORD') != '' -%}
{{ lookup('env', 'PASSWORD') }}
{%- else -%}
{{ project_password |
default(
lookup ('password', '/dev/null length=12 chars=lowercase,uppercase,digits') +
'_' +
project_password_suffix | default('Password')
)
}}
{%- endif -%}
tasks:
# Initially we need to ensure that the host_vars directory is created.
- name: Create host_vars directory
delegate_to: localhost
run_once: true
file:
path: "host_vars"
state: directory
mode: 0755
# And that each host has it's own directory (but only if we're generating
# a new password for that host).
- name: Create Directory for Stored Generated Values
delegate_to: localhost
file:
path: "host_vars/{{ inventory_hostname }}"
state: directory
mode: 0755
when:
- ansible_password is not defined
- machine_password is not defined
- project_password is not defined
# And lastly, we store the generated password. Ideally, we would use a vault
# at this point, but I don't know how to issue this statement from an ansible
# playbook!
- name: Store Generated Values
delegate_to: localhost
lineinfile:
path: "host_vars/{{ inventory_hostname }}/generated.yml"
regexp: '^machine_password:'
line: 'machine_password: {{ password }}'
state: present
create: yes
when:
- ansible_password is not defined
- machine_password is not defined
- project_password is not defined
# And just because this *is* a test, print it out :)
- name: Print password
delegate_to: localhost
debug: var=password
$ ansible-playbook -i inventory playbook.yml
PLAY [all] ******************************************************************************************************************************************************************************************************************************
TASK [Create host_vars directory] *******************************************************************************************************************************************************************************************************
changed: [server1 -> localhost]
TASK [Create Directory for Stored Generated Values] *************************************************************************************************************************************************************************************
changed: [server4 -> localhost]
changed: [server3 -> localhost]
changed: [server2 -> localhost]
changed: [server6 -> localhost]
changed: [server5 -> localhost]
changed: [server7 -> localhost]
changed: [server8 -> localhost]
changed: [server10 -> localhost]
changed: [server9 -> localhost]
changed: [server11 -> localhost]
changed: [server13 -> localhost]
changed: [server12 -> localhost]
changed: [server14 -> localhost]
changed: [server15 -> localhost]
changed: [server16 -> localhost]
changed: [server17 -> localhost]
changed: [server18 -> localhost]
changed: [server19 -> localhost]
changed: [server20 -> localhost]
TASK [Store Generated Values] ***********************************************************************************************************************************************************************************************************
changed: [server4 -> localhost]
changed: [server2 -> localhost]
changed: [server6 -> localhost]
changed: [server3 -> localhost]
changed: [server5 -> localhost]
changed: [server10 -> localhost]
changed: [server7 -> localhost]
changed: [server9 -> localhost]
changed: [server8 -> localhost]
changed: [server11 -> localhost]
changed: [server14 -> localhost]
changed: [server12 -> localhost]
changed: [server15 -> localhost]
changed: [server13 -> localhost]
changed: [server16 -> localhost]
changed: [server17 -> localhost]
changed: [server18 -> localhost]
changed: [server20 -> localhost]
changed: [server19 -> localhost]
TASK [Print password] *******************************************************************************************************************************************************************************************************************
ok: [server1 -> localhost] => {
"password": "decafbad\n"
}
ok: [server2 -> localhost] => {
"password": "ac9eu9l391cp_Password\n"
}
ok: [server3 -> localhost] => {
"password": "lecaee5pw1ee_Password\n"
}
ok: [server4 -> localhost] => {
"password": "aoe9wea857w7_Password\n"
}
ok: [server5 -> localhost] => {
"password": "wa4r2rlurw4s_Password\n"
}
ok: [server6 -> localhost] => {
"password": "9rrpcu4erc4s_Password\n"
}
ok: [server7 -> localhost] => {
"password": "3ppae5ra2u1a_Password\n"
}
ok: [server8 -> localhost] => {
"password": "wsws6aelr4l3_Password\n"
}
ok: [server9 -> localhost] => {
"password": "8ea9erp5o2eo_Password\n"
}
ok: [server10 -> localhost] => {
"password": "9pue4we510p6_Password\n"
}
ok: [server11 -> localhost] => {
"password": "lara8cue8rlp_Password\n"
}
ok: [server12 -> localhost] => {
"password": "2o519553eeo4_Password\n"
}
ok: [server13 -> localhost] => {
"password": "976coepru8uu_Password\n"
}
ok: [server14 -> localhost] => {
"password": "se89aa23swp2_Password\n"
}
ok: [server15 -> localhost] => {
"password": "91s407ere8lu_Password\n"
}
ok: [server16 -> localhost] => {
"password": "s7ece65esls1_Password\n"
}
ok: [server17 -> localhost] => {
"password": "6p4ur454o4ec_Password\n"
}
ok: [server18 -> localhost] => {
"password": "pccwrssssw19_Password\n"
}
ok: [server19 -> localhost] => {
"password": "w3r9r02e1w4s_Password\n"
}
ok: [server20 -> localhost] => {
"password": "r6pwo3c1e80o_Password\n"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************************************
server1 : ok=2 changed=1 unreachable=0 failed=0
server10 : ok=3 changed=2 unreachable=0 failed=0
server11 : ok=3 changed=2 unreachable=0 failed=0
server12 : ok=3 changed=2 unreachable=0 failed=0
server13 : ok=3 changed=2 unreachable=0 failed=0
server14 : ok=3 changed=2 unreachable=0 failed=0
server15 : ok=3 changed=2 unreachable=0 failed=0
server16 : ok=3 changed=2 unreachable=0 failed=0
server17 : ok=3 changed=2 unreachable=0 failed=0
server18 : ok=3 changed=2 unreachable=0 failed=0
server19 : ok=3 changed=2 unreachable=0 failed=0
server2 : ok=3 changed=2 unreachable=0 failed=0
server20 : ok=3 changed=2 unreachable=0 failed=0
server3 : ok=3 changed=2 unreachable=0 failed=0
server4 : ok=3 changed=2 unreachable=0 failed=0
server5 : ok=3 changed=2 unreachable=0 failed=0
server6 : ok=3 changed=2 unreachable=0 failed=0
server7 : ok=3 changed=2 unreachable=0 failed=0
server8 : ok=3 changed=2 unreachable=0 failed=0
server9 : ok=3 changed=2 unreachable=0 failed=0
$ ansible-playbook -i inventory playbook.yml
PLAY [all] ******************************************************************************************************************************************************************************************************************************
TASK [Create host_vars directory] *******************************************************************************************************************************************************************************************************
ok: [server1 -> localhost]
TASK [Print password] *******************************************************************************************************************************************************************************************************************
ok: [server1 -> localhost] => {
"password": "decafbad\n"
}
ok: [server2 -> localhost] => {
"password": "rp0w4easl400_Password\n"
}
ok: [server3 -> localhost] => {
"password": "u2p2pr5srpas_Password\n"
}
ok: [server4 -> localhost] => {
"password": "200c1euae2eu_Password\n"
}
ok: [server5 -> localhost] => {
"password": "epe0ea5a8rrr_Password\n"
}
ok: [server6 -> localhost] => {
"password": "7aucw0speaep_Password\n"
}
ok: [server7 -> localhost] => {
"password": "ecr1ru7uco1r_Password\n"
}
ok: [server8 -> localhost] => {
"password": "r4o28lwa1eao_Password\n"
}
ok: [server9 -> localhost] => {
"password": "1eu586rwap54_Password\n"
}
ok: [server10 -> localhost] => {
"password": "962cras4err9_Password\n"
}
ok: [server11 -> localhost] => {
"password": "ls075ewpsw5e_Password\n"
}
ok: [server12 -> localhost] => {
"password": "rrr1rouee1ce_Password\n"
}
ok: [server13 -> localhost] => {
"password": "res89es7saou_Password\n"
}
ok: [server14 -> localhost] => {
"password": "a35srpsa7ec3_Password\n"
}
ok: [server15 -> localhost] => {
"password": "8e8r73u2al8s_Password\n"
}
ok: [server16 -> localhost] => {
"password": "877rcp1p16oa_Password\n"
}
ok: [server17 -> localhost] => {
"password": "upar6spwclpp_Password\n"
}
ok: [server18 -> localhost] => {
"password": "5easoaa8629w_Password\n"
}
ok: [server19 -> localhost] => {
"password": "1oae487spsop_Password\n"
}
ok: [server20 -> localhost] => {
"password": "epaolas69e3w_Password\n"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************************************
server1 : ok=2 changed=0 unreachable=0 failed=0
server10 : ok=1 changed=0 unreachable=0 failed=0
server11 : ok=1 changed=0 unreachable=0 failed=0
server12 : ok=1 changed=0 unreachable=0 failed=0
server13 : ok=1 changed=0 unreachable=0 failed=0
server14 : ok=1 changed=0 unreachable=0 failed=0
server15 : ok=1 changed=0 unreachable=0 failed=0
server16 : ok=1 changed=0 unreachable=0 failed=0
server17 : ok=1 changed=0 unreachable=0 failed=0
server18 : ok=1 changed=0 unreachable=0 failed=0
server19 : ok=1 changed=0 unreachable=0 failed=0
server2 : ok=1 changed=0 unreachable=0 failed=0
server20 : ok=1 changed=0 unreachable=0 failed=0
server3 : ok=1 changed=0 unreachable=0 failed=0
server4 : ok=1 changed=0 unreachable=0 failed=0
server5 : ok=1 changed=0 unreachable=0 failed=0
server6 : ok=1 changed=0 unreachable=0 failed=0
server7 : ok=1 changed=0 unreachable=0 failed=0
server8 : ok=1 changed=0 unreachable=0 failed=0
server9 : ok=1 changed=0 unreachable=0 failed=0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment