How to pass variables of deployed VM (vmware_guest) to roles for further config

46 Views Asked by At

new to Ansible and having difficulty running roles on a newly deployed VM with vmware_guest. Trying to collect variables to be used within certain roles, but these seem not to be transferred.

I have this playbook that deploys and adds host for further configuration. VM deploys correctly.

Some clue how to do this would be appreciated.

---
- name: Deploy the VM
  hosts: localhost
  gather_facts: no

  tasks:
    - name: "Create VM from template"
      vmware_guest:
        validate_certs: false
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ vcenter_datacenter }}"
        cluster: "{{ vm_cluster }}"
        template: "{{ vm_template }}"
        name: "{{ vm_name }}"
        folder: "{{ vm_folder }}"
        #annotation: " {{ creationdate }}"
        hardware:
          num_cpus: "{{ vm_hw_cpu_n }}"
          memory_mb: "{{ vm_hw_ram_mb }}"
        disk:
          - size_gb: "{{ vm_disk_gb }}"
            type: thin
            datastore: "{{ vm_datastore_cluster }}"
        networks:
          - name: "{{ vm_net_name }}"
            type: static
            device_type: vmxnet3
            ip: 172.16.100.123
            netmask: 255.255.255.0
            gateway: 172.16.100.1
            connected: true
            start_connected: true
        customization:
          hostname: "{{ vm_name }}.domain.invalid"
          domain: domain.invalid
          dns_servers:
            - 172.16.100.10
            - 172.16.100.11
          dns_suffix:
            - domain.invalid
        state: present
        #state: poweredon
        wait_for_ip_address: true
      register: vm_info

    - name: Add host to inventory
      ansible.builtin.add_host:
        name: "{{ vm_info.instance.ipv4 }}"
        groups: vmware_vms
     

- name: Run Additional Configurations
  hosts: vmware_vms
  roles:
    - role: base
      vars:
        var_vm_name: "{{ vm_name }}"
        var_vm_ip: "{{ vm_info.instance.ipv4 }}"
        var_vm_domain: "{{ vm_info.customization.domain }}"
        var_vm_fqdn: "{{ vm_info.customization.hostname }}"
        var_vm_dnsservers: "{{ vm_info.customization.dns_servers }}"

The error I receive:

"msg": "AnsibleUndefinedVariable: 127.0.0.1       localhost\n127.0.1.1       {{ var_vm_name }}\n{{ var_vm_ip }} {{ var_vm_fqdn }} {{ var_vm_name }}\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n: {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. 127.0.0.1       localhost\n127.0.1.1       {{ var_vm_name }}\n{{ var_vm_ip }} {{ var_vm_fqdn }} {{ var_vm_name }}\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n: {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined",
  "exception": "Traceback (most recent call last):\n  File \"/usr/lib/python3.9/site-packages/ansible/template/__init__.py\", line 1004, in do_template\n    res = myenv.concat(rf)\n  File \"/usr/lib/python3.9/site-packages/ansible/template/native_helpers.py\", line 83, in ansible_concat\n    return ''.join([to_text(v) for v in nodes])\n  File \"/usr/lib/python3.9/site-packages/ansible/template/native_helpers.py\", line 83, in <listcomp>\n    return ''.join([to_text(v) for v in nodes])\n  File \"<template>\", line 12, in root\n  File \"/usr/lib/python3.9/site-packages/ansible/template/__init__.py\", line 295, in wrapper\n    ret = func(*args, **kwargs)\n  File \"/usr/lib/python3.9/site-packages/ansible/template/__init__.py\", line 547, in _ansible_finalize\n    return thing if _fail_on_undefined(thing) is not None else ''\n  File \"/usr/lib/python3.9/site-packages/ansible/template/__init__.py\", line 519, in _fail_on_undefined\n    elif is_sequence(data):\n  File \"/usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py\", line 94, in is_sequence\n    if not include_strings and is_string(seq):\n  File \"/usr/lib/python3.9/site-packages/jinja2/runtime.py\", line 852, in _fail_with_undefined_error\n    raise self._undefined_exception(self._undefined_message)\nansible.errors.AnsibleUndefinedVariable: 127.0.0.1       localhost\n127.0.1.1       {{ var_vm_name }}\n{{ var_vm_ip }} {{ var_vm_fqdn }} {{ var_vm_name }}\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n: {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/action/template.py\", line 152, in run\n    resultant = templar.do_template(template_data, preserve_trailing_newlines=True, escape_backslashes=False, overrides=overrides)\n  File \"/usr/lib/python3.9/site-packages/ansible/template/__init__.py\", line 1038, in do_template\n    raise AnsibleUndefinedVariable(e, orig_exc=e)\nansible.errors.AnsibleUndefinedVariable: 127.0.0.1       localhost\n127.0.1.1       {{ var_vm_name }}\n{{ var_vm_ip }} {{ var_vm_fqdn }} {{ var_vm_name }}\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n: {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. 127.0.0.1       localhost\n127.0.1.1       {{ var_vm_name }}\n{{ var_vm_ip }} {{ var_vm_fqdn }} {{ var_vm_name }}\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n: {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined. {{ vm_info.instance.ipv4 }}: 'vm_info' is undefined. 'vm_info' is undefined\n",
  "_ansible_no_log": null,
  "changed": false

Tried numerous methods but not sure I understand how this should be done.

1

There are 1 best solutions below

0
ikora On

You have an issue of variable delegation/scope.

Let me explain this: For example in this variable:

var_vm_ip: "{{ vm_info.instance.ipv4 }}"

You had this variable on another host, not on the current host. Take into consideration that the first task is executed on "localhost" and the rest are executed on the inventory group "vmware_vms".

How can we solve this? Using:CachedFacts/Hostvars First, I would create a set_fact step before the end of the first task, so we can pass the variables to the second task more easily:

- name: SetFact vminfo
      set_fact:
        vm_information: "{{ vm_info }}"
- name: Run Additional Configurations
  hosts: vmware_vms
  gather_facts: no
  roles:
    - role: base
      vars:
        var_vm_name: "{{ vm_name }}"
        var_vm_ip: "{{ hostvars['localhost'].vm_information.instance.ipv4 }}"
        var_vm_domain: "{{ hostvars['localhost'].vm_information.customization.domain }}"
        var_vm_fqdn: "{{ hostvars['localhost'].vm_information.customization.hostname }}"
        var_vm_dnsservers: "{{ hostvars['localhost'].vm_information.customization.dns_servers }}"