Automate Proxmox VM Deployments with GitLab CI and Ansible: A Step-by-Step Guide

December 6, 2024 · Maximilian Reinheimer
Abstract digital diagram with connected boxes and glowing lines, representing an automation workflow.

Welcome to another Automation Adventure! This time, we’ll explore automating the deployment of a virtual machine (VM) on Proxmox using GitLab CI and Ansible. If you’re already using Proxmox for virtualization, GitLab CI for continuous integration, and Ansible for configuration management, this guide will help you integrate these tools into a cohesive workflow.

By the end of this tutorial, you’ll have a GitLab CI pipeline that provisions a VM on Proxmox, configures its operating system, and sets it up for additional automation. Let’s dive in!

Organizing a GitLab CI Pipeline for Proxmox Deployments

The first step is to organize the pipeline into clear, sequential stages. This makes the workflow easier to manage and ensures tasks execute in the correct order. We’ll use two main stages:

  1. Create: Handles the provisioning of the VM on Proxmox.
  2. Setup: Configures the VM’s operating system once it is provisioned.

This structure keeps the process modular, ensuring that each stage completes successfully before the next one begins.


  stages:
    - create
    - setup

Defining Key Variables for Proxmox Automation in GitLab CI

Using variables in your pipeline configuration makes it more flexible and easier to maintain. For instance, defining variables for the inventory repository URL and VM name allows you to make updates without touching the pipeline’s core logic.

The INVENTORY_URL variable points to the Git repository containing the inventory files that Ansible will use, while PROXMOX_VM_NAME specifies the name of the VM you’re provisioning. This simple approach ensures that configuration changes require minimal effort.


  variables:
    INVENTORY_URL: https://${CI_SERVER_FQDN}/path/to/your/inventory
    PROXMOX_VM_NAME: ansible-managed-vm

Creating a Reusable Playbook Template for Proxmox and Ansible

To avoid redundancy, we’ll create a reusable job template in GitLab CI. This template will handle common tasks, such as installing dependencies, configuring SSH access, and managing inventory files. By standardizing these steps, you ensure consistency across all pipeline stages.

Installing Dependencies

Dependencies like Python, Ansible, and related libraries must be installed in the pipeline environment. We also include utilities like Git and SSH for inventory management and secure communication. These installations form the foundation of the automation process, allowing the playbooks to interact with Proxmox and target systems.


  .playbook_template:
    image: python:3-slim
    variables:
      ANSIBLE_FORCE_COLOR: 'true'
      ANSIBLE_INVENTORY: proxmox-inventory/hosts.yml,proxmox-inventory/example.proxmox.yml
    before_script:
      - pip install ansible requests netaddr proxmoxer jmespath
      - apt-get update && apt-get install -y openssh-client git

Configuring Secure SSH Access

SSH is vital for Ansible to connect to and manage the VM. Since the VM is created dynamically, we need to temporarily bypass strict host key checking. This approach, while suitable for trusted or test environments, should be used cautiously in production.

  1. First, create the .ssh directory and set its permissions to 0700 (accessible only by the owner).
  2. Next, disable strict host key checking. This allows Ansible to connect without verifying the VM’s host key, which isn’t predictable during creation.
  3. Start the SSH agent to manage keys securely, ensuring the private key is read-only before adding it to the agent.

The private key ($SSH_PRIVATE_KEY) should be stored as a file-type variable in GitLab CI with proper formatting, including a trailing newline.


  - install -d -m 0700 ~/.ssh
  - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
  - eval $(ssh-agent)
  - chmod 400 "$SSH_PRIVATE_KEY"
  - ssh-add "$SSH_PRIVATE_KEY"

Installing Ansible Requirements

Ansible roles and collections required by the playbooks are specified in a requirements.yml file. Installing these dependencies ensures your playbooks have all the necessary functionality to execute correctly.

	
  - ansible-galaxy install -r requirements.yml

Cloning Inventory Files

Ansible inventory files define target hosts for playbooks. By cloning the latest version from a Git repository, you ensure accuracy and up-to-date configurations. The --depth 1 flag improves performance by limiting the clone to only the latest commit, avoiding the full repository history.

Once the inventory is cloned, the ANSIBLE_INVENTORY variable (defined earlier) ensures that Ansible uses the correct inventory files during playbook execution. This variable allows Ansible to reference both static and dynamic inventory files, such as hosts.yml and example.proxmox.yml, without requiring manual adjustments.


  - git clone --depth 1 "${INVENTORY_URL}" proxmox-inventory

Automating VM Creation on Proxmox with GitLab CI

The first major task in the pipeline is provisioning a VM using the proxmox_vm.yml playbook. This playbook interacts with the Proxmox API to create the VM based on predefined parameters. The -e parameter in the playbook command passes extra variables — in this case, specifying the VM name dynamically.


  create_vm:
    extends: .playbook_template
    stage: create
    script:
      - ansible-playbook proxmox_vm.yml -e "cloud_vm_name=${PROXMOX_VM_NAME}"

Configuring VMs Automatically with Ansible

Once the VM is provisioned, the next stage involves configuring its operating system. This includes updating packages, setting up networking, and preparing the system for further tasks. The -l parameter limits the playbook’s scope to the newly created VM, identified by its name.


  setup_vm:
    extends: .playbook_template
    stage: setup
    script:
      - ansible-playbook vm_configuration.yml -l ${PROXMOX_VM_NAME}

Wrapping Up Your GitLab CI Workflow

You’ve now created a GitLab CI pipeline that automates the provisioning and configuration of Proxmox VMs. This setup combines Proxmox, Ansible, and GitLab CI to create an efficient and repeatable process that simplifies infrastructure management.

This pipeline can be extended in many ways, such as:

  • Deploying containerized application stacks.
  • Adding monitoring with tools like Prometheus or Grafana.
  • Strengthening security with additional hardening measures.

With this workflow in place, you can focus on scaling and improving your systems without being bogged down by repetitive manual tasks.