Skip to main content

Infraestructura como Código con Puppet en modo Standalone

Crónicas de una maestría (Parte 2)

Updated 4 min readMarkdown
Infraestructura como Código con Puppet en modo Standalone

Regresar a las aulas te enseña que la academia es dinámica. Justo cuando nos preparábamos para montar toda una arquitectura clásica de cliente-servidor con certificados SSL y un Puppet Master pesado, la clase dio un giro hacia la agilidad: para nuestras prácticas, orquestaremos nuestra infraestructura usando Puppet en modo Standalone.

Como SysAdmins de la vieja escuela, muchas veces estamos acostumbrados a resolver problemas de forma imperativa: un script de Bash lleno de sed, awk y systemctl para levantar servicios. Sin embargo, Puppet nos obliga a cambiar el chip hacia un lenguaje declarativo. En lugar de decirle al sistema cómo hacer las cosas, le declaramos el estado final deseado (ej. "el paquete apache2 debe estar instalado y el servicio ejecutándose") y Puppet se encarga de la magia para lograrlo.

Aunque la arquitectura empresarial requiere un Master, para entornos de desarrollo y laboratorios podemos usar el agente de Puppet de forma local, dejando que Vagrant automatice toda la ejecución. Aquí les muestro cómo adaptar nuestro entorno en Fedora para lograr este flujo de trabajo ágil.

1. El aprovisionamiento desde el Vagrantfile

Vagrant es tan flexible que nos permite encadenar distintos aprovisionadores. Para preparar nuestra máquina Ubuntu, usaremos un bloque shell (para instalar el agente) y un bloque puppet (para orquestar la configuración).

Editamos nuestro Vagrantfile agregando estas líneas justo antes del end final:

  # Bloque Shell: Instalamos el repositorio y el agente de Puppet 7
  config.vm.provision "shell", inline: <<-SHELL
    sudo wget https://apt.puppet.com/puppet7-release-jammy.deb
    sudo dpkg -i puppet7-release-jammy.deb
    sudo apt-get update
    sudo apt-get install -y puppet-agent
  SHELL
   
  # Bloque Puppet: Le indicamos a Vagrant dónde vivirán nuestros manifiestos
  config.vm.provision "puppet" do |puppet|
    puppet.module_path = "modules"        
    puppet.manifests_path = "manifests"
    puppet.manifest_file = "default.pp"
  end

2. Estructura como Código (Módulos y Manifiestos)

Al usar Puppet, el orden y la estructura son vitales. Al mismo nivel donde está guardado nuestro Vagrantfile en nuestro host, debemos crear la siguiente jerarquía de directorios:

.
├── Vagrantfile
├── manifests/
│   └── default.pp
└── modules/
    └── apache/
        ├── manifests/
        │   └── init.pp
        └── templates/
            └── virtual-hosts.conf.erb

El archivo manifests/default.pp es nuestro punto de entrada (el manifiesto principal). Por ahora, solo le diremos que incluya el módulo del servidor web:

# manifests/default.pp
include apache

3. Escribiendo nuestro primer módulo: Apache

Dentro de modules/apache/manifests/init.pp, declaramos el estado de nuestro servidor. Lo fascinante de la sintaxis declarativa es cómo manejamos las dependencias mediante require y subscribe para garantizar que (por ejemplo) el servicio no arranque si el paquete no está instalado.

class apache {
  # Actualizamos repositorios antes de instalar
  exec { 'apt-update':
    command => '/usr/bin/apt-get update',
  }

  # Forzamos el apt-update antes de evaluar cualquier paquete
  Exec['apt-update'] -> Package <| |>

  # 1. El paquete debe estar instalado
  package { 'apache2':
    ensure => installed,
  }

  # 2. Inyectamos una plantilla de configuración personalizada
  file { '/etc/apache2/sites-available/vagrant.conf':
    content => template('apache/virtual-hosts.conf.erb'),
    require => Package['apache2'],
  }

  # 3. Habilitamos nuestro sitio creando un symlink
  file { '/etc/apache2/sites-enabled/vagrant.conf':
    ensure  => link,
    target  => '/etc/apache2/sites-available/vagrant.conf',
    require => File['/etc/apache2/sites-available/vagrant.conf'],
  }

  # 4. El servicio debe estar corriendo, y se reiniciará si la conf cambia
  service { 'apache2':
    ensure    => running,
    enable    => true,
    subscribe => File['/etc/apache2/sites-available/vagrant.conf'],
  }
}

4. La verdadera agilidad: vagrant provision

¿Qué pasa si me equivoco en una línea o quiero agregar un módulo nuevo? En el modelo clásico de hipervisores manuales, tocaría deshacer cambios a mano o restaurar un snapshot. Con Vagrant y Puppet, simplemente corregimos nuestro archivo .pp en nuestro editor favorito y ejecutamos:

$ vagrant provision

Este es el verdadero superpoder de Infraestructura como Código. Vagrant detecta que la máquina ya está corriendo (no la destruye ni la reinicia) y simplemente lanza puppet apply con los nuevos cambios de forma idempotente. Si Apache ya estaba instalado, Puppet no pierde tiempo reinstalándolo, solo evalúa y aplica las diferencias.

Con esta sólida base declarativa en modo Standalone, hemos preparado el terreno. La primera actividad oficial de la maestría es automatizar desde cero el despliegue de un CMS completo (WordPress) con su base de datos, cumpliendo rúbricas estrictas.

Esa batalla, y el cómo utilizar WP-CLI para saltarnos los instaladores gráficos, se las cuento en la próxima crónica.

About the author

No comments yet. Be the first to comment.