Ansible set_fact across plays
Solution 1
Facts are host specific. As the documentation about set_fact says, "[v]ariables [set with set_fact] are set on a host-by-host basis".
Instead, I'd try using run_once
as defined in Delegation, rolling updates, and local actions, like this:
- hosts: contractsServers
tasks:
- name: Determine date
local_action: shell: date "+%Y_%m_%d" --date="1 days ago"
register: yesterday
always_run: True
changed_when: False
run_once: True
- name: Do something else locally
local_action: ...
register: some_variable_name
always_run: True
changed_when: False
run_once: True
- name: Do something remotely using the variables registered above
...
Solution 2
You could enable fact-caching. You will need to set up a local redis instance where facts then will be stored.
Related videos on Youtube
Mukul Jain
Updated on September 20, 2022Comments
-
Mukul Jain over 1 year
I have to run an ansible playbook to execute the following tasks
1) Calculate date in YYYY_MM_DD format and then use this prefix to download some file from aws to my local machine. The filename is of the following format 2015_06_04_latest_file.csv
2) I have to then create a folder by the name 2015_06_04 into multiple hosts and upload this file there.
This is my current playbook -
--- - hosts: 127.0.0.1 connection: local sudo: yes gather_facts: no tasks: - name: calculate date shell: date "+%Y_%m_%d" --date="1 days ago" register: output - name: set date variable set_fact: latest_date={{ item }} with_items: output.stdout_lines - local_action: command mkdir -p /tmp/latest_contracts/{{ latest_date }} - local_action: command /root/bin/aws s3 cp s3://primarydatafolder/data/{{ latest_date }}_latest_data.csv /tmp/latest_contracts/{{ latest_date }}/ creates=/tmp/latest_contracts/{{ latest_date }}/latest_data.csv register: result ignore_errors: true - local_action: command /root/bin/aws s3 cp s3://secondarydatafolder/data/{{ latest_date }}_latest_data.csv /tmp/latest_contracts/{{ latest_date }}/ creates=/tmp/latest_contracts/{{ latest_date }}/latest_data.csv when: result|failed # remove the date prefix from the downloaded file - local_action: command ./rename_date.sh {{ latest_date }} ignore_errors: true - hosts: contractsServers sudo: yes gather_facts: no tasks: - name: create directory file: path={{item.path}} state=directory mode=0775 owner=root group=root with_items: - {path: '/var/mukul/contracts/{{ latest_date }}' } - {path: '/var/mukul/contracts/dummy' } - name: copy dummy contracts copy: src=dummy dest=/var/mukul/contracts/ - name: delete previous symlink shell: unlink /var/mukul/contracts/latest ignore_errors: true - name: upload the newly created latest date folder to the host copy: src=/tmp/latest_contracts/{{ latest_date }} dest=/var/mukul/contracts/ - name: create a symbolic link to the folder on the host and call it latest action: file state=link src=/var/mukul/contracts/{{ latest_date }} dest=/var/mukul/contracts/latest
As per ansible's documentation on set_fact variable, this variable latest_date should be available across plays. However, ansible fails with the following message
failed: [192.168.101.177] => (item={'path': u'/var/mukul/contracts/{# latest_date #}'}) => {"failed": true, "item": {"path": "/var/mukul/contracts/{# latest_date #}"}} msg: this module requires key=value arguments (['path=/var/mukul/contracts/{#', 'latest_date', '#}', 'state=directory', 'mode=0775', 'owner=root', 'group=root'])
It looks as if the second playbook is unable to get the value of the latest_date fact. Can you please tell me where i'm making a mistake?
-
Mukul Jain almost 9 yearsThanks for this. I was looking for ways to do this without fact caching, because to me it seemed a bit too much to do for just maintaining facts across plays.