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

## Introduction
This is 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.

This achieves the ability to quickly set up a router lab for the
purposes of experimenting with iptables, or whatever else you
want to use for routing or firewalls.

This is also, for myself, an opportunity to learn ansible.

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

## Networking
I begin by setting up a new network in libvirt, which will serve
as an _out-of-band_ network for connecting to the lab virtual machines.
This is covered in a
[previous blog post](/posts/add-kvm-network-with-virsh/){target="_blank"}.

## Overview
The lab consists of seven virtual machines.

I begin by creating a _base_ Debian 11 virtual machine called `dnet` by connecting to
my physical server using `virt-manager`.

After creating a _base_ virtual machine, the next step is to create
a clone from which to work. I call this machine `dcon`.

The client clones consist of 5 virtual machines named
`dnetone` through `dnetfive`. Once set up, all five virtual machines
are reachable through the _out-of-band_ network.

But there are also two bridge networks connecting the client clones
to each other. The first and second clones are connected to each other on
the **upper** bridge network, with the first clone acting as a router for the
second. The second, third, fourth, and fifth clones are connected to each
other on the **lower** bridge network, with the second clone acting
as a router for the third, fourth, and fifth clones. Traffic from the
second clone will go through the first clone to reach the internet, and
traffic from the third, fourth, and fifth clones will go through
the second clone and then through the first clone to reach the internet.

DHCP is handled by dnsmasq on the first clone and the second clone.

## Resources
For ansible I used the
[ansible documentation](https://docs.ansible.com/ansible/latest/index.html){target="_blank"}.

This
[blog post](https://www.brianlinkletter.com/2019/02/build-a-network-emulator-using-libvirt/){target="_blank"}
by Brian Linkletter is also really helpful.

## Control Node Setup
* Create a control node by cloning the _base_ virtual machine.
```shell
virt-clone --original dnet --name dcon --auto-clone
```
* Configure ansible host file
```cfg
# ~/.ansible.cfg
[defaults]
inventory = ~/router-lab/ansible/hosts.yml
```
* Setup bashrc
```bash
# ~/.bashrc
export LIBVIRT_DEFAULT_URI="qemu+ssh://<user>@<server>/system"

alias ansible-pb=anspb
anspb() {
  ANS_DIR=~/router-lab/ansible/playbooks;
  echo Changing to "${ANS_DIR}" and executing: ansible-playbook "${@}"
  (cd $ANS_DIR || exit ; ansible-playbook "${@}")
}
```
* configure Vim or similar for editing bash and python
* install apps
```bash
apt install ansible ansible-lint libvirt-clients
apt install --no-install-recommends virtinst
```
The control node needs root ssh access to the _base_ virtual machine so
that it will have root ssh access to the clones.

## To Be Continued
In the next blog post,
[Ansible KVM Router Lab Part 2](/posts/ansible-kvm-router-lab-part-2/){target="_blank"},
I begin breaking down the bash scripts which build out the lab, beginning with
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash){target="_blank"}.
