Using Ansible with Proxmox: PART 2


In Part 1B, we finished setting up our Ansible controller and ensured it could securely connect to our Proxmox environment. With that in place, we’re now ready to organise our automation workspace so everything has its place and purpose.
In this part, we’ll be creating an organised and thought-out Ansible folder structure, defining our inventory, installing the necessary collections, and securing our credentials using Ansible Vault. This structure will serve as the backbone for all the playbooks we’ll write in the coming posts.
Step 1: Create Your Ansible Folder Structure
Now, Let’s create this structure inside ~/Automation/Ansible/
:
mkdir -p automation/ansible/{playbooks,inventories,group_vars/all,roles/windows_vm/tasks,roles/windows_vm/other_scripts,roles/windows_vm/vars}
touch automation/ansible/{ansible.cfg,requirements.yml,inventories/hosts.ini,playbooks/create-windows2019-template.yml,roles/windows_vm/tasks/main.yml,roles/windows_vm/vars/main.yml}
This gives you:
automation/
└── ansible/
├── ansible.cfg
├── inventories
│ └── hosts.ini
├── requirements.yml
├── group_vars/
│ └── all
│ └── vault.yml (created in step 5)
├── playbooks/
│ └── create-windows2019-template.yml
└── roles/
└── windows_vm/
├── tasks/
│ └── main.yml
├── vars/
│ └── main.yml
└── other_scripts/
File Explanations
ansible.cfg – Configures Ansible defaults (e.g., inventory location, Python interpreter).
inventories/hosts.ini – Lists Proxmox server(s) to interact with.
requirements.yml - for installing ansible collections
group_vars/all/vault.yml – Stores global vars like
proxmox_api_user
,proxmox_api_token_id
.playbooks/create-windows2019-template.yml – The main playbook you will run.
roles/windows_vm/tasks/main.yml – All provisioning logic in one file. Also a directory you'll use for other specific roles and tasks, when running a multi-file playbook.
other_scripts/ – Optional for config files or scripts.
Step 2: Create Hosts.ini and Test host connection:
Create Your Inventory File
Host.ini file: might include direction to private ssh key, AND localhost ansible_connection)
Ansible needs to know which servers to manage. Create a file like this if not already done:
nano ~/Automation/Ansible/inventories/hosts.ini
automation/
└── ansible/
├── ansible.cfg
├── inventories
├ └── hosts.ini
Paste:
[proxmox]
192.168.1.125 ansible_user=Ansible
Save (ctrl + o), press enter, and exit (ctrl + x).
NOTE: Remember how you spell the host name, ansible can be case sensitive so using the wrong case can cause errors.
Step 3: Test Ansible Connection
Run a quick ping test to ensure Ansible can talk to your Proxmox server:
ansible -i ~/Automation/Ansible/inventories/hosts.ini all -m ping
You should get:
192.168.1.125 | SUCCESS => {
"changed": false,
"ping": "pong"
}
If not, SSH key or permissions are probably misconfigured.
Step 4: Use Ansible to Create a VM on Proxmox
We’ll use a special Proxmox community-provided modules that lets Ansible create or clone VMs on Proxmox.
Install Proxmox Collection
Install the Ansible collection to interact with the Proxmox API:
ansible-galaxy collection install community.general
ansible-galaxy collection install community.libvirt
(You'll mostly use community.general.proxmox_kvm
)
if either of these do no work then you can do via a requirments.yml file:
Alternative - Using a requirements.yml
Alternatively, you can create requirements.yml file for installing ansible collections (community.libvert 1.0.2).
Save in ansible directory (~/Automation/Ansible)
# requirements.yml
collections:
- name: community.libvirt
version: "1.0.2" # or any available version
Then run:
ansible-galaxy collection install -r requirements.yml
Step 5: Create Ansible Vault for Proxmox Credentials
Run the following (while in the Ansible file):
ansible-vault create group_vars/all/vault.yml
Add this inside:
proxmox_api_user: "your_proxmox_username"
proxmox_api_token_id: "your_proxmox_token_id"
proxmox_api_token_secret: "your_proxmox_token_secret"
⚠️ Don’t use the Proxmox web password in plaintext elsewhere — only reference it from Vault!
Assuming you're in ~/Automation/Ansible/
, you should now have:
automation/
└── ansible/
├── ansible.cfg
├── inventory.yml
├── requirements.yml
├── group_vars/
│ └── all/
│ └── vault.yml
Encrypt it:
ansible-vault encrypt vault.yml
Honestly, im not a fan of Vim and MUCH prefer Nano, so to get the vault.yml open and edit securely in Nano we can do the below: NOTE: Doing the below without the export command (so just the ansible command) will open vault.yml in Vim… Not sure why you’d want that though:
export EDITOR=nano
ansible-vault edit vault.yml
If you ever want to decrypt it temporarily:
ansible-vault decrypt vault.yml
If you just want to view contents (read-only), use:
ansible-vault view vault.yml
Step 6: Setting up Vault password file (vault_pass.txt):
Usually, vault_pass.txt
is stored on the machine locally where you run Ansible (your control node), not inside your Git repo or project directory — because it’s essentially the “key” to decrypt all your encrypted Ansible Vault secrets.
A common practice is:
Example:
~/.vault_pass.txt
How to set it up
# Create the vault password file in your home directory
echo "MySuperSecretVaultPassword" > ~/.vault_pass.txt
# Restrict file permissions so only you can read it
chmod 600 ~/.vault_pass.txt
Secure the .vault_pass.txt
file:
chmod 600 ~/.vault_pass.txt
600
means:Only the file owner can read and write to the file.
All others (group + others) get no access at all.
This is important because your
.vault_pass.txt
file contains the plain text Vault password. If it's left world-readable (644
), any local user could decrypt your secrets.If your machine is multi-user (e.g., a shared VM or server), unprotected secrets can easily be leaked or misused. Setting
600
ensures only you can read the file.
Why store it there
Keeps it outside of version control so it never gets pushed to GitHub.
Prevents accidental exposure since only your user can read it (
chmod 600
).You can point Ansible to it in ansible.cfg so you don’t have to pass
-vault-password-file
every time.
ansible.cfg example
[defaults]
inventory = inventory.yml
vault_password_file = ~/.vault_pass.txt
Step 7 – Verify Your Setup:
You can now run playbooks without being prompted for a vault password:
ansible-playbook playbooks/create_windows_vm.yml
If everything’s set up correctly, Ansible will:
Load your inventory
Will automatically decrypt your secrets.
Use the Proxmox API module to create or manage VMs
We’ve now prepared our Ansible controller and ensured our SSH keys are ready for secure, passwordless communication with our target machines. In the next posts, we’ll move on to the fun part — actually writing and running our first playbook.
We’ll cover:
Single-file playbooks – quick and simple automation in one YAML file.
Multi-file playbooks – a modular approach with roles, variables, and cleaner structure.
By the end, you’ll not only know how to type up your playbook but also run it successfully from start to finish.
If you feel certain steps or lines of code could have been done more efficiently, please let me know. At the end of the day, positive, constructive criticism, is one of the best ways to grow and improve not only as an IT Professional but life in general.
Thanks!
Subscribe to my newsletter
Read articles from Mike Kobbie Tieku TABI directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
