How To Automate Proxmox VE Using Ansible

Dec 15, 2023 · 10 mins read
How To Automate Proxmox VE Using Ansible

In the video below, we show you how you can automate Proxmox VE using Ansible


Proxmox VE has a really useful graphical user interface that allows you to manage nodes and virtual machines

There’s no separate management software to install and most of the things that need to be done can be done through a web browser

But these days it’s all about automation and fortunately the developers have provided a REST like API that we can use

Now for me, the automation tool of choice is Ansible

So in this video we go over how you can automate Proxmox VE using Ansible

Useful links:
https://docs.ansible.com/ansible/latest/collections/community/general/proxmox_kvm_module.html https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pip_module.html

Install sshpass:
First we need to install sshpass on our computer which is running Ansible

sudo apt install sshpass -y

Although you’ll have to switch to root if your account doesn’t have sudo rights and run the command this way

apt install sshpass -y

The reason we need this software is because initially Ansible needs to login as root to our Proxmox VE nodes

Assuming you haven’t setup SSH keys for the root account, this requires password authentication

Now it’s better if we’re prompted for the root password rather than storing this in a file

And the reason sshpass is required is so that when Ansible is prompted by the server for the root password it can pass on the one we entered

Onboard Proxmox VE:
To begin with, all we can do is to login to Proxmox VE using the root account but it’s better if we use another account as well as SSH keys

First we’ll create an inventory file to define the nodes we’ll access

nano inventory

[pvenodes]
192.168.102.10
192.168.102.11
192.168.102.12

Now save and exit

Then we’ll setup some default settings for Ansible

nano ansible.cfg

[defaults]
interpreter_python=auto_silent
host_key_checking=False

This is to avoid warnings that can show up to do with the python interpreter and also to avoid the prompts you would run into when logging into a host for the first time using SSH

Next we’ll check that we can access the PVE servers using the root account

ansible pvenodes -i inventory -m ping --user=root -k

The ping module will test root access and for now we have to tell it we want to use the root account and to prompt us for the password

Assuming we can gain access as root, we’ll then create a playbook to setup our user account

nano pve_onboard.yml

- hosts: pvenodes
  tasks:

  - name: install sudo package
    apt:
      name: sudo
      update_cache: yes
      cache_valid_time: 3600
      state: latest

  - name: create Ansible user
    user:
      name: ansible
      shell: '/bin/bash'

  - name: add Ansible ssh key
    authorized_key:
      user: ansible
      key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMJ/0TAXIIpd7v97lbU7+AS+XL2dy1N3F/9XIhttH3mG ansible@homelab.lan"

  - name: add ansible to sudoers
    copy:
      src: sudoer_ansible
      dest: /etc/sudoers.d/ansible
      owner: root
      group: root
      mode: 0440

Now save and exit

In this playbook we’ll install the sudo package, then we’ll create a new user account, although I would suggest using something less obvious for the name

We’ll then upload the SSH public key for the account, so Ansible can use SSH key authentication to login

In which case, you’ll need to replace the one in this example with your own

And then we’ll give the account sudo rights by uploading a file to the /etc/sudoers.d folder

NOTE: It’s assumed that the Proxmox VE server has access to updates; Either a subscription for the Enterprise repository or is using Non-Subscription updates, otherwise the playbook will likely fail

Now we need to create a folder where files are stored

mkdir files

And then create the file we mentioned for granting sudo rights

nano files/sudoer_ansible

ansible ALL=(ALL) NOPASSWD: ALL

Now save and exit

In this example we’re granting the ansible user to have sudo rights for all commands and we’re not prompting for a password

It does carry a high risk in terms of security, because anyone in possession of the private key will have root privilege, but we’re doing this so we can schedule automatations at a later date without requiring interaction

TIP: To improve security, all computers should have a personal firewall installed to restrict which other computers can gain remote access

We’ll now run this playbook, but using the root account

ansible-playbook pve_onboard.yml -i inventory --user=root -k

Once this is done, we should able to test access to Proxmox VE using the Ansible account

ansible pvenodes -m ping -i inventory --user=ansible  --private-key ~/.ssh/ansible-key

Although I expect you will need to change the username and path for the private key being used for Ansible

PVE User Account and API Token
Now although we can login to the operating system using SSH, I want to manage PVE itself using the REST like API that Proxmox has provided

To do that we’ll create a user account and API token

So in the GUI, navigate to Datacentre | Permissions | Users

Click Add, fill in the details and then click Add

At the very least we need to provide the User name and this needs to match the user account we just created

