---
title: "Ansible KVM Router Lab Part 4"
date: 2021-10-17
draft: false
tags: ["linux", "kvm", "libvirt", "virsh", "ansible", "bash"]
authors: ["trent"]
post: 29
---
date: 2021-10-17

## Introduction
This is Part 4 of a multi-part series of blog posts for building a
[router lab](https://github.com/TrentSPalmer/router-lab){target="_blank"}
automatically using a series of bash scripts and ansible.

[Ansible KVM Router Lab Part 1](/posts/ansible-kvm-router-lab-part-1/){target="_blank"}
is an overview.

In [Ansible KVM Router Lab Part 2](/posts/ansible-kvm-router-lab-part-2/){target="_blank"},
I break down the script 
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash){target="_blank"}.

In [Ansible KVM Router Lab Part 3](/posts/ansible-kvm-router-lab-part-3/){target="_blank"},
I explain
[define_bridge_networks.bash](https://github.com/TrentSPalmer/router-lab/blob/master/define_bridge_networks.bash){target="_blank"}
and [shutdown_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/shutdown_vms.bash){target="_blank"}
scripts which are used to construct the lab.

In this post I explain
[connect_vms_to_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/connect_vms_to_bridges.bash){target="_blank"},
[start_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/start_vms.bash){target="_blank"},
and
[rebuild_known_hosts.bash](https://github.com/TrentSPalmer/router-lab/blob/master/rebuild_known_hosts.bash){target="_blank"}
scripts which are used to construct the lab.

In [Ansible KVM Router Lab Part 5](/posts/ansible-kvm-router-lab-part-5/){target="_blank"},
I explain the ansible playbook tasks used to finish building the lab.

In [Ansible KVM Router Lab Part 6](/posts/ansible-kvm-router-lab-part-6/){target="_blank"},
I explain
[disconnect_vms_from_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/disconnect_vms_from_bridges.bash){target="_blank"},
[undefine_and_remove_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/undefine_and_remove_vms.bash){target="_blank"},
and [remove_bridge_networks](https://github.com/TrentSPalmer/router-lab/blob/master/remove_bridge_networks.bash){target="_blank"}
which are used to destroy the lab.

## `connect_vms_to_bridges.bash`
Aside from the _out-of-band_ network which can be used to contact the lab clients
directly, the lab clients are connected to each other using two bridge networks.

As explained in 
[Ansible KVM Router Lab Part 1](/posts/ansible-kvm-router-lab-part-1/){target="_blank"},
lab clients one and two are connected to the upper bridge, and lab clients two, three, four,
and five are connected to the lower bridge with the first client acting as a router
for the second client, and the second client acting as a client for the third, fourth, and
fifth clients.

### `check_uid "${USER_UID}"`
[connect_vms_to_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/connect_vms_to_bridges.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash connect_vms_to_bridges.bash`.

### `function connect_upper_bridge()`
`connect_upper_bridge` calls `connect_vm_to_bridge` against the first lab client and the upper bridge,
and again against the second lab client and the upper bridge.

### `function connect_lower_bridge()`
`connect_lower_bridge` calls `connect_vm_to_bridge` against the second lab client and the lower bridge,
against the third lab client and the lower bridge, against the fourth lab client and the lower bridge,
and against the fifth lab client and the lower bridge.

### `function connect_vm_to_bridge()`
`connect_vm_to_bridge` parses the output of `virsh dominfo` against the intended lab client to verify that it
is shutdown. Then, if the intended lab client is shutdown, `connect_vm_to_bridge` parses the output of
`virsh domiflist` to find out if the intended new interface is yet defined, and if not invokes
`virsh attach-interface <vm> --type network --source <bridge network>`. Finally, `connect_vm_to_bridge`
recursively calls itself for verification.

## `start_vms.bash`
After defining the new network interfaces for all the lab clients, you can boot them.

### `check_uid "${USER_UID}"`
[start_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/start_vms.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash start_vms.bash`.

### `function start_vms()`
`start_vms` calls `start_vm` against the entire MACHINES array, simultaneously.
`start_vm` is exported from
[env.bash](https://github.com/TrentSPalmer/router-lab/blob/master/env.bash.example){target="_blank"},
and per parsing the output of `virsh list --inactive`, starts the virtual machine if it is not running.

## `rebuild_known_hosts.bash`
You will need to have a valid list of known_hosts in order for ansible to connect to the lab
clients.

The script deletes `~/.ssh/known_hosts` and then initiates an ssh connection to all the router lab clients
in order to repopulate `~/.ssh/known_hosts`.

### `check_uid "${USER_UID}"`
[rebuild_known_hosts.bash](https://github.com/TrentSPalmer/router-lab/blob/master/rebuild_known_hosts.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash rebuild_known_hosts`.

## To Be Continued
In the next blog post,
[Ansible KVM Router Lab Part 5](/posts/ansible-kvm-router-lab-part-5/){target="_blank"},
I explain the ansible playbook tasks used to finish building the lab.
