Hosting Equipo Avantys 5 min

Automatizar VPS con Ansible: Guía Práctica

Aprende a automatizar la configuración de tu VPS con Ansible. Playbooks para seguridad, LEMP, WordPress y backups. Ahorra horas de trabajo.

// Compartir

Automatizar VPS con Ansible: Guía Práctica
Automatizar VPS con Ansible

¿Cansado de configurar VPS manualmente? Con Ansible puedes automatizar todo: desde seguridad básica hasta deploy completo. Una vez configurado, replicar toma minutos.

Por qué Ansible

AlternativaComplejidadCurva
Scripts BashMediaBaja
AnsibleBajaMedia
TerraformAltaAlta
Puppet/ChefAltaAlta

Ansible es ideal para VPS: Sin agentes, usa SSH, fácil de aprender.

Instalar Ansible

En tu máquina local (no en el VPS)

# Ubuntu/Debian
sudo apt update
sudo apt install ansible -y

# macOS
brew install ansible

# Verificar
ansible --version

Estructura básica

Flujo de trabajo Ansible
mi-ansible/
├── inventory.ini      # Lista de servidores
├── ansible.cfg        # Configuración
├── playbooks/
│   ├── seguridad.yml
│   ├── lemp.yml
│   └── wordpress.yml
└── roles/            # Opcional, para organizar

Inventario

# inventory.ini
[vps]
mi-vps ansible_host=123.45.67.89 ansible_user=root

[produccion]
prod1 ansible_host=123.45.67.90 ansible_user=deploy
prod2 ansible_host=123.45.67.91 ansible_user=deploy

Configuración

# ansible.cfg
[defaults]
inventory = inventory.ini
host_key_checking = False

Playbook: Seguridad básica

Playbooks Ansible para VPS
# playbooks/seguridad.yml
---
- name: Configurar seguridad básica VPS
  hosts: vps
  become: yes

  vars:
    ssh_port: 2222
    usuario: deploy

  tasks:
    - name: Actualizar sistema
      apt:
        update_cache: yes
        upgrade: dist

    - name: Crear usuario no-root
      user:
        name: "{{ usuario }}"
        shell: /bin/bash
        groups: sudo
        append: yes

    - name: Configurar clave SSH para usuario
      authorized_key:
        user: "{{ usuario }}"
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

    - name: Cambiar puerto SSH
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?Port'
        line: "Port {{ ssh_port }}"

    - name: Deshabilitar login root
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin no'

    - name: Deshabilitar login por contraseña
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?PasswordAuthentication'
        line: 'PasswordAuthentication no'

    - name: Reiniciar SSH
      service:
        name: sshd
        state: restarted

    - name: Instalar UFW
      apt:
        name: ufw
        state: present

    - name: Configurar UFW - denegar por defecto
      ufw:
        default: deny
        direction: incoming

    - name: UFW - permitir SSH
      ufw:
        rule: allow
        port: "{{ ssh_port }}"
        proto: tcp

    - name: UFW - permitir HTTP
      ufw:
        rule: allow
        port: 80

    - name: UFW - permitir HTTPS
      ufw:
        rule: allow
        port: 443

    - name: Activar UFW
      ufw:
        state: enabled

    - name: Instalar Fail2ban
      apt:
        name: fail2ban
        state: present

    - name: Habilitar Fail2ban
      service:
        name: fail2ban
        state: started
        enabled: yes

Ejecutar

ansible-playbook playbooks/seguridad.yml

Playbook: Stack LEMP

# playbooks/lemp.yml
---
- name: Instalar stack LEMP
  hosts: vps
  become: yes

  vars:
    php_version: "8.2"
    mysql_root_password: "tu_password_seguro"

  tasks:
    - name: Instalar Nginx
      apt:
        name: nginx
        state: present

    - name: Instalar PHP y extensiones
      apt:
        name:
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-mysql"
          - "php{{ php_version }}-curl"
          - "php{{ php_version }}-gd"
          - "php{{ php_version }}-mbstring"
          - "php{{ php_version }}-xml"
          - "php{{ php_version }}-zip"
          - "php{{ php_version }}-intl"
        state: present

    - name: Instalar MariaDB
      apt:
        name: mariadb-server
        state: present

    - name: Iniciar servicios
      service:
        name: "{{ item }}"
        state: started
        enabled: yes
      loop:
        - nginx
        - "php{{ php_version }}-fpm"
        - mariadb

    - name: Configurar OPcache
      lineinfile:
        path: "/etc/php/{{ php_version }}/fpm/php.ini"
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
      loop:
        - { regexp: '^;?opcache.enable=', line: 'opcache.enable=1' }
        - { regexp: '^;?opcache.memory_consumption=', line: 'opcache.memory_consumption=128' }
      notify: Reiniciar PHP-FPM

  handlers:
    - name: Reiniciar PHP-FPM
      service:
        name: "php{{ php_version }}-fpm"
        state: restarted