This is because we’re using Linux for the user database, and hence why we aren’t asked for a password here

Next we need to assign permissions for this user account

Navigate to Datacentre | Permissions and from the Add drop-down menu select User Permission

For the Path select / i.e. the root folder

For the user, select the one for Ansible

For the Role select Administrator

Now click Add

Using API tokens for authentication is preferrable to using a username and password

This way if a token is lost we can revoke the token and create a new one rather than having to disable the user account for instance

In addition, we can also assign expiry dates to tokens which reduces the risk of someone being able to use a dormant account

To setup an API token, navigate to Datacentre | Permissions | API Tokens

Click Add and select the Ansible user from the drop down menu

Enter a Token ID e.g. ansible-token

To avoid complications de-select the Privilege Separation option, otherwise we’ll have to handle different privileges for the user account and token

It’s a good practice to give tokens an expiry date, maybe 1 month from the current date

But bear in mind you will need to set yourself a regular reminder to update this

Sites like GitHub for instance also request you to generate a new token each time

If you do decide to create a new token as well, Ansible will need to be updated

Both of these decisions though depend on your own security tolerance

In any case, click Add when ready

You’ll then be given details of the API token and also its secret

For example,

Token ID
ansible@pam!ansible-token
Secret
848d5601-a186-4532-9199-bb96e7f33bfa

NOTE: While the Token ID is a combination of the user name and token name we provided, you will not be able to recover the Secret once you close this window

Do store these in a safe location because they provide Administrator access to Proxmox VE

Now close the dialogue window

Install Proxmoxer:
The Ansible community has created some useful modules that allows Ansible to manage Proxmox VE but these rely on a Python wrapper called proxmoxer

Now there are various examples out there about how to install this, but I ran into a lot of issues installing this using pip on Debian 12 so I opted to install this as a Python package

First we’ll create the playbook

nano pve_install_proxmoxer.yml
- hosts: pvenodes
  become: true
  tasks:

  - name: update repository cache
    apt:
      update_cache: yes
      cache_valid_time: 3600

  - name: install proxmoxer
    apt:
      name:
      - python3-proxmoxer
      state: latest

Now save and exit

Granted this won’t be the latest version, but this is the simplest solution I’ve found without having to deal with virtual environemts

Now we just need run this playbook to get it installed

ansible-playbook pve_install_proxmoxer.yml -i inventory --user=ansible --private-key ~/.ssh/ansible-key

Ansible should now be able to manage Proxmox VE through the API

Testing:
As a basic test we’ll create a playbook that creates a virtual machine on a Proxmox node but with minimal options

nano pve_create_vm.yml
- hosts: 192.168.102.10
  become: false
  gather_facts: false
  tasks:

  - name: Create new vm with minimal options
    vars:
      ansible_python_interpreter: /usr/bin/python3
    proxmox_kvm:
      api_user: ansible@pam
      api_token_id: ansible-token
      api_token_secret: 7a4c9e2f-fede-417b-b0e8-d3cbaed5c5ad
      api_host: 192.168.102.10
      node: pvedemo1
      name: vmtest

Now save and exit

Although you’ll need to replace several of these entries with your own information

NOTE: It’s not a good practice to store sensitive details like these in a playbook, but at this stage we’re only testing to see if Ansible can create a virtual machine

Because we’re using the REST like API, we don’t need to become root and I’ve disabled gathering facts to speed up the process

To make sure Ansible uses Python 3, I’ve set a variable which points to its location

After that we use the proxmox_kvm module to create a very basic VM

So the login details are provided, along with the host to login to

And then we just define which node to create the VM on and what to call it

Finally we’ll run this playbook

ansible-playbook pve_create_vm.yml -i inventory --user=ansible --private-key ~/.ssh/ansible-key

You should then see a new VM on that node which was assigned the next available VMID

Summary:
Now you might be thinking, what’s the point?

I could have created a virtual machine much quicker than this through the web browser

We’ll that is true but think about the bigger picture

Once you have the intial installation of Proxmox VE done, and there is the potential to automate that part, Ansible can then build the cluster

It can then create the templates and use those to create all of your virtual machines

Assuming Ansible is maintaining the configuration of those virtual machines going forward, you don’t need to backup those virtual machines, only your data and your Ansible files

Now that is going to save you a lot of disk storage space both locally and offsite

But it also saves a lot of time, because if you’ve ever dealt with a disaster recovery you’ll know it can take a while just to get you hands on the backup files, let alone restore the computers

And Ansible could re-build the entire cluster much quicker than it would take to restore things manually

Sharing is caring!