Reputation: 5261
My Ansible playbook deploys to both database and webservers and I need to use some shared variables between them. The answer from this question almost gives me what I need:
---
- hosts: all
tasks:
- set_fact: my_global_var='hello'
- hosts: db
tasks:
- debug: msg={{my_global_var}}
- hosts: web
tasks:
- debug: msg={{my_global_var}}
However, in my case the variable is a password that is generated randomly by the playbook on each run and then has to be shared:
---
- hosts: all
tasks:
- name: Generate new password
shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
register: new_password
- name: Set password as fact
set_fact:
my_global_var: "{{ new_password.stdout }}"
- hosts: db
tasks:
- debug: msg={{my_global_var}}
- hosts: web
tasks:
- debug: msg={{my_global_var}}
This above example doesn't work as the password is now re-generated and completely different for each host in the all
hosts (unless you coincidentally use the same machine/hostname for your db and web servers).
Ideally I don't want someone to have to remember to pass a good random password in on the command-line using --extra-vars
, it should be generated and handled by the playbook.
Is there any suggested mechanism in Ansible for creating variables within a playbook and having it accessible to all hosts within that playbook?
Upvotes: 4
Views: 2170
Reputation: 29
I know this is an old question but I settled on an alternative method that combines the two answers provided here and this issue, by using an implicit localhost reference and doing everything within the same play. I think it's a bit more elegant. Tested with 2.8.4.
This is the working solution in my context, where I wanted a common timestamped backup directory across all my hosts, for later restore:
---
tasks:
- name: Set local fact for the universal backup string
set_fact:
thisHostTimestamp: "{{ ansible_date_time.iso8601 }}"
delegate_to: localhost
delegate_facts: true
- name: Distribute backup datestring to all hosts in group
set_fact:
backupsTimeString: "{{ hostvars['localhost']['thisHostTimestamp'] }}"
I believe this should translate to the OP's original example like this, but I have not tested it:
---
- hosts: all
tasks:
- name: Generate new password
shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
register: new_password
delegate_to: localhost
delegate_facts: true
- name: Set password as fact
set_fact:
my_global_var: "{{ hostvars['localhost'].new_password.stdout }}"
Upvotes: 0
Reputation: 68329
You may want to try to generate pass on localhost and then copy it to every other host:
---
- hosts: localhost
tasks:
- name: Generate new password
shell: "tr -dc _[:alnum:] < /dev/urandom | head -c${1:-20}"
register: new_password
- hosts: all
tasks:
- name: Set password as fact
set_fact:
my_global_var: "{{ hostvars['localhost'].new_password.stdout }}"
- hosts: db
tasks:
- debug: msg={{my_global_var}}
- hosts: web
tasks:
- debug: msg={{my_global_var}}
Upvotes: 4