Playbook: WordPress

# playbooks/wordpress.yml
---
- name: Instalar WordPress
  hosts: vps
  become: yes

  vars:
    dominio: "midominio.com"
    db_name: "wordpress"
    db_user: "wp_user"
    db_password: "password_seguro"

  tasks:
    - name: Crear base de datos
      mysql_db:
        name: "{{ db_name }}"
        state: present

    - name: Crear usuario MySQL
      mysql_user:
        name: "{{ db_user }}"
        password: "{{ db_password }}"
        priv: "{{ db_name }}.*:ALL"
        state: present

    - name: Crear directorio web
      file:
        path: "/var/www/{{ dominio }}"
        state: directory
        owner: www-data
        group: www-data

    - name: Descargar WordPress
      get_url:
        url: https://wordpress.org/latest.tar.gz
        dest: /tmp/wordpress.tar.gz

    - name: Extraer WordPress
      unarchive:
        src: /tmp/wordpress.tar.gz
        dest: "/var/www/{{ dominio }}"
        remote_src: yes
        extra_opts: [--strip-components=1]
        owner: www-data
        group: www-data

    - name: Configurar Nginx para WordPress
      template:
        src: templates/nginx-wordpress.conf.j2
        dest: "/etc/nginx/sites-available/{{ dominio }}"
      notify: Reiniciar Nginx

    - name: Activar sitio
      file:
        src: "/etc/nginx/sites-available/{{ dominio }}"
        dest: "/etc/nginx/sites-enabled/{{ dominio }}"
        state: link
      notify: Reiniciar Nginx

  handlers:
    - name: Reiniciar Nginx
      service:
        name: nginx
        state: restarted

Variables con Vault (secretos)

# Crear archivo encriptado
ansible-vault create secrets.yml

# Contenido
db_password: "mi_password_muy_seguro"
api_key: "abc123..."

# Usar en playbook
ansible-playbook playbook.yml --ask-vault-pass

Ejecutar en múltiples servidores

# Solo un servidor
ansible-playbook -l mi-vps playbooks/seguridad.yml

# Grupo completo
ansible-playbook -l produccion playbooks/seguridad.yml

# Todos
ansible-playbook playbooks/seguridad.yml

Playbook completo: VPS desde cero

# playbooks/vps-completo.yml
---
- name: Configurar VPS completo
  hosts: vps
  become: yes

  vars:
    ssh_port: 2222
    php_version: "8.2"
    dominio: "midominio.com"

  roles:
    - seguridad
    - lemp
    - wordpress
    - ssl
    - backups

Comandos útiles

# Verificar sintaxis
ansible-playbook playbook.yml --syntax-check

# Modo prueba (no ejecuta)
ansible-playbook playbook.yml --check

# Ver qué haría
ansible-playbook playbook.yml --diff

# Ejecutar tarea específica
ansible-playbook playbook.yml --tags "nginx"

# Ejecutar en verbose
ansible-playbook playbook.yml -v

Preguntas frecuentes

¿Necesito instalar algo en el VPS para usar Ansible?

No. Ansible usa SSH y Python (que ya viene en Ubuntu). No necesita agentes. Solo necesitas Ansible en tu máquina local.

¿Puedo usar Ansible si solo tengo un VPS?

Sí, vale la pena. Documentas tu configuración como código, puedes replicar fácilmente, y si algo falla, reconfiguras en minutos.

¿Ansible es difícil de aprender?

Es el más fácil de las herramientas de automatización. YAML es legible, la documentación es excelente. En unas horas puedes crear playbooks básicos.

¿Puedo mezclar Ansible con configuración manual?

Sí, pero no es ideal. Ansible funciona mejor cuando gestiona todo. Cambios manuales pueden perderse o causar conflictos.

¿Ansible es gratis?

Ansible Core es 100% gratis y open source. Ansible Tower/AWX ofrece interfaz gráfica y más features (gratis AWX, pago Tower).

Nuestra recomendación

Para empezar:

  1. Crea playbook de seguridad básica
  2. Prueba en VPS de desarrollo
  3. Añade playbooks gradualmente

Beneficios:

  • Configuración documentada
  • Replicable en minutos
  • Menos errores humanos
  • Versionable con Git

¿No quieres automatizar tú mismo? La administración gestionada de Avantys incluye configuración y mantenimiento profesional.


Conclusión

Ansible transforma horas de configuración manual en minutos de ejecución automática. Una vez creados los playbooks, tienes tu infraestructura como código.

Empieza con seguridad básica y ve añadiendo más automatización.


¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.