Ansible Playbook Work: Merging VM Creation With MariaDB Install
This is iteration 3 of automating VM provisioning and software setup in Proxmox. There are hardcoded IPs, hardcoded VM IDs, and manual delays—but each step refines the process. Eventually, we’ll abstract these variables, but right now, the goal is to get a repeatable, working deployment.
What This Playbook Does
This Ansible playbook handles two key tasks:
- Deploying a new VM in Proxmox with a predefined template, setting its configuration, and allowing time for initialization.
- Configuring MariaDB on the new VM, ensuring it's installed, running, and accessible.
This automation saves significant manual effort and ensures consistency across deployments.
Cloning and Configuring the Proxmox VM
The first section of the playbook interacts directly with the Proxmox API to clone a VM from a template, configure networking, and start it.
Key Steps:
- Clone a new VM from template ID 3000.
- Wait for Proxmox to report the VM as fully created.
- Attach Cloud-Init to handle SSH key injection.
- Set a static IP address and ensure proper boot configuration.
- Start the VM and pause for 90 seconds to allow the system to finish booting.
- name: Clone and Configure a New Proxmox VM
hosts: proxmox
gather_facts: no
tasks:
- name: Clone the VM from Template (3000)
uri:
url: "https://{{ inventory_hostname }}:8006/api2/json/nodes/mcp/qemu/3000/clone"
method: POST
headers:
Authorization: "PVEAPIToken=root@pam!codexmcp=<REDACTED>"
body_format: form-urlencoded
body:
newid: "2022"
name: "mariadb-core-1"
full: "1"
target: "mcp"
storage: "mcp-zfs1"
validate_certs: no
register: clone_response
- name: Wait for VM to be fully created (Check Lock Status)
uri:
url: "https://{{ inventory_hostname }}:8006/api2/json/nodes/mcp/qemu/2022/status/current"
method: GET
headers:
Authorization: "PVEAPIToken=root@pam!codexmcp=<REDACTED>"
validate_certs: no
register: vm_status
until: "'lock' not in vm_status.json.data"
retries: 20
delay: 5
- name: Set IP Address and Boot Configuration
uri:
url: "https://{{ inventory_hostname }}:8006/api2/json/nodes/mcp/qemu/2022/config"
method: POST
headers:
Authorization: "PVEAPIToken=root@pam!codexmcp=<REDACTED>"
body_format: form-urlencoded
body:
ipconfig0: "ip=10.0.1.65/24,gw=10.0.1.1"
boot: "c"
bootdisk: "scsi0"
machine: "q35"
validate_certs: no
- name: Start the New VM
uri:
url: "https://{{ inventory_hostname }}:8006/api2/json/nodes/mcp/qemu/2022/status/start"
method: POST
headers:
Authorization: "PVEAPIToken=root@pam!codexmcp=<REDACTED>"
validate_certs: no
- name: Pause for 90 seconds to allow VM setup to complete
pause:
seconds: 90
The 90-second pause is a temporary fix. In future iterations, we’ll replace this with Proxmox QEMU agent checks to determine actual boot readiness.
Configuring MariaDB on the New VM
Once the VM is up, Ansible configures MariaDB. This section ensures:
- MariaDB is installed and running.
- A new database (
codexmcp
) is created. - A dedicated database user is set up with privileges.
- MariaDB listens on all interfaces (
0.0.0.0
).
- name: Configure the New VM
hosts: mariadb_core
gather_facts: no
tasks:
- name: Install MariaDB and dependencies
apt:
name:
- python3
- python3-pymysql
- mariadb-server
state: present
update_cache: yes
- name: Ensure MariaDB is started and enabled at boot
service:
name: mariadb
state: started
enabled: yes
- name: Create database `codexmcp`
community.mysql.mysql_db:
name: codexmcp
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Create `codexmcp` user with privileges
community.mysql.mysql_user:
name: codexmcp
password: "secure-db-password"
priv: "codexmcp.*:ALL"
host: "%"
plugin: "mysql_native_password"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Allow MariaDB to listen on all interfaces
lineinfile:
path: /etc/mysql/mariadb.conf.d/50-server.cnf
regexp: '^bind-address'
line: 'bind-address = 0.0.0.0'
state: present
notify: Restart MariaDB
handlers:
- name: Restart MariaDB
service:
name: mariadb
state: restarted
Next Steps: Refining the Automation
This is iteration 3 of this part of the CodexMCP automation. There are some clear areas for improvement:
- Remove Hardcoded Values
- IP addresses and VM IDs should be dynamically assigned.
- Variables should be extracted for flexibility.
- Replace the Fixed Delay with a Real VM Readiness Check
- Use QEMU Agent to determine when the VM is fully booted.
- Check Cloud-Init logs for finalization before running the database setup.
- Expand the Playbook for More Services
- Automate additional configurations, such as monitoring and backups.
Each iteration gets us closer to a fully automated, one-click deployment for CodexMCP components.
Final Thoughts
This script is working, but it’s not final—and that’s the point. Every piece of automation starts as a rough draft and improves over time. For now, it gets the job done, and as we refine it, we reduce friction, manual intervention, and deployment time.
Stay tuned for the next iteration—where we eliminate the delays and move toward a truly self-managing system.
-One of These Days
--Bryan