Para todos aquellos que utilizamos Puppet habitualmente hemos implementado módulos para distintos entornos (development, testing, production), distintos problemas, pautas, ideas… Cada una de las declaraciones que podemos hacer en ellos puede tener requerimientos distintos y debemos tener en cuenta los cambios que pueden surgir en un futuro. Probablemente nos hemos encontrado en la situación en la que hemos integrado nuestros datos de configuración (direcciones IP, nombres de aplicaciones, credenciales, o cualquier tipo de datos que no queramos compartir) en el código de nuestro repositorio.
Existen distintos métodos para separar esta información sensible, a continuación explicaremos como hacerlo a través de Hiera y eyaml.
Hiera es una herramienta de búsqueda de pares clave/valor para configurar información. Hiera-eyaml es un backend para Hiera que nos proporciona pares de clave/valor cifradas en ficheros yaml para ser utilizadas a través de Puppet.
PD: Si utilizáis algún gestor de versiones de Ruby como rbenv o rvm tenedlo en cuenta al instalar hiera y hiera-eyaml 😉
Podemos tomar como ejemplo la configuración de un módulo para gestionar el servicio SSH:

class ssh {
  $ssh_packages      = ['openssh','openssh-clients','openssh-server']
  $permit_root_login = 'no'
  $ssh_users         = ['root','jeff','gary','hunter']
  package { $ssh_packages:
    ensure => present,
    before => File['/etc/ssh/sshd_config'],
  }
  file { '/etc/ssh/sshd_config':
    ensure  => present,
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    # Template uses $permit_root_login and $ssh_users
    content => template('ssh/sshd_config.erb'),
  }

Y este sería la plantilla que podríamos utilizar para el fichero sshd_config:

Protocol 2
SyslogFacility AUTHPRIV
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
# PermitRootLogin Setting
PermitRootLogin <%= permit_root_login %>
# Allow individual Users
<% ssh_users.each do |user| -%>
AllowUser <%= user %>
<% end -%>
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL
X11Forwarding yes
Subsystem	sftp	/usr/libexec/openssh/sftp-server

Con Hiera podemos hacer referencia a las variables más sensibles cambiando estas 3 lineas:

$ssh_packages      = hiera('ssh_packages')
$permit_root_login = hiera('permit_root_login')
$ssh_users         = hiera('ssh_users')

 
 
Hiera-eyaml nos puede ayudar a evitar comprometer nuestros datos sensible en el backend configurado con hiera. Podemos seguir este procedimiento para lograrlo:

  1. Generar claves pública y privada, por defecto las crea dentro del directorio ./keys en que ejecutemos el siguiente comando. $ eyaml createkeys
  2.  

  3. Añadimos el backend eyaml a la configuración de Hiera en /etc/hiera.yaml
    ---
    :backends:
        - eyaml
        - yaml
    :hierarchy:
        - %{environment}
        - common
    :yaml:
        :datadir: '/etc/puppet/hieradata'
    :eyaml:
        :datadir: '/etc/puppet/hieradata'
        # If using the pkcs7 encryptor (default)
        :pkcs7_private_key: /path/to/private_key.pkcs7.pem
        :pkcs7_public_key:  /path/to/public_key.pkcs7.pem
  4.  

  5. Añadir un fichero de configuración eyaml, de este modo no deberemos especificar la ubicación cada vez que queramos cifrar datos, por defecto sería ~/.eyaml/config.yaml pero podemos sobrescribir esta configuración con la variable de entorno EYAML_CONFIG.
  6.  

  7. Encriptamos los datos con el comando $ eyaml encrypt -p y obtenemos un string similar a este
    ENC[PKCS7,Y22exl+OvjDe+drmik2XEeD3VQtl1uZJXFFF2NnrMXDWx0csyqLB/2NOWefvNBTZfOlPvMlAesyr4bUY4I5XeVbVk38XKxeriH69EFAD4CahIZlC8lkE/uDhjJGQfh052eonkungHIcuGKY/5sEbbZl/qufjAtp/ufor15VBJtsXt17tXP4yl5ZP119Fwq8xiREGOL0lVvFYJz2hZc1ppPCNG5lwuLnTekXN/OazNYpf4CMd/HjZFXwcXRtTlzewJLc+/gox2IfByQRhsI/AgogRfYQKocZgFb/DOZoXR7wmIZGeunzwhqfmEtGiqpvJJQ5wVRdzJVpTnANBA5qxeA==]
  8.  

  9. En este punto ya podemos añadir la información cifrada en el fichero eyaml definido en el segundo paso.
    ssh::permit_root_login: ENC[PKCS7,Y22exl+OvjDe+drmik2XEeD3VQtl1uZJXFFF2NnrMXDWx0csyqLB/2NOWefvNBTZfOlPvMlAesyr4bUY4I5XeVbVk38XKxeriH69EFAD4CahIZlC8lkE/uDhjJGQfh052eonkungHIcuGKY/5sEbbZl/qufjAtp/ufor15VBJtsXt17tXP4yl5ZP119Fwq8xiREGOL0lVvFYJz2hZc1ppPCNG5lwuLnTekXN/OazNYpf4CMd/HjZFXwcXRtTlzewJLc+/gox2IfByQRhsI/AgogRfYQKocZgFb/DOZoXR7wmIZGeunzwhqfmEtGiqpvJJQ5wVRdzJVpTnANBA5qxeA==]
  10.  
     

Debemos tener especial cuidado con las claves generadas con hiera-eyaml y administrar la información cifrada con nuestro gestor de claves favorito (KeepassX, Passpack, etc.) 
En conclusión podemos obtener varias ventajas de utilizar Hiera en combinación con hiera-eyaml, entre ellas:

  • Facilita la configuración de los distintos entornos: configuramos fácilmente datos por defecto con múltiples niveles de override.
  • Facilita la reutilización de los módulos públicos de Puppet: No edites el código, sólo coloca la información necesaria en Hiera.
  • Facilita la colaboración: No necesitas preocuparte de limpiar tu información antes de mostrar el módulo.

 
Saludos!