Last active
December 25, 2023 20:18
-
-
Save ngschmidt/88fe09a1c5733735a4232dd24c44f78e to your computer and use it in GitHub Desktop.
GitHub Actions vSphere + Netbox VM Deployment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
- hosts: localhost | |
gather_facts: true | |
# Before executing ensure that the prerequisites are installed | |
# `ansible-galaxy collection install vmware.vmware_rest netbox.netbox` | |
# `python3 -m pip install aiohttp pynetbox` | |
# We start with a pre-check playbook, if it fails, we don't want to | |
# make changes | |
any_errors_fatal: true | |
vars_files: | |
- "parameters.yaml" | |
- "options.yaml" | |
tasks: | |
- name: "Debug" | |
ansible.builtin.debug: | |
msg: '{{ image_data[vm_data["template"]] }}' | |
- name: "Build the VM" | |
vmware.vmware_rest.vcenter_vmtemplate_libraryitems: | |
vcenter_hostname: '{{ lookup("env", "VHOSTNAME") }}' | |
vcenter_username: '{{ lookup("env", "VAPIUSER") }}' | |
vcenter_password: '{{ lookup("env", "VAPIPASS") }}' | |
vcenter_validate_certs: false | |
name: '{{ vm_data.name }}' | |
library: '{{ vm_data.library }}' | |
template_library_item: '{{ image_data[vm_data["template"]] }}' | |
placement: | |
cluster: '{{ vm_data.cluster }}' | |
folder: '{{ vm_data.folder }}' | |
disk_storage: | |
datastore: '{{ vm_data.datastore }}' | |
hardware_customization: | |
cpu_update: | |
num_cpus: '{{ vm_data.hardware.cpus }}' | |
memory_update: | |
memory: '{{ vm_data.hardware.memory }}' | |
session_timeout: 1200 | |
state: deploy | |
register: vmware_vm | |
- name: "Report the VM!" | |
ansible.builtin.debug: | |
var: vmware_vm | |
- name: "Start the VM!" | |
vmware.vmware_rest.vcenter_vm_power: | |
vcenter_hostname: '{{ lookup("env", "VHOSTNAME") }}' | |
vcenter_username: '{{ lookup("env", "VAPIUSER") }}' | |
vcenter_password: '{{ lookup("env", "VAPIPASS") }}' | |
vcenter_validate_certs: false | |
vm: '{{ vmware_vm.value }}' | |
state: start | |
- name: "Wait for the VM to fully boot" | |
ansible.builtin.pause: | |
minutes: 2 | |
- name: "Fetch VM networking information" | |
vmware.vmware_rest.vcenter_vm_guest_networking_interfaces_info: | |
vcenter_hostname: '{{ lookup("env", "VHOSTNAME") }}' | |
vcenter_username: '{{ lookup("env", "VAPIUSER") }}' | |
vcenter_password: '{{ lookup("env", "VAPIPASS") }}' | |
vcenter_validate_certs: false | |
vm: "{{ vmware_vm.value }}" | |
register: vmware_vm_networking_ifaces | |
- name: "Report the VM's Networking Interfaces Info!" | |
ansible.builtin.debug: | |
var: vmware_vm_networking_ifaces | |
- name: "Fetch VM networking information" | |
vmware.vmware_rest.vcenter_vm_guest_networking_info: | |
vcenter_hostname: '{{ lookup("env", "VHOSTNAME") }}' | |
vcenter_username: '{{ lookup("env", "VAPIUSER") }}' | |
vcenter_password: '{{ lookup("env", "VAPIPASS") }}' | |
vcenter_validate_certs: false | |
vm: "{{ vmware_vm.value }}" | |
register: vmware_vm_networking | |
- name: "Report the VM's Networking Info!" | |
ansible.builtin.debug: | |
var: vmware_vm_networking | |
- name: "Register the VM in Netbox!" | |
netbox.netbox.netbox_virtual_machine: | |
netbox_token: '{{ lookup("env", "NETBOX_TOKEN") }}' | |
netbox_url: '{{ lookup("env", "NETBOX_URL") }}' | |
validate_certs: false | |
data: | |
cluster: '{{ lookup("env", "NETBOX_CLUSTER") }}' | |
name: '{{ vm_data.name }}' | |
description: '{{ vmware_vm }}' | |
local_context_data: '{{ vm_data }}' | |
memory: '{{ vm_data.hardware.memory }}' | |
vcpus: '{{ vm_data.hardware.cpus }}' | |
- name: "Configure VM Interface in Netbox!" | |
netbox.netbox.netbox_vm_interface: | |
netbox_token: '{{ lookup("env", "NETBOX_TOKEN") }}' | |
netbox_url: '{{ lookup("env", "NETBOX_URL") }}' | |
validate_certs: false | |
data: | |
name: '{{ vm_data.name }}_intf_{{ item.mac_address | replace(":", "") | safe }}' | |
virtual_machine: '{{ vm_data.name }}' | |
vrf: 'Campus' | |
mac_address: '{{ item.mac_address }}' | |
with_items: '{{ vmware_vm_networking_ifaces.value }}' | |
- name: "Reserve IP" | |
netbox.netbox.netbox_ip_address: | |
netbox_token: '{{ lookup("env", "NETBOX_TOKEN") }}' | |
netbox_url: '{{ lookup("env", "NETBOX_URL") }}' | |
validate_certs: false | |
data: | |
address: '{{ item.ip.ip_addresses[0].ip_address }}/{{ item.ip.ip_addresses[0].prefix_length }}' | |
vrf: 'Campus' | |
assigned_object: | |
virtual_machine: '{{ vm_data.name }}' | |
state: present | |
with_items: '{{ vmware_vm_networking_ifaces.value }}' | |
register: ip_obj | |
- name: "Debug" | |
ansible.builtin.debug: | |
msg: "{{ ip_obj }}" | |
- name: "Finalize the VM in Netbox!" | |
netbox.netbox.netbox_virtual_machine: | |
netbox_token: '{{ lookup("env", "NETBOX_TOKEN") }}' | |
netbox_url: '{{ lookup("env", "NETBOX_URL") }}' | |
validate_certs: false | |
data: | |
cluster: 'eng-lab-c0' | |
name: '{{ vm_data.name }}' | |
primary_ip4: | |
address: '{{ vmware_vm_networking_ifaces.value[0].ip.ip_addresses[0].ip_address }}/{{ vmware_vm_networking_ifaces.value[0].ip.ip_addresses[0].prefix_length }}' | |
vrf: "Campus" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "On-Demand: Build VM" | |
on: | |
workflow_dispatch: | |
inputs: | |
machine_name: | |
description: "Machine Name" | |
required: true | |
default: "abcde" | |
template: | |
description: "VM Template UUID" | |
required: true | |
type: choice | |
options: | |
- alpine_latest | |
- ubuntu_latest | |
- debian_latest | |
default: "alpine_latest" | |
library: | |
description: "Content Library" | |
required: true | |
default: "9b15789e-af13-41fe-a931-a78d9fde840e" | |
hardware_cpus: | |
description: "VM vCPU Count" | |
required: true | |
default: "1" | |
hardware_memory: | |
description: "VM Memory Allocation (in MB)" | |
required: true | |
default: "512" | |
permissions: | |
contents: read | |
jobs: | |
build: | |
runs-on: self-hosted | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Create Variable YAML File | |
run: | | |
cat <<EOF > roles/vmware_rest/parameters.yaml | |
--- | |
vm_data: | |
name: "${{ github.event.inputs.machine_name }}" | |
template: "${{ github.event.inputs.template }}" | |
cluster: "domain-c1008" | |
datastore: "datastore-73010" | |
folder: "group-v1100" | |
library: "${{ github.event.inputs.library }}" | |
hardware: | |
cpus: ${{ github.event.inputs.hardware_cpus }} | |
memory: ${{ github.event.inputs.hardware_memory }} | |
EOF | |
cat <<EOF > roles/vmware_rest/options.yaml | |
--- | |
image_data: | |
alpine_latest: "e162b08e-a9a4-4a37-af61-d3f5397360af" | |
ubuntu_latest: "a609b303-931a-4c27-a2c5-06cf5a831695" | |
debian_latest: "78bfb9cd-c82a-4864-9755-a915974492db" | |
EOF | |
- name: Build VM | |
run: | | |
cd roles/vmware_rest/ | |
cat parameters.yaml | |
cat options.yaml | |
export VAPIUSER="${{ secrets.VAPIUSER }}" | |
export VAPIPASS="${{ secrets.VAPIPASS }}" | |
export VHOSTNAME="vcenter.lab.engyak.net" | |
export NETBOX_TOKEN="${{ secrets.NETBOX_TOKEN }}" | |
export NETBOX_URL="https://netbox-url" | |
export NETBOX_CLUSTER="eng-lab-c0" | |
ansible-playbook build_vm.yml |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment