6

I have a playbook where I'm spinning up an instance in aws with the ec2 module. To be more flexible I ask via prompt for the hostname. I found in the ec2 examples the code snippet, which allows you to run a second playbook with newly spun up instance for further configuration.

Now I want to set the hostname via module hostname but I cannot access the variable in the second playbook.

This is how my playbook looks like:

---
- hosts: localhost
  ...

  vars_prompt:
    - name: var_hostname
      prompt: "Please enter the hostname"
      private: no

  tasks:

    - name: Spin up instance
      local_action:
        module: ec2
        ...
      register: ec2

    - name: Add new instance to host group
      add_host: hostname={{ item.public_ip }} groupname=launched
      with_items: ec2.instances

- hosts: launched
  ...

  tasks:

    - name: Set hostname
      hostname: name="{{ var_hostname }}"

fatal: [launched] => One or more undefined variables: 'var_hostname' is undefined

Is there a way to pass a variable from one playbook to another one?

I found Ansible best practice for passing vars to nested playbooks? but unfortunately it didn't had a solution which I can use.

Community
  • 1
  • 1
ByteNudger
  • 1,545
  • 5
  • 29
  • 37
  • Possible duplicate of **[How do I set register a variable to persist between plays in ansible?](http://stackoverflow.com/questions/33896847/how-do-i-set-register-a-variable-to-persist-between-plays-in-ansible)** – Felipe Alvarez May 10 '17 at 02:28
  • In this particular case, it's more efficient to put the variables into the parameters of the module *add_host*. – Vladimir Botka Jun 27 '22 at 05:05

3 Answers3

7

You can use set_fact and hostvars together to achieve what you want.

Do set_fact on one group of hosts( i.e localhost), and access them in a different play using hostvars

{{hostvars['localhost']["new_fact"]}}

vangap
  • 243
  • 5
  • 12
5

You can use local files.

1) Write

- name: write public ip
  local_action:
    template:
      dest: /tmp/ansible_master_public_ip.txt
      src: templates/public_ip.j2

2) Retrieve with http://docs.ansible.com/ansible/playbooks_lookups.html

hostname: "{{ lookup('file', '/tmp/ansible_master_public_ip.txt') | trim }}"

PS. Ini file lookup also an option if you need more than few variables.

Kai
  • 1,478
  • 2
  • 15
  • 15
0
  • Add the host's variable to the parameters. For example,
    - name: Add new instance to host group
      add_host:
        hostname: "{{ ec2.instances.0.public_ip }}"
        groupname: launched
        var_hostname: "{{ var_hostname }}"
  • See examples

  • Use only the first item from the list because you have only one hostname. There is no reason to iterate the list.


Example of a complete playbook for testing

- hosts: localhost
  gather_facts: false
  vars_prompt:
    - name: var_hostname
      prompt: "Please enter the hostname"
      private: no
  vars:
    ec2:
      instances:
        - public_ip: AAA.BBB.CCC.DDD
  tasks:
    - name: Add new instance to host group
      add_host:
        hostname: "{{ ec2.instances.0.public_ip }}"
        groupname: launched
        var_hostname: "{{ var_hostname }}"

- hosts: launched
  gather_facts: false
  tasks:
    - debug:
        var: var_hostname
shell> ansible-playbook pb.yml 
Please enter the hostname: host_2

PLAY [localhost] *****************************************************************************

TASK [Add new instance to host group] ********************************************************
changed: [localhost]

PLAY [launched] ******************************************************************************

TASK [debug] *********************************************************************************
ok: [AAA.BBB.CCC.DDD] => 
  var_hostname: host_2

PLAY RECAP ***********************************************************************************
AAA.BBB.CCC.DDD: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  • Use pause instead of vars_prompt if you have more hosts. For example,
    - name: Get var_hostname(s)
      pause:
        prompt: "Please enter the hostname for {{ item.public_ip }}"
        echo: yes
      loop: "{{ ec2.instances }}"
      register: var_hostnames
    - name: Add new instances to host group
      add_host:
        hostname: "{{ item.item.public_ip }}"
        groupname: launched
        var_hostname: "{{ item.user_input }}"
      loop: "{{ var_hostnames.results }}"
      loop_control:
        label: "{{ item.user_input }}"

Example of a complete playbook for testing

- hosts: localhost
  gather_facts: false
  vars:
    ec2:
      instances:
        - public_ip: AAA.BBB.CCC.DD1
        - public_ip: AAA.BBB.CCC.DD2
  tasks:
    - name: Get var_hostname(s)
      pause:
        prompt: "Please enter the hostname for {{ item.public_ip }}"
        echo: yes
      loop: "{{ ec2.instances }}"
      register: var_hostnames
    - name: Add new instances to host group
      add_host:
        hostname: "{{ item.item.public_ip }}"
        groupname: launched
        var_hostname: "{{ item.user_input }}"
      loop: "{{ var_hostnames.results }}"
      loop_control:
        label: "{{ item.user_input }}"

- hosts: launched
  gather_facts: false
  tasks:
    - debug:
        var: var_hostname
shell> ansible-playbook pb.yml 

PLAY [localhost] *****************************************************************************

TASK [Get var_hostname(s)] *******************************************************************
[Get var_hostname(s)]
Please enter the hostname for AAA.BBB.CCC.DD1:
host_1^Mok: [localhost] => (item={'public_ip': 'AAA.BBB.CCC.DD1'})
[Get var_hostname(s)]
Please enter the hostname for AAA.BBB.CCC.DD2:
host_2^Mok: [localhost] => (item={'public_ip': 'AAA.BBB.CCC.DD2'})

TASK [Add new instances to host group] *******************************************************
ok: [localhost] => (item=host_1)
ok: [localhost] => (item=host_2)

PLAY [launched] ******************************************************************************

TASK [debug] *********************************************************************************
ok: [AAA.BBB.CCC.DD1] => 
  var_hostname: host_1
ok: [AAA.BBB.CCC.DD2] => 
  var_hostname: host_2

PLAY RECAP ***********************************************************************************
AAA.BBB.CCC.DD1: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
AAA.BBB.CCC.DD2: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63