L.T
L.T

Reputation: 2589

How to share variables in same playbook.yml at ansible-playbook?

playbook.yml

- name: dump_db
  hosts: pay_server
  remote_user: root
  become_user: root
  vars:
    now: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
  tasks:
    - debug:
        msg: "{{ now }}"
    - copy:
        src: my.cnf
        dest: /tmp/my.cnf
        mode: 0644
    - name: dump
      shell: |
        mysqldump --defaults-extra-file=my.cnf \
          --set-gtid-purged=OFF \
          --single-transaction db_name  db_tables > /tmp/dump.{{now}}.sql
      args:
        chdir: /tmp
    - name: Download
      fetch:
        src: "/tmp/dump.{{now}}.sql"
        dest: "dump.{{now}}.sql"
        flat: yes
- name: Restore
  hosts: localhost
  tasks:
    - tags: restore
      shell: |
        mysql --defaults-extra-file=local.cnf db_name < dump.{{hostvars['pay_server'].now}}.sql

shows error

The error was: \"hostvars['pay_server']\" is undefined

ansible version:

ansible [core 2.12.0]
  config file = /Users/huyinghuan/.ansible.cfg
  configured module search path = ['/Users/huyinghuan/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/huyinghuan/Library/Python/3.8/lib/python/site-packages/ansible
  ansible collection location = /Users/huyinghuan/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/huyinghuan/Library/Python/3.8/bin/ansible
  python version = 3.8.9 (default, Oct 26 2021, 07:25:53) [Clang 13.0.0 (clang-1300.0.29.30)]
  jinja version = 3.0.3
  libyaml = False

there is test code:

- name: dump_db
  hosts: pay_server
  remote_user: root
  become_user: root
  tasks:
    - set_fact:
        now: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
    - debug:
        msg: "{{ now }}"
- name: Restore
  hosts: localhost
  tasks:
    - debug:
        var: hostvars['pay_server']['now']

Result:

enter image description here


Adds on:

I try to use roles defined global variable like:

roles/mysql/vars/main.yml:

now: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"

test code:

- name: dump_db
  hosts: pay_server
  remote_user: root
  become_user: root
  roles:
    - mysql
  tasks:
    - debug:
        var: now
    - shell: |
        # mock task spend time
        sleep 1
- name: Restore
  hosts: localhost
  roles:
    - mysql
  tasks:
    - debug:
        var: now

enter image description here

Upvotes: 0

Views: 226

Answers (3)

L.T
L.T

Reputation: 2589

Use delegate_to share remote and localhost

test code:

- name: dump_db
  hosts: pay_server
  remote_user: root
  become_user: root
  tasks:
    - set_fact:
        now: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
    - debug:
        var: now
    - shell: |
        echo {{ now }}
      delegate_to: "localhost"
      delegate_facts: true
      register: result
    - debug:
        var: result.stdout_lines

Upvotes: 0

seshadri_c
seshadri_c

Reputation: 7340

How to share variables ...

One way to do this is to set_fact the variable for the host on which the task runs.

- name: example
  hosts: host1

  tasks:
    - set_fact:
        now: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
    - shell: |
        # tasks will spend some time, example: dump mysql to {{now}}.sql

- name: example2
  hosts: host2

  tasks:
    - debug:
        var: hostvars['host1']['now']
    - shell: |
        # do something, example: restore data to localhost form {{hostvars['host1'].now}}.sql

Upvotes: 1

U880D
U880D

Reputation: 12008

You may have a look first into

Documentation

and use an inventory and approach like

---
- hosts: test
  become: false
  gather_facts: true

  vars:

    NOW: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"

  tasks:

  - name: Example ONE
    debug:
      msg: "{{ NOW }}"
    when: "'test1' in ansible_hostname"

  - name: Example TWO
    debug:
      msg: "{{ NOW }}"
    when: "'test2' in ansible_hostname"

resulting into an output of

TASK [Example ONE] *******
ok: [test1.example.com] =>
  msg: '20220726080000'

TASK [Example TWO] *******
ok: [test2.example.com] =>
  msg: '20220726080000'

Upvotes: 1

Related Questions