Milestone 6 ‐ Blue Network and vyos Provisioning with Ansible - Jacob-Mayotte/SYS480 GitHub Wiki
💡The intersection between Virtual Machine Automation and Physical Networking is interesting. How do you provision a system that is meant to be on another network? We will use a combination of PowerCLI to control the network the virtual machines are on and Ansible to adjust the actual virtual machine OS settings. Automating the vyos router is not an easy task to start with but it is the logical one before we configure the Blue network
Milestone 6.1: BlueX Networking
Requirements:
Add a new function (e.g. called New-Network) that creates a Virtual Switch and Portgroup
function new_Network {
try {
# Prompt the user for the new network name
$netName = Read-Host -Prompt "Please Enter the new Network name"
# Create the switch
New-VirtualSwitch -Name $netName -VMHost $conf.esxi_host -ErrorAction Stop
# Create the port group
New-VirtualPortGroup -Name $netName -VirtualSwitch $netName -ErrorAction Stop
Write-Host "Network '$netName' created successfully." -ForegroundColor Green
} catch {
Write-Host "Error: $_" -ForegroundColor Red
}
}
Sources:
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/new-virtualswitch/#Default
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/new-virtualportgroup/#Default
Add a new function (e.g. called Get-IP) to get the IP, vm name and MAC address from the first interface of a named VM.
function Get-IP
{
try {
# Prompt user to select a VM
$selectedVM = Select-VM -folderName $conf.vm_folder
if ($selectedVM) {
# Get the first network adapter of the selected VM
$networkAdapter = $selectedVM | Get-NetworkAdapter | Select-Object -First 1
if ($networkAdapter) {
# Get the IP, VM name, and MAC address
$ipAddress = $selectedVM.Guest.IPAddress[0]
$macAddress = $networkAdapter.MacAddress
# Debug info
Write-Host "VM Name: $($selectedVM.Name)"
Write-Host "IP Address: $ipAddress"
Write-Host "MAC Address: $macAddress"
} else
{
Write-Host "No network adapter found for VM '$($selectedVM.Name)'." -ForegroundColor Yellow
}
}
} catch
{
Write-Host "Error: $_" -ForegroundColor Red
}
}
Sources:
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/get-networkadapter/#VirtualDeviceGetter
- https://communities.vmware.com/t5/ESXi-Discussions/Quick-way-to-gather-all-VM-guest-names-and-IP-addresses/td-p/1330279 // Get all IP's explained
Demo
Show the two new functions... well functioning!
- Run the New-Network function, show new network in GUI
- Run Get-IP, explain headache of issue here. Code works for some VM's while it wont for others.
Milestone 6.2: blueX-fw &more util functions
Deliverable 2: This was easy. I just ran my driver file and created a new VM named: Blue1-FW
Deliverable 3: Create a utility function within 480-utils.ps1 that will start a VM or VMs with by name. Add functions to start and stop VMs. Used a switch statement:
function manage_Power
{
try
{
# Prompt user to select a VM
$selectedVM = Select-VM -folderName $conf.vm_folder
if ($selectedVM) {
# Prompt user to select a power operation
$powerOperation = Read-Host -Prompt "Enter the power operation (start, stop, restart)"
# Perform the power operation based on the user input
switch ($powerOperation) {
"start" {
Start-VM -VM $selectedVM -Confirm:$false
Write-Host "VM '$($selectedVM.Name)' started successfully." -ForegroundColor Green
}
"stop" {
Stop-VM -VM $selectedVM -Confirm:$false
Write-Host "VM '$($selectedVM.Name)' stopped successfully." -ForegroundColor Green
}
"restart" {
Restart-VM -VM $selectedVM -Confirm:$false
Write-Host "VM '$($selectedVM.Name)' restarted successfully." -ForegroundColor Green
}
default {
Write-Host "Invalid power operation. Please enter a valid operation (start, stop, restart)." -ForegroundColor Red
}
}
}
} catch
{
Write-Host "Error: $_" -ForegroundColor Red
}
}
Sources:
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/start-vm/#Default
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/stop-vm/#Default
- https://lazyadmin.nl/powershell/powershell-switch-statement/
Deliverable 4: Create a utility function called Set-Network within 480-utils.ps1 that sets a virtual machine network adapter to the network of your choice. Add a function (e.g. Called Set-Network) that lets you set the network on the different interfaces on a VM.
function Set-Network
{
try
{
# Prompt user to select a VM
$selectedVM = Select-VM -folderName $conf.vm_folder
if ($selectedVM)
{
# retrieves the list of available virtual networks
$virtualNetworks = Get-VirtualNetwork
# Display the listr of virtual networks to the user
Write-Host "Available Virtual Networks:" $virtualNetworks | Format-Table -Property Name
# Prompt user to select a virtual network
$selectedNetwork = Read-Host -Prompt "Enter the name of the virtual network to set"
# Check if the selected network exists
if ($virtualNetworks.Name -contains $selectedNetwork)
{
# Get the network adapter settings of the selected VM
$networkAdapters = $selectedVM | Get-NetworkAdapter
# Display the list of network adapters to user
Write-Host "Available Network Adapters for $($selectedVM.Name):"
$networkAdapters | Format-Table -Property Name, NetworkName
# Promept user to select a network adapter
Write-Host "Select the network adapter by its index:"
# Loop through network adapters and display them with their index
for ($i = 0; $i -lt $networkAdapters.Count; $i++)
{
# Display the network adapter name and network name with their index
Write-Host "[$($i + 1)] $($networkAdapters[$i].Name) - $($networkAdapters[$i].NetworkName)"
}
# Prompts the user to enter the index number of the network adapter to set
$selectedAdapterIndex = Read-Host -Prompt "Enter the index number of the network adapter to set"
# Check if the input is a valid number and within the range of available adapters (RegEx string match - used earlier in the script)
if ($selectedAdapterIndex -match '^\d+$' -and $selectedAdapterIndex -ge 1 -and $selectedAdapterIndex -le $networkAdapters.Count)
{
# Get the network adapter object based on the selected index
$selectedAdapter = $networkAdapters[$selectedAdapterIndex - 1]
# Set the network adapter to the selected virtual network
Set-NetworkAdapter -NetworkAdapter $selectedAdapter -NetworkName $selectedNetwork
Write-Host "Network adapter '$($selectedAdapter.Name)' on VM '$($selectedVM.Name)' set to '$selectedNetwork' successfully." -ForegroundColor Green
} else
{
Write-Host "Invalid index. Please enter a valid index between 1 and $($networkAdapters.Count)." -ForegroundColor Red
}
} else
{
Write-Host "Virtual network '$selectedNetwork' not found." -ForegroundColor Red
}
}
} catch
{
Write-Host "Error: $_" -ForegroundColor Red
}
}
Sources:
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/get-virtualnetwork/#Default
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/get-networkadapter/#VirtualDeviceGetter
- https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.core/commands/set-networkadapter/#Default
Demo:
- Create a linked clone from Vyos VM, then create a new VM called:
FW-Blue1
- Sets a virtual machine network adapter to the network of your choice - In your video, demonstrate this against the internal eth1 interface on fw-blue1.
- Show the power function!
Miletsone 6.3: Ansible Ping
Fortunately Devin provides a lot for this milestone:
Using the install guide from: https://greenmountaincyber.com/docs/topics/vmware/powercli/xubuntu-dependencies I installed Ansible
sudo apt install sshpass python3-paramiko git
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible
ansible --version
cat >> ~/.ansible.cfg << EOF
[defaults]
host_key_checking = false
EOF
I was really stumped here until I spoke to Ryan. I was confused because we did not have a vyos machine in place at this point, but after speaking w/ Peers/Ryan it became clear that I was supposed to create a new VM and just uppload the Vyos ISO to it. Then I would create a base image of the new vyos machine.
Vyos machine info:
-
Hostname: 480-fw-vyos
-
Default creds: Username:
vyos
Password:vyos
-
Followed Devin's Video
-
Okay to really break this down for myself because I learned a ton here. I created a new vyos fw vm, completely new and then created a base snapshot/base vm. This is just a template to use for other future vyos fw's. Since I have a base vyos fw now I can create a linked clone. We use the linkedcloner.ps1 file to create said linked vyos clone. I did this and created the new usable vyos fw:
fw-blue
. I need to run my script against this VM so I can set the network and show the power function in action.
Execution of new Set_Network:
Checking fw-blue
networking info with the new Get-IP
function:
Now since the vyos-fw fw-blue
is on the correct network I tested the ansible ping, to do this I did the following:
fw-blue
Ansible Ping on - Created the directory
SYS480
and the filefw1-blue1-vars.txt
. - File contents: NOTE! The IP info was gathered via my Get-IP function, then the rest of the file was structured from Devins video.
[vyos]
10.0.17.102 hostname=fw-blue mac=00:50:56:bf:7a:45 wan_ip=10.0.17.200 lan_ip=10.0.5.2 network=10.0.5.0/24 nameserver=10.0.17.4 gateway=10.0.17.2
[vyos:vars]
ansible_python_interpreter=/usr/bin/python3
- Review of structure:
- Now open a bash terminal and execute the ping with our inventory file:
ansible vyos -m ping -i fw-blue1-vars.txt --user vyos --ask-pass
SUCCESSFUL!
- Now navigate to vSphere and create a new snapshot called:
before-ansible
onfw-blue
- From here I moved onto the vyos configurations
Milestone 6.4: vyos config's
For the VyOS configuration, I followed Devins's video and worked with Max B. Max and I broke down this last milestone into a few parts:
- Create directory structure like Devin:
- Run
show config
on yourfw-blue
VM. Copy the output and create aconfig.boot.j2
file with it. This is a jinja template, but to completely make it a jinja template I had to change the variables to match the contents offw-blue1-vars.txt
. So theconfig.boot.j2
ended up looking like this:
interfaces {
ethernet eth0 {
address {{ wan_ip }}/24
}
ethernet eth1 {
address {{ lan_ip }}/24
}
loopback lo {
}
}
nat {
source {
rule 10 {
outbound-interface eth0
source {
address {{ lan }}
}
translation {
address masquerade
}
}
}
}
protocols {
static {
route 0.0.0.0/0 {
next-hop {{ gateway }} {
}
}
}
}
service {
dns {
forwarding {
allow-from {{ lan }}/24
listen-address {{ lan_ip }}
system
}
}
ssh {
listen-address 0.0.0.0
}
}
system {
config-management {
commit-revisions 100
}
conntrack {
modules {
ftp
h323
nfs
pptp
sip
sqlnet
tftp
}
}
console {
device ttyS0 {
speed 115200
}
}
host-name {{ hostname }}
login {
user vyos {
authentication {
encrypted-password {{ password_hash }}
}
}
}
name-server {{ nameserver }}
ntp {
server time1.vyos.net {
}
server time2.vyos.net {
}
server time3.vyos.net {
}
}
syslog {
global {
facility all {
level info
}
facility protocols {
level debug
}
}
}
}
- Now create the
vyos-config.yml
file:
- name: vyos network config
hosts: vyos
vars_prompt:
- name: password
prompt: Enter your new vyos password
private: true
tasks:
- name: Set the password hash fact
set_fact:
password_hash: "{{ password | password_hash('sha512') }}"
- name: load vyos config from template
become: yes
template:
src: /home/jacob/SYS480/ansible/files/vyos/config.boot.j2
dest: /config/config.boot
mode: "0775"
owner: root
group: vyattacfg
- name: bounce and end
become: yes
shell: nohup bash -c "/usr/bin/sleep 10 && /usr/sbin/shutdown -r now" &
- Test the playbook with the following command:
ansible-playbook -i inventories/fw-blue1-vars.txt --user vyos --ask-pass vyos-config.yml
Expected output:
- Since the playbook changes the networking addresses on the VyOS VM the SSH connection was closed, the IP changed. So now when you return to the powershell session you can see this reflected when you run
Get-IP
function:
Yay!