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

## Introduction
This is Part 2 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 this post I begin breaking down the bash scripts which build the router
lab, beginning with
[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 [Ansible KVM Router Lab Part 4](/posts/ansible-kvm-router-lab-part-4/){target="_blank"},
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.

## `build_vms.bash`
### `check_uid "0"`
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash)
begins by making sure that it is run as the _root_ user. This is because root is required to
ssh into the clones to change their hostnames, machine-ids, and host-ssh-keys. You can call
with `sudo bash build_vms.bash`.

For this same reason, `~/.ssh/known_hosts` is useless so it is deleted (and then rebuilt).

### `function build_vms()`
Next, 
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash){target="_blank"}
calls `build_vms`, which loops over the array of MACHINES, which is an
array that holds that names of the lab clients, passing each name in turn
to `create_vm`.

`create_vm` creates the virtual machine if it does not already exist, using `virt-clone`, and
then calls `start_vm` to start it.

`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.

### `function set_hostnames()`
Next, 
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash){target="_blank"}
calls `set_hostnames`, which simultaneously calls `set_hostname` on the entire MACHINES array. `set_hostname`
in turn waits for the virtual machine to be fully booted, then updates the files `/etc/hostname` and
`/etc/hosts`, and then reboots the virtual machine to apply the new hostname.

### `function confirm_hostnames()`
`confirm_hostnames` simultaneously calls `confirm_hostname` against the entire MACHINES array.
`confirm_hostname` waits for the virtual machine to be fully booted, then confirms the correct
_hostname_ in `/etc/hostname`.

### `function confirm_hostnames_in_hosts()`
`confirm_hostnames_in_hosts` works almost exactly the same as `confirm_hostnames`, but this time
the file `/etc/hosts` on the virtual machine is grepped for the proper _hostname_, and corrected
if necessary.

### `function reset_hosts_ssh_keys()`
`reset_hosts_ssh_keys` simultaneously calls `reset_host_ssh_keys` against the MACHINES array,
which in turn compares the host_ssh_key of the virtual machine against the _bas3_ virtual
machine, and if necessary deletes `/etc/ssh/ssh_host_*`, generates new host_ssh_keys, restarts
`sshd` on the virtual machine, removes `~/.ssh/known_hosts`, and then reruns itself in
order to confirm the new host_ssh_keys.

### `function reset_machine_ids()`
`reset_machine_ids` simultaneously calls `reset_machine_id` against the entire MACHINES array,
which in turn checks the _machine-id_ of the virtual machine to make sure that it is different
than the _machine-id_ of the _base_ virtual machine, and if necessary deletes
`/etc/machine-id` and `/var/lib/dbus/machine-id` and recreates them.

## To Be Continued
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.
