简体   繁体   中英

Passing an Ansible variable from one role to another

In an Ansible playbook, I have a first role that creates 3 VMs in a cloud platform, and a second role that performs several setup tasks on each VM. I need to pass each VM IP address from role 1 to role 2.

This is my inventory hosts file

[masters]
master.domain.tld

[workers]
worker1.domain.tld
worker2.domain.tld

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa

So far I managed to register and then extract each VM IP using this code:

......
register: hcloud_info
 
- debug:
    msg: 'Hcloud IP address is {{ item.hcloud_server.ipv4_address }}'
  with_items: "{{ hcloud_info.results }}"

The 3 IPs are properly displayed.

To pass the VM IPs from role 1 to role 2, I'm using an in-memory inventory using the add_host directive:

- name: Add new servers to dynamic inventory
  add_host:
    name: "{{ item.hcloud_server.ipv4_address }}"
    groups: new_servers
  with_items: "{{ hcloud_info.results }}"

Now in the second role, I would need to access data in the in-memory inventory to pull out each single VM's public IP and assign it ( delegate_to: SERVER_PUBLIC_IP ) to each server using this snippet:

- name: Apply private IP to master
  hcloud_server_network:
    api_token: "{{ hcloud_token }}"
    network: priv_network
    server: master.domain.tld
    ip: 10.1.0.2
    state: present
  delegate_to: SERVER_PUBLIC_IP

I've been trying to use this code in role 1, to pass it to role 2, but a 'hcloud_server' has no attribute error shows up...

- Name: Display IPs
  debug: msg="{{ item.hcloud_server.ipv4_address }}"
  with_items: "{{ groups.new_servers }}"

For example, get the IPs of the hosts (you take it from hcloud_info )

- hosts: workers
  gather_facts: true
  tasks:
  - debug:
      var: ansible_all_ipv4_addresses|first
ok: [worker1.domain.tld] => 
  ansible_all_ipv4_addresses|first: 10.1.0.61
ok: [worker2.domain.tld] => 
  ansible_all_ipv4_addresses|first: 10.1.0.62

In the 1st role create a dictionary of the IP addresses (fit the expression _ip to your needs)

shell> cat roles/create-vm/tasks/main.yml
- set_fact:
    my_ip: "{{ dict(ansible_play_batch|zip(_ip)) }}"
  vars:
    _ip: "{{ ansible_play_batch|
             map('extract', hostvars, 'ansible_all_ipv4_addresses')|
             map('first')|
             list }}"
  run_once: true

gives

  my_ip:
    worker1.domain.tld: 10.1.0.61
    worker2.domain.tld: 10.1.0.62

Use this dictionary in the 2nd role

shell> cat roles/apply-ip-to-master/tasks/main.yml
- debug:
    msg: "Apply {{ my_ip[inventory_hostname] }} to master"

Create a playbook

- hosts: workers
  gather_facts: true
  roles:
    - create-vm
    - apply-ip-to-master

gives

ok: [worker1.domain.tld] => 
  msg: Apply 10.1.0.61 to master
ok: [worker2.domain.tld] => 
  msg: Apply 10.1.0.62 to master

This way you can "Apply private IP to master" for each worker instead of delegating the task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM