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!