From 7bb88aaa661dc6756e862562c47368de11657f44 Mon Sep 17 00:00:00 2001 From: Georg Date: Wed, 5 Jan 2022 23:59:13 +0100 Subject: Init Ansible NetBox DHCP POC deployment Signed-off-by: Georg --- ansible/deployment_poc/tasks/configure_dhcp.yml | 31 +++++++++++ ansible/deployment_poc/tasks/configure_libvirt.yml | 61 ++++++++++++++++++++++ ansible/deployment_poc/tasks/init_dhcp.yml | 7 +++ .../tasks/netbox_evaluate_cluster.yml | 50 ++++++++++++++++++ .../deployment_poc/tasks/netbox_evaluate_ip.yml | 5 ++ .../tasks/netbox_evaluate_prefix.yml | 6 +++ .../deployment_poc/tasks/netbox_evaluate_site.yml | 5 ++ .../deployment_poc/tasks/netbox_evaluate_vm.yml | 23 ++++++++ .../deployment_poc/tasks/netbox_query_cluster.yml | 14 +++++ ansible/deployment_poc/tasks/netbox_query_ip.yml | 14 +++++ .../deployment_poc/tasks/netbox_query_prefix.yml | 14 +++++ ansible/deployment_poc/tasks/netbox_query_site.yml | 14 +++++ ansible/deployment_poc/tasks/netbox_query_vm.yml | 15 ++++++ ansible/deployment_poc/tasks/netbox_tags_post.yml | 24 +++++++++ ansible/deployment_poc/tasks/netbox_tags_pre.yml | 34 ++++++++++++ 15 files changed, 317 insertions(+) create mode 100644 ansible/deployment_poc/tasks/configure_dhcp.yml create mode 100644 ansible/deployment_poc/tasks/configure_libvirt.yml create mode 100644 ansible/deployment_poc/tasks/init_dhcp.yml create mode 100644 ansible/deployment_poc/tasks/netbox_evaluate_cluster.yml create mode 100644 ansible/deployment_poc/tasks/netbox_evaluate_ip.yml create mode 100644 ansible/deployment_poc/tasks/netbox_evaluate_prefix.yml create mode 100644 ansible/deployment_poc/tasks/netbox_evaluate_site.yml create mode 100644 ansible/deployment_poc/tasks/netbox_evaluate_vm.yml create mode 100644 ansible/deployment_poc/tasks/netbox_query_cluster.yml create mode 100644 ansible/deployment_poc/tasks/netbox_query_ip.yml create mode 100644 ansible/deployment_poc/tasks/netbox_query_prefix.yml create mode 100644 ansible/deployment_poc/tasks/netbox_query_site.yml create mode 100644 ansible/deployment_poc/tasks/netbox_query_vm.yml create mode 100644 ansible/deployment_poc/tasks/netbox_tags_post.yml create mode 100644 ansible/deployment_poc/tasks/netbox_tags_pre.yml (limited to 'ansible/deployment_poc/tasks') diff --git a/ansible/deployment_poc/tasks/configure_dhcp.yml b/ansible/deployment_poc/tasks/configure_dhcp.yml new file mode 100644 index 0000000..9802b0e --- /dev/null +++ b/ansible/deployment_poc/tasks/configure_dhcp.yml @@ -0,0 +1,31 @@ +--- +- name: Configure DHCP + block: + - name: Query DHCP server + set_fact: + dhcp_os: "{{ hostvars[dhcp_host]['platforms'][0] }}" + + - name: Insert DHCP host block + ansible.builtin.blockinfile: + #backup: yes + block: "{{ lookup('template', '../templates/dhcpd.conf.j2') }}" + marker: "### {mark} Ansible managed block for {{ vm_name }} ###" + path: "/etc/dhcpd.conf" + #delegate_to: "{{ dhcp_host }}" + become: yes + become_method: doas + when: dhcp_os == 'openbsd-x86_64' + + - name: Insert DHCP static mapping + vyos.vyos.vyos_config: + backup: yes + backup_options: + dir_path: "/tmp/" + comment: "Configured as part of {{ vm_name }} deployment" + lines: + - "set service dhcp-server shared-network-name LAN subnet {{ prefix_display }} static-mapping {{ vm_name }} mac-address {{ mac_address }}" + - "set service dhcp-server shared-network-name LAN subnet {{ prefix_display }} static-mapping {{ vm_name }} ip-address {{ ip_address }}" + save: no # CHANGE BEFORE ROLLOUT + when: dhcp_os == 'vyos-x86_64' + delegate_to: "{{ dhcp_host }}" + diff --git a/ansible/deployment_poc/tasks/configure_libvirt.yml b/ansible/deployment_poc/tasks/configure_libvirt.yml new file mode 100644 index 0000000..b3e49b6 --- /dev/null +++ b/ansible/deployment_poc/tasks/configure_libvirt.yml @@ -0,0 +1,61 @@ +--- +- name: Provision VM + block: + - name: Create domain template + ansible.builtin.template: + src: "../templates/libvirt-template.xml.j2" + dest: "../templates/libvirt-{{ inventory_hostname }}.xml" + group: lysergic + mode: '0660' + + - name: Create storage template + ansible.builtin.template: + src: "../templates/libvirt-storage-template.xml.j2" + dest: "../templates/generated/libvirt-storage-{{ inventory_hostname }}.xml" + group: lysergic + mode: '0660' + + - name: Define domain + virt: + uri: "{{ libvirt_url }}" + command: define + xml: "{{ lookup('template', '../templates/libvirt-template.xml.j2') }}" + autostart: no + # delegate_to: localhost + + - name: Query volumes + ansible.builtin.command: + argv: + - /usr/bin/virsh + - -c + - "{{ libvirt_url }}" + - vol-list + - "{{ storage.name }}" + register: volumes + no_log: true + + - name: Define volume + ansible.builtin.command: + argv: + - /usr/bin/virsh + - -c + - "{{ libvirt_url }}" + - vol-create + - "{{ storage.name }}" + - "../templates/generated/libvirt-storage-{{ inventory_hostname }}.xml" + when: vm_name not in volumes.stdout + + - name: Fetch MAC address + ansible.builtin.shell: "/usr/bin/virsh -c {{ libvirt_url }} domiflist {{ vm_name }} | awk '{print $5}' | cut -d/ -f 1 | tail -n 2 | head -n1" # ewww :-( + register: domiflist_mac + + - name: Store MAC address + set_fact: + mac_address: "{{ domiflist_mac.stdout }}" + + delegate_to: localhost + + always: + - name: Debug + ansible.builtin.debug: + msg: "{{ libvirt_url if libvirt_url is defined }} - {{ storage.name if storage is defined }} - {{ mac_address if mac_address is defined }}" diff --git a/ansible/deployment_poc/tasks/init_dhcp.yml b/ansible/deployment_poc/tasks/init_dhcp.yml new file mode 100644 index 0000000..fbd4765 --- /dev/null +++ b/ansible/deployment_poc/tasks/init_dhcp.yml @@ -0,0 +1,7 @@ +--- +- name: Initialize DHCP configurator + include_tasks: "../tasks/configure_dhcp.yml" + vars: + dhcp_host: "{{ item }}" + with_items: "{{ dhcp_servers }}" + diff --git a/ansible/deployment_poc/tasks/netbox_evaluate_cluster.yml b/ansible/deployment_poc/tasks/netbox_evaluate_cluster.yml new file mode 100644 index 0000000..1e8b07f --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_evaluate_cluster.yml @@ -0,0 +1,50 @@ +--- +- name: Evaluate cluster + block: + - name: Increment counters + set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int +1 }}" + host_count: "{{ 0 if retry_count is undefined else host_count | int +1 }}" + + - name: Pick cluster host + set_fact: + #host_choice: "{{ nb_hosts.json.results[nb_hosts.json.count | random | int] }}" #PICK RANDOM + #host_choice: "{{ nb_hosts.json.results[1] }}" #FAIL TEST + host_choice: "{{ nb_hosts.json.results[host_count | int] }}" #INCREMENT + no_log: true + + - name: Evaluate cluster host status + set_fact: + host_status: "{{ host_choice.status.value }}" + #register: host_status + + - name: Evaluate cluster host name + set_fact: + host: "{{ host_choice.name }}" + + - name: Evaluate cluster host status + fail: + msg: Host is not ready. + when: host_status != 'active' + + - name: Evaluate cluster host configuration + set_fact: + storage: "{{ host_choice.config_context.storage[0] }}" + #deployment_servers: "{{ host_choice.config_context.deployment_servers }}" + dhcp_servers: "{{ host_choice.config_context.dhcp_servers }}" + dns_servers: "{{ host_choice.config_context.dns_servers }}" + when: host_status == 'active' + + rescue: + - name: Check retry counter + fail: + msg: "Too many retries - no host is ready" + when: retry_count | int == 3 and host_status != 'active' + + - debug: + msg: "{{ host if host is defined }} - {{ host_status if host_status is defined }}" + + - name: Re-evaluate cluster + include_tasks: "../tasks/netbox_evaluate_cluster.yml" + when: host_status != 'active' + diff --git a/ansible/deployment_poc/tasks/netbox_evaluate_ip.yml b/ansible/deployment_poc/tasks/netbox_evaluate_ip.yml new file mode 100644 index 0000000..828b15e --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_evaluate_ip.yml @@ -0,0 +1,5 @@ +--- +- name: Define IP address + set_fact: + ip_address: "{{ nb_ip.json[0].address | ansible.netcommon.ipaddr('address') }}" + diff --git a/ansible/deployment_poc/tasks/netbox_evaluate_prefix.yml b/ansible/deployment_poc/tasks/netbox_evaluate_prefix.yml new file mode 100644 index 0000000..74983e4 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_evaluate_prefix.yml @@ -0,0 +1,6 @@ +--- +- name: Evaluate prefix options + set_fact: + prefix_id: "{{ nb_prefix.json.results[0].id }}" + prefix_display: "{{ nb_prefix.json.results[0].display }}" + diff --git a/ansible/deployment_poc/tasks/netbox_evaluate_site.yml b/ansible/deployment_poc/tasks/netbox_evaluate_site.yml new file mode 100644 index 0000000..abd5347 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_evaluate_site.yml @@ -0,0 +1,5 @@ +--- +- name: Gather site configuration + set_fact: + site_id: "{{ nb_site.json.results[0].id }}" + diff --git a/ansible/deployment_poc/tasks/netbox_evaluate_vm.yml b/ansible/deployment_poc/tasks/netbox_evaluate_vm.yml new file mode 100644 index 0000000..8188024 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_evaluate_vm.yml @@ -0,0 +1,23 @@ +--- +- name: Pick hard- and software + # not needed, can be pulled from hostvars + set_fact: + vcpus: "{{ nb_vm.json.results[0].vcpus | int }}" + os: "{{ nb_vm.json.results[0].platform.name }}" + +# - name: Pick virtual hardware specifications +# # not needed, part of hostvars +# set_fact: +# memory: "{{ nb_vm.json.results[0].memory }}" +# disk: "{{ nb_vm.json.results[0].disk }}" + +- name: Pick metadata + set_fact: + id: "{{ nb_vm.json.results[0].id }}" + site: "{{ hostvars[inventory_hostname]['sites'][0] }}" + status: "{{ nb_vm.json.results[0].status.value }}" + +# # not needed, part of hostvars +# #tags: "{{ nb_vm.json.results[0].tags[0].slug }}" +# #tags: "{{ nb_vm.json.results[0].tags | sum(start=[]) | map(attribute='slug') }}" + diff --git a/ansible/deployment_poc/tasks/netbox_query_cluster.yml b/ansible/deployment_poc/tasks/netbox_query_cluster.yml new file mode 100644 index 0000000..1f948d1 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_query_cluster.yml @@ -0,0 +1,14 @@ +--- +- name: Locate cluster hosts + ansible.builtin.uri: + url: "{{ endpoint }}/dcim/devices/?cluster_id={{ nb_vm.json.results[0].cluster.id }}" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: GET + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + register: nb_hosts + delegate_to: localhost + diff --git a/ansible/deployment_poc/tasks/netbox_query_ip.yml b/ansible/deployment_poc/tasks/netbox_query_ip.yml new file mode 100644 index 0000000..f0ed7b7 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_query_ip.yml @@ -0,0 +1,14 @@ +--- +- name: Query available address + ansible.builtin.uri: + url: "{{ endpoint }}/ipam/prefixes/{{ prefix_id }}/available-ips/?limit=1" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: GET + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + register: nb_ip + delegate_to: localhost + diff --git a/ansible/deployment_poc/tasks/netbox_query_prefix.yml b/ansible/deployment_poc/tasks/netbox_query_prefix.yml new file mode 100644 index 0000000..d0c0990 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_query_prefix.yml @@ -0,0 +1,14 @@ +--- +- name: Query prefix + ansible.builtin.uri: + url: "{{ endpoint }}/ipam/prefixes/?site_id={{ site_id }}&tenant={{ tenant }}&limit=1" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: GET + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + register: nb_prefix + delegate_to: localhost + diff --git a/ansible/deployment_poc/tasks/netbox_query_site.yml b/ansible/deployment_poc/tasks/netbox_query_site.yml new file mode 100644 index 0000000..5894a6c --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_query_site.yml @@ -0,0 +1,14 @@ +--- +- name: Query site + ansible.builtin.uri: + url: "{{ endpoint }}/dcim/sites/?slug={{ site }}" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: GET + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + register: nb_site + delegate_to: localhost + diff --git a/ansible/deployment_poc/tasks/netbox_query_vm.yml b/ansible/deployment_poc/tasks/netbox_query_vm.yml new file mode 100644 index 0000000..52308f0 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_query_vm.yml @@ -0,0 +1,15 @@ +--- + # consider ditching this block, would need to work around missing cluster ID in hostvars +- name: Query VM + ansible.builtin.uri: + url: "{{ endpoint }}/virtualization/virtual-machines/?name={{ inventory_hostname }}" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: GET + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + register: nb_vm + delegate_to: localhost + diff --git a/ansible/deployment_poc/tasks/netbox_tags_post.yml b/ansible/deployment_poc/tasks/netbox_tags_post.yml new file mode 100644 index 0000000..9b24ca3 --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_tags_post.yml @@ -0,0 +1,24 @@ +--- +- name: Post-deployment tagging + block: + - name: Construct body for tagging + set_fact: + body2: ' {% for tag in tag_exist %}{% if loop.last %}{"slug": "{{ tag }}"}{% else %}{"slug": "{{ tag }}"},{% endif %}{% endfor %}' + when: tag_exist is defined + + - name: Set post-deployment tags + ansible.builtin.uri: + url: "{{ endpoint }}/virtualization/virtual-machines/{{ id }}/" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: PATCH + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + body_format: json + body: ' {"tags": [ {{ body2 }}]}' + delegate_to: localhost + when: body2 is defined + no_log: true + diff --git a/ansible/deployment_poc/tasks/netbox_tags_pre.yml b/ansible/deployment_poc/tasks/netbox_tags_pre.yml new file mode 100644 index 0000000..23a804b --- /dev/null +++ b/ansible/deployment_poc/tasks/netbox_tags_pre.yml @@ -0,0 +1,34 @@ +--- +- name: Pre-deployment tagging + block: + - name: Gather tags + set_fact: + tag_exist: "{{ tags }}" + tag_append: "['active-deployment']" + + - name: Merge tags + set_fact: + tag_merged: "{{ tag_merged + [item] }}" + with_items: + - "{{ tag_exist }}" + - "{{ tag_append }}" + + - name: Construct body for tagging + set_fact: + body1: ' {% for tag in tag_merged %}{% if loop.last %}{"slug": "{{ tag }}"}{% else %}{"slug": "{{ tag }}"},{% endif %}{% endfor %}' + + - name: Set pre-deployment tags + ansible.builtin.uri: + url: "{{ endpoint }}/virtualization/virtual-machines/{{ id }}/" + client_cert: "{{ cert }}" + client_key: "{{ key }}" + method: PATCH + return_content: yes + headers: + Accept: application/json + Authorization: "Token {{ token }}" + body_format: json + body: ' {"tags": [ {{ body1 }}]}' + delegate_to: localhost + no_log: true + -- cgit v1.2.3