# Playbook to build new VMs in RHV Cluste # Currently only builds RHEL VMs # Create Host - name: Preflight checks hosts: tag_build gather_facts: false tasks: - assert: that: - site == "sagely_dc" - is_virtual - name: Ensure Primary IP exists and is in DNS hosts: tag_build gather_facts: false collections: - netbox.netbox - freeipa.ansible_freeipa - redhat.rhv tasks: - name: Obtain SSO token for RHV ovirt_auth: url: "{{ ovirt_url }}" username: "{{ ovirt_username }}" insecure: true password: "{{ ovirt_password }}" delegate_to: localhost - name: Get unused IP Address from pool netbox_ip_address: netbox_url: "{{ netbox_api }}" netbox_token: "{{ netbox_token }}" data: prefix: 192.168.16.0/20 assigned_object: name: eth0 virtual_machine: "{{ inventory_hostname }}" state: new register: new_ip when: primary_ip4 is undefined delegate_to: localhost - set_fact: primary_ip4: "{{ new_ip.ip_address.address|ipaddr('address') }}" vm_hostname: "{{ inventory_hostname.split('.')[0] }}" vm_domain: "{{ inventory_hostname.split('.',1)[1] }}" delegate_to: localhost when: primary_ip4 is undefined - name: Primary IPv4 Assigned in Netbox netbox_virtual_machine: netbox_url: "{{ netbox_api }}" netbox_token: "{{ netbox_token }}" data: primary_ip4: "{{ primary_ip4 }}" name: "{{ inventory_hostname }}" delegate_to: localhost - name: Primary IPv4 Address debug: var: primary_ip4 - name: Ensure IP Address in IdM ipadnsrecord: records: - name: "{{ vm_hostname }}" zone_name: "{{ vm_domain }}" record_type: A record_value: - "{{ new_ip.ip_address.address|ipaddr('address') }}" create_reverse: true ipaadmin_password: "{{ ipaadmin_password }}" delegate_to: idm1.mgmt.toal.ca - name: Create VMs hosts: tag_build connection: local gather_facts: no collections: - netbox.netbox - redhat.rhv vars: # Workaround to get correct venv python interpreter ansible_python_interpreter: "{{ ansible_playbook_python }}" tasks: - name: Basic Disk Profile set_fact: vm_disks: - name: '{{ inventory_hostname }}_boot' bootable: true sparse: true descr: '{{ inventory_hostname }} Boot / Root disk' interface: virtio size: '{{ disk|default(40) }}' state: present storage_domain: "{{ rhv_storage_domain }}" activate: true when: vm_disks is not defined - name: Create VM Disks ovirt_disk: auth: '{{ ovirt_auth }}' name: '{{ item.name }}' description: '{{ item.descr }}' interface: '{{ item.interface }}' size: '{{ item.size|int * 1024000 }}' state: '{{ item.state }}' sparse: '{{ item.sparse }}' wait: true storage_domain: '{{ item.storage_domain }}' async: 300 poll: 15 loop: '{{ vm_disks }}' - set_fact: nb_query_filter: "slug={{ platform }}" - debug: msg='{{ query("netbox.netbox.nb_lookup", "platforms", api_filter=nb_query_filter, api_endpoint=netbox_api, token=netbox_token)[0].value.name }}' - name: Create VM in RHV ovirt_vm: auth: '{{ ovirt_auth }}' name: '{{ inventory_hostname }}' state: present memory: '{{ memory }}MiB' memory_guaranteed: '{{ (memory / 2)|int }}MiB' disks: '{{ vm_disks }}' cpu_cores: '{{ vcpus }}' cluster: '{{ cluster }}' # This is ugly Can we do better? operating_system: '{{ query("netbox.netbox.nb_lookup", "platforms", api_filter=nb_query_filter, api_endpoint=netbox_api, token=netbox_token)[0].value.name }}' type: server graphical_console: protocol: - vnc - spice boot_devices: - hd async: 300 poll: 15 notify: PXE Boot register: vm_result - name: Assign NIC ovirt_nic: auth: '{{ ovirt_auth }}' interface: virtio mac_address: '{{ item.mac_address|default(omit) }}' name: '{{ item.name }}' profile: '{{ item.untagged_vlan.name }}' network: '{{ item.untagged_vlan.name }}' # This is fragile state: '{{ (item.enabled == True) |ternary("plugged","unplugged") }}' linked: yes vm: '{{ inventory_hostname }}' loop: '{{ interfaces }}' register: interface_result - debug: var=interface_result - name: Host configured in Satellite redhat.satellite.host: username: "{{ satellite_admin_user }}" password: "{{ satellite_admin_pass }}" server_url: "{{ satellite_url }}" name: "{{ inventory_hostname }}" hostgroup: "RHEL8/RHEL8 Sandbox" organization: Toal.ca location: Lab ip: "{{ primary_ip4 }}" mac: "{{ interface_result.results[0].nic.mac.address }}" #fragile build: "{{ vm_result.changed |ternary(true,false) }}" validate_certs: no - name: Assign interface MACs to Netbox netbox_vm_interface: netbox_url: "{{ netbox_api }}" netbox_token: "{{ netbox_token }}" data: name: "{{ item.nic.name }}" mac_address: "{{ item.nic.mac.address }}" virtual_machine: "{{ inventory_hostname }}" loop: "{{ interface_result.results }}" handlers: - name: PXE Boot ovirt_vm: auth: "{{ ovirt_auth }}" name: "{{ inventory_hostname }}" boot_devices: - network state: running register: vm_build_result - name: Ensure VM is running and reachable hosts: tag_build gather_facts: no connection: local collections: - redhat.rhv vars: # Hack to work around virtualenv python interpreter ansible_python_interpreter: "{{ ansible_playbook_python }}" tasks: - name: VM is running ovirt_vm: auth: "{{ ovirt_auth }}" name: "{{ inventory_hostname }}" state: running boot_devices: - hd - name: Wait for SSH to be ready wait_for_connection: timeout: 1800 sleep: 5 # - name: Ensure IP address is correct in Netbox # netbox_virtual_machine: # data: # name: "{{ inventory_hostname }}" # primary_ip4: "{{ primary_ip4 }}" # netbox_url: "{{ netbox_api }}" # netbox_token: "{{ netbox_token }}" # state: present # delegate_to: localhost #TODO: Clear Build tag