Overview
I am sharing these playbooks because they have helped me manage virtual machines in my home lab and cloud instances. Users should have a basic knowledge of Ansible, some experience with Linux, and some familiarity with virtual machines. You can follow along with the repository at Git Hub here.
Environment
These playbooks were written with the following environment in place. You will need to adjust files and playbooks to meet your environment's needs.
- Local network of 10.20.26.x
- Working Bind/DNS service managing the home.internal domain
- Working email service for the above domain
- Working HashiCorp Vault instance to manage secrets
- Debian 12 workstation to run the Ansible playbooks
Ansible Setup
To install Ansible and its dependencies on Debian 12 run the following command:
sudo apt install ansible
Next, clone this repository and change to the cloned directory. The next command will create an Ansible Vault file:
ansible-vault create secrets.yaml
This will ask you for an Ansible Vault password and then open secrets.yaml in a text editor. If you plan to use HashiCorp Vault to manage passwords, you can add your token to secrets.yaml here.
Otherwise you can add your sudo passwords to secrets.yaml for Ansible Vault to manage.
If using HashiCorp Vault, you will also need to install the hvac Python package via pip:
sudo apt install python3-pip
python3 -m venv myenv
source myenv/bin/activate
pip install hvac
If you are using vault.yaml, it will connect to your HashiCorp Vault instance. Edit the URL to match your Vault instance's URL. vault.yaml is treated as a vars file; it pulls keys from a HashiCorp Vault path. For this example the path is kv/data/ansible. It uses the Ansible secret named ansible_token to store the token for HashiCorp Vault.
The next file to edit is the inventory.yaml file. This example shows how to pull secrets from both HashiCorp Vault and Ansible Vault. For example, the ansible_become_password for dev.devsrv1 is stored in Ansible Vault. The ansible_become_password for network.debiansrv1 is stored in HashiCorp Vault and returned in the key list called vault_data, under the key debiansrv1_sudo.
The last step is to generate SSH key pairs if you don't already have them. This public key will be used to communicate with the servers that Ansible will manage.
ssh-keygen
Minimal Debian VM Setup
On to creating VM templates. The first template will be a fresh install of Debian 12. I changed the VM networking to use bridged mode. This places the VM on the local network using DHCP.
For a minimal install, deselect all options in Software Selection except SSH Server, since this is needed to manage the machine via Ansible.
After the instance is installed, stop it and clone the instance for further work. I call this template deb12base.
Preparing cloned template for Ansible
On a clean Debian 12 install, you cannot SSH in as root. Therefore, sudo and python3 need to be installed.
apt install sudo python3
/usr/sbin/usermod -a -G sudo <sudouser>
Next, edit /etc/network/interfaces to give the template a static IP on the network. Add the host to DNS so you can use the hostname in the inventory file. There is a playbook for that: bind-update.yaml.
If you want to change the template hostname, use the following command:
sudo hostnamectl set-hostname <hostname>.home.internal
To allow Ansible playbooks to connect, copy your SSH public key to the new VM:
ssh-copy-id <sudouser>@<hostname>
After these changes, stop the instance and clone it for further work. I call this template deb12work.
Ansible Playbook usage
Now, on to using the Ansible playbooks.
The first Ansible playbook to run sets the system clock to use systemd-timesyncd:
ansible-playbook --ask-vault-pass clock-setup.yaml
The second playbook sets up an email client so services or cron jobs can notify a network user via email. This playbook copies a couple of files from the assets folder to the server. These files should be reviewed and edited before running the playbook.
ansible-playbook --ask-vault-pass mail-setup.yaml
Test the email setup by sending an email from the guest machine.
The next playbook installs rkhunter and ClamAV. This script installs cron jobs to run these tools daily. The cron jobs also run an apt upgrade check and email the results of what packages need to be installed without actually installing them. Be sure to edit these so they notify the correct email address. The playbook will also copy a stricter /etc/ssh/sshd_config to prevent root logins and enforce safer TLS settings. rkhunter will complain if these are not set.
ansible-playbook --ask-vault-pass security-tools-install.yaml
This playbook will restart the server or guest instance.
Next playbook will use nftables as a firewall. It isn't very strict as it allows all outbound traffic. It does block inbound traffic except for SSH. Adjust it according to your needs.
ansible-playbook --ask-vault-pass nftables-install.yaml
Next playbook will install and configure fail2ban. This utility slows down attackers by putting them in a jail for a period of time. Adjust the configurations to your preference.
ansible-playbook --ask-vault-pass fail2ban-install.yaml
Apt Upgrades
This playbook will upgrade apt packages on multiple servers. Configure as needed.
ansible-playbook --ask-vault-pass apt-upgrade.yaml
Install Nginx Server
This playbook will install nginx and compile it with modsecurity. It will add modsecurity rules from OWASP. Also, it will add jails to fail2ban for modsecurity and for various 400 errors over periods of time to prevent system scanning. The playbook has a variable for the version of nginx you are using. Be sure to change this to the correct version you are targeting.
ansible-playbook --ask-vault-pass nginx-install.yaml
Shutdown and Restart
These playbooks can simply restart or shutdown a group of instances.
ansible-playbook --ask-vault-pass restart.yaml
ansible-playbook --ask-vault-pass shutdown.yaml
Change Hostname
When cloning new instances from templates, you might want to change the hostname for the new clone. This playbook will copy /etc/network/interfaces so you can set the static IP as well. Make sure to edit that before running. Here is the playbook call for that. This playbook shows how to pass environment variables to ansible.
ansible-playbook --ask-vault-pass change-hostname.yaml -e 'hostname=devsrv1'
Finalizing templates by regenerating host keys
Up until now, I have been cloning templates and reusing those templates. This is fine except for the fact that SSH host keys have been reused as well. For a final step I want to regenerate the SSH host keys and finalize a VM template to be re-used. This will cause Man in the Middle warnings the next time you try to connect, so you will have to follow the instructions to clear those up. I found this technique at this address, https://www.youtube.com/watch?v=oAULun3KNaI.
ansible-playbook --ask-vault-pass prep-template.yaml



Top comments (0)