DEV Community

Cover image for Automation in Action: Scenarios with Proxmox and Ansible
Fedya
Fedya

Posted on

Automation in Action: Scenarios with Proxmox and Ansible

Nowadays, Time Is the Most Valuable Resource
If you manage virtual machines or servers manually, you know how much time and effort it takes. The good news is that there are ways to automate almost everything in your IT infrastructure.

πŸ“Œ Specific Benefit: With Proxmox and Ansible, you can automate server installations, updates, and configurations.
πŸ“Œ Practical Content: You’ll see real-world examples and usage scenarios.
πŸ“Œ Measurable Value: Save up to 80% of the time spent on routine tasks, allowing you to focus on strategic work.

🧠 What Is Proxmox?
Proxmox VE (Virtual Environment) is an open-source virtualization platform based on Debian Linux. It combines the KVM hypervisor and LXC containers with a web interface and a powerful REST API.

Key Advantages of Proxmox:
βœ… Free and open-source
πŸ”§ Manage VMs and containers
πŸ”„ Cluster and High Availability (HA) support
🌐 Web-based interface for easy management

πŸ€” What Is Ansible?
Ansible is an agentless automation tool that uses SSH to access remote machines and execute tasks.

Advantages of Ansible:
🧩 Simple YAML syntax (playbooks)
πŸ§ͺ Idempotent (always produces the same result)
🚫 No additional software needed on client machines
πŸ“š Huge library of modules

🧩 Why Combine Proxmox and Ansible?
By integrating Proxmox for virtualization and Ansible for automation, you get a powerful platform for managing entire IT environments with minimal effort.

This combination provides:
Fast VM provisioning

Bulk system updates

Consistent server configurations

Automated backups and monitoring

πŸ› οΈ Scenario 1: Automatically Create VMs in Proxmox
Problem:
Manually creating a VM is time-consuming and requires multiple clicks in the web interface.

Solution:
With Ansible, you can create an LXC container in Proxmox using a single playbook.

Example Playbook:

---
- name: Create LXC Container in Proxmox  
  hosts: localhost  
  connection: local  
  gather_facts: no  

  vars:  
    proxmox_api_host: "{{ proxmox_host | default('proxmox.example.com') }}"  
    proxmox_api_user: "{{ proxmox_user | default('root@pam') }}"  
    proxmox_node: "{{ target_node | default('pve') }}"  
    ct_id: "{{ vmid | default(200) }}"  
    ct_hostname: "{{ hostname | default('test-lxc') }}"  
    ct_cores: "{{ cores | default(2) }}"  
    ct_memory: "{{ memory | default(1024) }}"  
    ct_disk_size: "{{ disk_size | default(8) }}"  
    ct_storage: "{{ storage | default('local-lvm') }}"  
    ct_template: "{{ ostemplate | default('local:vztmpl/ubuntu-20.04-standard_20.04-1_amd64.tar.gz') }}"  
    ct_password: "{{ root_password | default('changeme123') }}"  

  tasks:  
    - name: Create LXC Container  
      community.general.proxmox:  
        api_user: "{{ proxmox_api_user }}"  
        api_password: "{{ proxmox_password }}"  
        api_host: "{{ proxmox_api_host }}"  
        node: "{{ proxmox_node }}"  
        vmid: "{{ ct_id }}"  
        hostname: "{{ ct_hostname }}"  
        cores: "{{ ct_cores }}"  
        memory: "{{ ct_memory }}"  
        swap: "{{ ct_memory // 2 }}"  
        disk: "{{ ct_disk_size }}"  
        storage: "{{ ct_storage }}"  
        ostemplate: "{{ ct_template }}"  
        password: "{{ ct_password }}"  
        # Network config  
        netif:  
          net0: "name=eth0,bridge=vmbr0,ip=dhcp,type=veth"  
        # Features  
        features:  
          - nesting=1  # Allows Docker  
        # Auto-start  
        onboot: yes  
        # Unprivileged container (more secure)  
        unprivileged: yes  
        state: present  
      register: lxc_creation  

    - name: Start Container  
      community.general.proxmox:  
        api_user: "{{ proxmox_api_user }}"  
        api_password: "{{ proxmox_password }}"  
        api_host: "{{ proxmox_api_host }}"  
        vmid: "{{ ct_id }}"  
        state: started  
      when: lxc_creation is succeeded  

    - name: Show Container Info  
      debug:  
        msg: |  
          LXC container created successfully!  
          ID: {{ ct_id }}  
          Hostname: {{ ct_hostname }}  
          Node: {{ proxmox_node }}  
          Resources: {{ ct_cores }} cores, {{ ct_memory }}MB RAM  
Enter fullscreen mode Exit fullscreen mode

How to Use Enhanced Playbooks:

# For a VM with variables  
ansible-playbook proxmox-vm.yml -e "proxmox_password=your_password vmid=111 vm_name=web-server"  

# For LXC with variables  
ansible-playbook proxmox-lxc.yml -e "proxmox_password=your_password vmid=201 hostname=app-container"  

