Vagrant y Puppet Server para pruebas de entornos

El objetivo es tener en Vagrant un servidor Puppet y al menos dos servidores agentes. En este post no trataré la creación de manifiestos, sino que llegará hasta la firma automática de certificados SSL de cuantos agentes se deseen.

Estos son entornos son muy útiles para reproducir en una máquina local, o servidor dedicado, un entorno de producción para poner a prueba la configuración de los servicios y aplicaciones.

Empezando con Vagrant

Todo los scripts los he usado con la versión de Vagrant de los repositorios de Ubuntu 18.04 y Virtualbox como aprovisionador también de los repositorios.

Puppet Server

Vagrant.configure("2") do |config|
  config.vm.box = "generic/debian9"
  config.vm.hostname = "obelix"
  config.vm.network "public_network",ip: "192.168.1.90",bridge: "enp12s0"
  config.vm.provider "virtualbox"# do |vb|
     vb.gui = false
     vb.memory = "2048"
  end
  config.ssh.insert_key = false
  config.ssh.private_key_path = ["~/.vagrant.d/insecure_private_key","/home/gustavo/.ssh/gmoreno", ]
  config.vm.provision "file", source: "~/.ssh/gmoreno.pub", destination: "~/.ssh/authorized_keys"
  config.vm.provision "file", source: "puppet.conf", destination: "/home/vagrant/puppet.conf"
  config.vm.provision "shell", path: server.sh
end

config.vm.box: la caja o «imagen» que usará para el aprovisionador. En este caso una imagén generica de Debian Stretch

config.vm.hostname: el hostname que tendrá la VM.

config.vm.network: confgiura una red publica, con una dirección IP estática y el bridge de la misma interfaz del sistema anfitrión.

config.vm.provider: Define Virtualbox como aprovisonador, sin entorno gráfico y con 2048 Mb de memoría RAM.

En el siguiente segmento se aprovisona una llave para hacer una conexión por SSH:

 config.ssh.insert_key = false
 config.ssh.private_key_path = ["~/.vagrant.d/insecure_private_key","/home/usuario/.ssh/id_rsa", ]
 config.vm.provision "file", source: "~/.ssh/id_rsa.pub", destination: "~/.ssh/authorized_keys"

Con estos envíamos a la VM una llave privada SSH (llamada en este caso id_rsa). También una llave pública que se añade al authorized_keys. De este modo, se prepara el logueo por SSH. Harán falta algunas instrucciones más.

 config.vm.provision "file", source: "puppet.conf", destination: "/home/vagrant/puppet.conf"
 config.vm.provision "shell", path: server.sh

Se copia el archivo puppet.conf desde el anfitrión a la VM y el script bootstrap para el aprovisionamiento de la maquina virtual.

El puppet.conf está en el mismo directorio que el Vagrantfile

[main]
server = puppetserver
certname = puppetserver

[master]
dns_alt_names = puppetserver,puppet

También el bootstrap, llamado aquí server.sh

##### Permite el logueo SSH "normal" #####
sed -i -e "\\#PasswordAuthentication yes# s#PasswordAuthentication yes#PasswordAuthentication no#g" /etc/ssh/sshd_config
systemctl restart sshd.service
#####              #####             #####

#### Instala Puppet Server 5.3 desde Puppetlabs ####    
APT_DOMAIN="//apt.puppetlabs.com"
PCK_PUPPET="puppet5-release-stretch.deb"
PUPPET_DEB="${APT_DOMAIN}/${PCK_PUPPET}"
wget ${PUPPET_DEB}
dpkg -i ${PCK_PUPPET}
apt-get update
apt-get install -y puppetserver 

#### Copia de puppet.conf al directorio de configuración ####
cp -f /home/vagrant/puppet.conf /etc/puppetlabs/puppet/puppet.conf
#### Wilcard de nodos cuyo certificado serán autofirmados ####
echo '*.casa' > /etc/puppetlabs/puppet/autosign.conf

#### Memoria JVM de 2g por defecto a 500 mb  ###
sed -i s/Xmx2g/Xmx500m/g /etc/default/puppetserver;
sed -i s/Xms2g/Xms500m/g /etc/default/puppetserver;
#### Y reinicio del Puppet Server ####
systemctl start puppetserver

Nodos

En un Vagranfile pueden configurarse más de una VM. El script siguiente incluye una función que es llamada para cada máquina que se desee, con distintos nombres para el archivo puppet.conf

def agent(hostname,ip,ssh_key_path,puppet_conf,shell)

  Vagrant.configure("2") do |config|
    config.vm.define hostname do |a|
      a.vm.box = "generic/debian9"
      a.vm.provider "virtualbox"
      a.vm.hostname = hostname
      a.vm.network "public_network",ip: ip, bridge: "enp12s0"
      a.ssh.insert_key = false
      a.ssh.private_key_path = ["~/.vagrant.d/insecure_private_key",ssh_key_path]
      a.vm.provision "file", source: ssh_key_path+".pub", destination: "~/.ssh/authorized_keys"
      a.vm.provision "file", source: puppet_conf, destination: "/home/vagrant/puppet.conf"
      a.vm.provision "shell", path: shell
    end
  end
end

agent("nginx","192.168.1.50","/home/usuario/.ssh/id_rsa","puppet-nginx.conf","agente.sh")
agent("postgres","192.168.1.51","/home/usuario/.ssh/id_rsa","puppet-postgres.conf","agente.sh")

Es muy similar al Vagranfile del servidor. Cabe destacar la llamada:

agent("nginx","192.168.1.50","/home/usuario/.ssh/id_rsa","puppet-nginx.conf","agente.sh").

Lo parametros que se introducen son, en este orden: nombre de la VM y hostname, dirección IP de la máquina, path de la llave RSA, el nombre del archivo puppet.conf y el nombre del archivo bootstrap.

El bootstrap agente.sh para el nodo puede ser como este:

sed -i -e «\#PasswordAuthentication yes# s#PasswordAuthentication yes#PasswordAuthentication no#g» /etc/ssh/sshd_config
systemctl restart sshd.service

echo "192.168.1.90 puppetserver puppet" >> /etc/hosts
wget //apt.puppetlabs.com/puppet5-release-stretch.deb
dpkg -i puppet5-release-stretch.deb
apt-get update
apt-get -y install puppet-agent
cp /home/vagrant/puppet.conf /etc/puppetlabs/puppet/puppet.conf -f
mkdir /var/lib/puppet
ln -s /opt/puppetlabs/puppet/bin/puppet /bin/puppet
puppet agent -t

Y el puppet.conf

[main]
ssldir = /var/lib/puppet/ssl
server = puppetserver
certname = testing-nginx-r0001.casa

[master]
vardir = /var/lib/puppet
cadir  = /var/lib/puppet/ssl/ca
dns_alt_names = puppetserver,puppet

El certname se debe ir cambiando a cada nueva máquina creada si se mantiene el mismo servidor. La razón para ello es que el servidor recibiría la petición de firmar un certificado con un nombre que ya existe y se negaría a hacerlo.

En el ejemplo se usan los archivos de configuración con los nombres puppet-nginx.conf y puppet-postgres.conf entre los cuales la única diferencia de contenido es el certname.

Gustavo Moreno

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.