Ansible

| Apr 29, 2024 min read

Introduction

Ansible is a powerfull tool used to automate repetitive work. I use it primairily to automate the installation and partial configuration of new servers. Deploying new servers is something I do quite often, as I’d rather have a clean VM that can easily be trown away, rather than having to clean up my messes afterwards in case things dont turn out as expected.

Infrastructure as Code

As of writing I am working on rebuilding my entire deployment workflow. previously all ansible tasks where managed through Ansible AWX, and for every VM a new task had to be created, and afterwards an entry in the inventory had to be manualy created. Any plays that would configure the new VM had also to be manually selected. All together it was a functional, but not that automated automation project.

With the third revision of my automated VM deploy script I have turned towards Infrastructure as code. My entire homelab shall be managed through the ansible inventory. Here the VM spec, and desired software components will be specified.

All work will be shared on the following public GitHub repository: Infrastructure as Code - GitHub

The Inventory

The end goal of this project is to have my entire infrastructure managed by code. Here is a small snippit of the inventory:

####################
kubernetes:        #
  hosts:           #
####################

    kube-master-00:
      vlan: 103
      id: 10
      kubernetes: v1.29

    kube-master-01:
      vlan: 103
      id: 11
      kubernetes: v1.29

    kube-master-02:
      vlan: 103
      id: 12
      kubernetes: v1.29

    kube-worker-00:
      vlan: 103
      id: 20
      kubernetes: v1.29

    kube-worker-01:
      vlan: 103
      id: 21
      kubernetes: v1.29

    kube-worker-02:
      vlan: 103
      id: 22
      kubernetes: v1.29

All hosts specified in this snippet shall be installed with the Kubernetes version 1.29, and the latest minor release. In case you wish to delete a VM, all you need to do is remove it from the inventory. Ansible will do the rest, however this comes with the side effect that any VM that doesnt exist in the inventory gets deleted. Even if you didnt intend to. For that reason there are a couple VMs that are hardcoded to never be deleted via the corresponding var file.

All VMs are deployed with the default specs of 4 cores, 4GB memory and 20 GB of storage. If a VM requires more resources, or may not be powered on but still needs to be preserved, all can be specified like this:

  kube-worker:
      vlan: 103
      id: 20
      memory: 32768
      cpu: 8
      disk: 60
      state: stopped



Automating job execution

Previously all jobs had to be manually started whenever a new VM needed to be deployed. To fix this issue I turned towards GitHub actions, or a CI/CD pipeline, whichever you preffer. The pipeline in the end is quite simple. A check is made if any changes have been made in the inventory file, if any changes where detected an API call is made towards ansible AWX and the workflow is executed.

The end result is that all that needs to be done is adding or removing a VM to/from the inventory and pushing it to GitHub. The rest all happens automatically.



AWX Workflow

To keep maintenance of the playbook as easy as possible different portions of the deployment are segmented in different Ansible jobs devided via Ansible tags. As of writing we have the following jobs:

  • Project Sync
  • Inventory Sync
  • Deploy phase
  • Prep phase

After these phases more plays are added to the workflow to install VM specific software like monitoring tools or Kubernetes.

During the deploy phase the VM itself is created in proxmox. During the prep phase basic configuration changes are made, like: locking down SSH, configuring cloud-init, installing default applications like vim, git and the qemu-guest-agent.



Goals

The end goal for this project is to automate close to everything. From the installation to the software configuration. For example, I wish to automate cluster creation / expansion for kubernetes. Besides kubernetes I also want to automate Nginx vhost and HAproxy configuration.