# Or use a vars file  
ansible-playbook proxmox-vm.yml --extra-vars "@vars.yml"  
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ Scenario 2: Configure a New Web Server
Problem:
Manually installing a LAMP/LEMP stack is time-consuming and error-prone.

Solution:
An Ansible playbook that automates the process.

Example Playbook:

---
- name: Install and Configure LAMP Stack  
  hosts: web  
  become: yes  
  vars:  
    mysql_root_password: "your_secure_password_here"  

  tasks:  
    - name: Update packages  
      apt:  
        update_cache: yes  

    - name: Install Apache  
      apt:  
        name: apache2  
        state: present  

    - name: Install PHP and required modules  
      apt:  
        name:  
          - php  
          - php-mysql  
          - php-cli  
          - php-curl  
          - php-gd  
          - php-mbstring  
          - php-xml  
          - libapache2-mod-php  
        state: present  

    - name: Install MariaDB  
      apt:  
        name:  
          - mariadb-server  
          - mariadb-client  
          - python3-pymysql  
        state: present  

    - name: Start and enable Apache  
      systemd:  
        name: apache2  
        state: started  
        enabled: yes  

    - name: Start and enable MariaDB  
      systemd:  
        name: mariadb  
        state: started  
        enabled: yes  

    - name: Set MySQL root password  
      mysql_user:  
        name: root  
        password: "{{ mysql_root_password }}"  
        login_unix_socket: /var/run/mysqld/mysqld.sock  

    - name: Remove anonymous MySQL users  
      mysql_user:  
        name: ''  
        host_all: yes  
        state: absent  
        login_user: root  
        login_password: "{{ mysql_root_password }}"  

    - name: Remove test database  
      mysql_db:  
        name: test  
        state: absent  
        login_user: root  
        login_password: "{{ mysql_root_password }}"  

    - name: Create basic PHP info file  
      copy:  
        content: "<?php phpinfo(); ?>"  
        dest: /var/www/html/info.php  
        mode: '0644'  

    - name: Enable Apache rewrite module  
      apache2_module:  
        name: rewrite  
        state: present  
      notify: restart apache  

    - name: Configure firewall for HTTP/HTTPS  
      ufw:  
        rule: allow  
        port: "{{ item }}"  
      loop:  
        - '80'  
        - '443'  

  handlers:  
    - name: restart apache  
      systemd:  
        name: apache2  
        state: restarted  
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ Scenario 3: Mass Update All Servers
Problem:
Updating 10+ servers one by one is exhausting and risky.

Solution:
With Ansible, you can update all machines with a single command.

Example Playbook:

# Strategy for production updates  

# 1. Update staging first  
- name: Update staging servers  
  hosts: staging  
  become: yes  
  tasks:  
    - include: update-tasks.yml  

# 2. Update production in small batches  
- name: Update production (group 1)  
  hosts: production[0:2]  # First 3 servers  
  become: yes  
  serial: 1  
  tasks:  
    - include: update-tasks.yml  
    - name: Wait and verify  
      pause:  
        minutes: 5  
        prompt: "Check if everything works before continuing"  

- name: Update production (group 2)  
  hosts: production[3:]   # Remaining servers  
  become: yes  
  serial: "20%"  
  tasks:  
    - include: update-tasks.yml  
Enter fullscreen mode Exit fullscreen mode

How to Use the Playbook:

# Safe update (recommended)  
ansible-playbook update-servers.yml  

# Only security updates  
ansible-playbook update-servers.yml -e "upgrade_type=security"  

# Full update (be careful!)  
ansible-playbook update-servers.yml -e "upgrade_type=full"  

# With auto-reboot (risky!)  
ansible-playbook update-servers.yml -e "auto_reboot=true"  

# On smaller server batches  
ansible-playbook update-servers.yml -e "batch_size=1"  

# Only specific servers  
ansible-playbook update-servers.yml -l "webservers"  
Enter fullscreen mode Exit fullscreen mode

πŸ”— Useful Tips for Beginners
1️⃣ Start with a local Proxmox server – Install Proxmox on an old PC for practice.
2️⃣ Use Ansible Vault – Encrypt passwords and tokens with ansible-vault.
3️⃣ Test before execution – Use --check for a dry run before applying changes.
4️⃣ Group servers in an inventory file – Organize by function (e.g., [web], [db]).

πŸ“ˆ Key Takeaways & Recommendations
The Proxmox + Ansible combo provides:
πŸ”₯ Flexibility – Full control over your virtual environment
βš™οΈ Speed – Tasks that take hours are done in minutes
🧠 Simplicity – Easy-to-understand YAML files

πŸ§ͺ Conclusion
Whether you're a sysadmin, DevOps engineer, or enthusiast, automation is the future. With Proxmox and Ansible, you can build a stable, easy-to-manage infrastructure with minimal effort but maximum impact.

πŸš€ Start today with small steps and experience the power of automation from your first playbook!

Let me know if you'd like any refinements! πŸš€

Top comments (0)