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