Puppet - Proyecto en vivo

Para realizar las pruebas en vivo de la aplicación de la configuración y los manifiestos en el nodo Puppet, usaremos una demostración de trabajo en vivo. Esto se puede copiar y pegar directamente para probar cómo funciona la configuración. Si el usuario desea utilizar el mismo conjunto de código, debe tener la misma convención de nomenclatura que se muestra en los fragmentos de código siguientes.

Comencemos con la creación de un nuevo módulo.

Crear un módulo nuevo

El primer paso para probar y aplicar la configuración httpd es crear un módulo. Para hacer esto, el usuario necesita cambiar su directorio de trabajo al directorio del módulo Puppet y crear una estructura de módulo básica. La creación de la estructura se puede hacer manualmente o utilizando Puppet para crear un texto modelo para el módulo.

# cd /etc/puppet/modules 
# puppet module generate Live-module

Note - El comando Puppet module generate requiere que el nombre del módulo tenga el formato [nombre de usuario] - [módulo] para cumplir con las especificaciones de Puppet forge.

El nuevo módulo contiene algunos archivos básicos, incluido un directorio de manifiesto. El directorio ya contiene un manifiesto llamado init.pp, que es el archivo de manifiesto principal de los módulos. Esta es una declaración de clase vacía para el módulo.

class live-module { 
}

El módulo también contiene un directorio de prueba que contiene un manifiesto llamado init.pp. Este manifiesto de prueba contiene una referencia a la clase de módulo en vivo dentro de manifest / init.pp:

include live-module

Puppet utilizará este módulo de prueba para probar el manifiesto. Ahora estamos listos para agregar la configuración al módulo.

Instalación de un servidor HTTP

El módulo Puppet instalará los paquetes necesarios para ejecutar el servidor http. Esto requiere una definición de recurso que defina la configuración de paquetes httpd.

En el directorio de manifiesto del módulo, cree un nuevo archivo de manifiesto llamado httpd.pp

# touch test-module/manifests/httpd.pp

Este manifiesto contendrá toda la configuración HTTP para nuestro módulo. Para fines de separación, mantendremos el archivo httpd.pp separado del archivo de manifiesto init.pp

Necesitamos poner el siguiente código en el archivo de manifiesto httpd.pp.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
}

Este código define una subclase de módulo de prueba llamada httpd, luego define una declaración de recursos de paquete para el paquete httpd. El atributo asegurar => instalado comprueba si el paquete requerido está instalado. Si no está instalado, Puppet usa la utilidad yum para instalarlo. Lo siguiente es incluir esta subclase en nuestro archivo de manifiesto principal. Necesitamos editar el manifiesto init.pp.

class test-module { 
   include test-module::httpd 
}

Ahora es el momento de probar el módulo, lo que podría hacerse de la siguiente manera

# puppet apply test-module/tests/init.pp --noop

El comando Puppet Apply aplica la configuración presente en el archivo de manifiesto en el sistema de destino. Aquí, estamos usando test init.pp que se refiere al init.pp principal. –Noop realiza la ejecución en seco de la configuración, que solo muestra la salida pero en realidad no hace nada.

A continuación se muestra la salida.

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.59 seconds 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 1 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.67 seconds

La línea resaltada es el resultado del atributo asegurar => instalado. El current_value ausente significa que Puppet ha detectado que el paquete httpd está instalado. Sin la opción –noop, Puppet instalará el paquete httpd.

Ejecutando el servidor httpd

Después de instalar los servidores httpd, necesitamos iniciar el servicio usando otra desaceleración de recursos: Servicio

Necesitamos editar el archivo de manifiesto httpd.pp y editar el siguiente contenido.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
   service { 'httpd': 
      ensure => running, 
      enable => true, 
      require => Package["httpd"], 
   } 
}

A continuación se muestra la lista de objetivos que hemos logrado con el código anterior.

  • los ensure => El estado de ejecución comprueba si el servicio se está ejecutando, si no, lo habilita.

  • los enable => El atributo true configura el servicio para que se ejecute cuando se inicia el sistema.

  • los require => Package["httpd"]El atributo define una relación de ordenamiento entre una desaceleración de recursos y otra. En el caso anterior, garantiza que el servicio httpd se inicie después de instalar el paquete http. Esto crea una dependencia entre el servicio y el paquete respectivo.

Ejecute el comando de aplicación de marionetas para probar los cambios nuevamente.

# puppet apply test-module/tests/init.pp --noop 
Notice: Compiled catalog for puppet.example.com in environment 
production in 0.56 seconds 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 2 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.41 seconds

Configuración del servidor httpd

Una vez que se completen los pasos anteriores, tendremos el servidor HTTP instalado y habilitado. El siguiente paso es proporcionar alguna configuración al servidor. De forma predeterminada, httpd proporciona algunas configuraciones predeterminadas en /etc/httpd/conf/httpd.conf que proporciona un puerto de host web 80. Agregaremos un host adicional para proporcionar algunas facilidades específicas del usuario al host web.

Se utilizará una plantilla para proporcionar un puerto adicional ya que requiere una entrada variable. Crearemos un directorio llamado plantilla y agregaremos un archivo llamado test-server.config.erb en el nuevo director y agregaremos el siguiente contenido.

Listen <%= @httpd_port %> 
NameVirtualHost *:<% = @httpd_port %> 

<VirtualHost *:<% = @httpd_port %>> 
   DocumentRoot /var/www/testserver/ 
   ServerName <% = @fqdn %> 
   
   <Directory "/var/www/testserver/"> 
      Options All Indexes FollowSymLinks 
      Order allow,deny 
      Allow from all 
   </Directory> 
</VirtualHost>

La plantilla anterior sigue el formato de configuración estándar del servidor apache-tomcat. La única diferencia es el uso del carácter de escape Ruby para inyectar variables desde el módulo. Tenemos FQDN que almacena el nombre de dominio completo del sistema. Esto se conoce comosystem fact.

Los datos del sistema se recopilan de cada sistema antes de generar el catálogo de marionetas de cada sistema respectivo. Puppet usa el comando facter para obtener esta información y uno puede usar facter para obtener otros detalles sobre el sistema. Necesitamos agregar las líneas resaltadas en el archivo de manifiesto httpd.pp.

class test-module::httpd { 
   package { 'httpd': 
      ensure => installed, 
   } 
   service { 'httpd': 
      ensure => running, 
      enable => true, 
      require => Package["httpd"], 
   } 
   file {'/etc/httpd/conf.d/testserver.conf': 
      notify => Service["httpd"], 
      ensure => file, 
      require => Package["httpd"], 
      content => template("test-module/testserver.conf.erb"), 
   } 
   file { "/var/www/myserver": 
      ensure => "directory", 
   } 
}

Esto ayuda a lograr las siguientes cosas:

  • Esto agrega una declaración de recursos de archivo para el archivo de configuración del servidor (/etc/httpd/conf.d/test-server.conf). El contenido de este archivo es la plantilla test-serverconf.erb que se creó anteriormente. También verificamos el paquete httpd instalado antes de agregar este archivo.

  • Esto agrega la segunda declaración de recursos de archivo que crea un directorio (/ var / www / test-server) para el servidor web.

  • A continuación, agregamos la relación entre el archivo de configuración y el servicio https usando el notify => Service["httpd"]attribute. Esto verifica si hay cambios en el archivo de configuración. Si lo hay, Puppet reinicia el servicio.

Lo siguiente es incluir httpd_port en el archivo de manifiesto principal. Para esto, necesitamos finalizar el archivo de manifiesto init.pp principal e incluir el siguiente contenido.

class test-module ( 
   $http_port = 80 
) { 
   include test-module::httpd 
}

Esto establece el puerto httpd en el valor predeterminado de 80. Lo siguiente es ejecutar el comando Puppet apply.

Lo siguiente será la salida.

# puppet apply test-module/tests/init.pp --noop 
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.84 seconds 

Notice: /Stage[main]/test-module::Httpd/File[/var/www/myserver]/ensure: 
current_value absent, should be directory (noop) 

Notice: /Stage[main]/test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: 
/Stage[main]/test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensure: 
current_value absent, should be file (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 4 
events 

Notice: Stage[main]: Would have triggered 'refresh' from 1 events 
Notice: Finished catalog run in 0.51 seconds

Configurar el cortafuegos

Para comunicarse con el servidor, se requiere un puerto abierto. El problema aquí es que diferentes tipos de sistemas operativos utilizan diferentes métodos para controlar el firewall. En el caso de Linux, las versiones inferiores a 6 usan iptables y la versión 7 usa firewalld.

Puppet maneja de alguna manera esta decisión de usar un servicio apropiado usando los hechos del sistema y su lógica. Para esto, primero debemos verificar el sistema operativo y luego ejecutar el comando de firewall apropiado.

Para lograr esto, necesitamos agregar el siguiente fragmento de código dentro de la clase testmodule :: http.

if $operatingsystemmajrelease <= 6 { 
   exec { 'iptables': 
      command => "iptables -I INPUT 1 -p tcp -m multiport --ports 
      ${httpd_port} -m comment --comment 'Custom HTTP Web Host' -j ACCEPT && 
      iptables-save > /etc/sysconfig/iptables", 
      path => "/sbin", 
      refreshonly => true, 
      subscribe => Package['httpd'], 
   } 
   service { 'iptables': 
      ensure => running, 
      enable => true, 
      hasrestart => true, 
      subscribe => Exec['iptables'], 
   } 
}  elsif $operatingsystemmajrelease == 7 { 
   exec { 'firewall-cmd': 
      command => "firewall-cmd --zone=public --addport = $ { 
      httpd_port}/tcp --permanent", 
      path => "/usr/bin/", 
      refreshonly => true, 
      subscribe => Package['httpd'], 
   } 
   service { 'firewalld': 
      ensure => running, 
      enable => true, 
      hasrestart => true, 
      subscribe => Exec['firewall-cmd'], 
   } 
}

El código anterior realiza lo siguiente:

  • Utilizando el operatingsystemmajrelease determina si el sistema operativo que se utiliza es la versión 6 o 7.

  • Si la versión es 6, entonces ejecuta todos los comandos de configuración necesarios para configurar la versión 6 de Linux.

  • Si la versión del sistema operativo es 7, ejecuta todos los comandos necesarios para configurar el firewall.

  • El fragmento de código para ambos sistemas operativos contiene una lógica que garantiza que la configuración se ejecute solo después de que se haya instalado el paquete http.

Finalmente, ejecute el comando de aplicación Puppet.

# puppet apply test-module/tests/init.pp --noop 
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for puppet.example.com in environment 
production in 0.82 seconds 

Notice: /Stage[main]/test-module::Httpd/Exec[iptables]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/test-module::Httpd/Service[iptables]: Would have 
triggered 'refresh' from 1 events

Configurando el SELinux

Como estamos trabajando en una máquina Linux que es de la versión 7 y superior, necesitamos configurarla para hacer una comunicación http. SELinux restringe el acceso no estándar al servidor HTTP de forma predeterminada. Si definimos un puerto personalizado, entonces necesitamos configurar SELinux para proporcionar acceso a ese puerto.

Puppet contiene algún tipo de recurso para administrar funciones de SELinux, como booleanos y módulos. Aquí, necesitamos ejecutar el comando semanage para administrar la configuración del puerto. Esta herramienta es parte del paquete policycoreutils-python, que no está instalado en los servidores red-hat de forma predeterminada. Para lograr lo anterior, necesitamos agregar el siguiente código dentro de la clase test-module :: http.

exec { 'semanage-port': 
   command => "semanage port -a -t http_port_t -p tcp ${httpd_port}", 
   path => "/usr/sbin", 
   require => Package['policycoreutils-python'], 
   before => Service ['httpd'], 
   subscribe => Package['httpd'], 
   refreshonly => true, 
} 

package { 'policycoreutils-python': 
   ensure => installed, 
}

El código anterior realiza lo siguiente:

  • El paquete require => ['policycoreutils-python'] asegura que tenemos el módulo de Python requerido instalado.

  • Puppet usa semanage para abrir el puerto usando httpd_port como verificable.

  • El servicio before => garantiza la ejecución de este comando antes de que se inicie el servicio httpd. Si HTTPD comienza antes del comando SELinux, SELinux falla la solicitud de servicio y la solicitud de servicio.

Finalmente, ejecute el comando de aplicación Puppet

# puppet apply test-module/tests/init.pp --noop 
... 
Notice: /Stage[main]/test-module::Httpd/Package[policycoreutilspython]/ 
ensure: current_value absent, should be present (noop) 
...
Notice: /Stage[main]/test-module::Httpd/Exec[semanage-port]/returns: 
current_value notrun, should be 0 (noop) 
... 
Notice: /Stage[main]/test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop)

Puppet instala primero el módulo de Python y luego configura el acceso al puerto y finalmente inicia el servicio httpd.

Copiar archivos HTML en el servidor web

Con los pasos anteriores hemos completado la configuración del servidor http. Ahora, tenemos una plataforma lista para instalar una aplicación basada en web, que Puppet también puede configurar. Para probar, copiaremos algunas páginas web de índice html de muestra en el servidor.

Cree un archivo index.html dentro del directorio de archivos.

<html> 
   <head> 
      <title>Congratulations</title> 
   <head> 
   
   <body> 
      <h1>Congratulations</h1> 
      <p>Your puppet module has correctly applied your configuration.</p> 
   </body> 
</html>

Cree una app.pp de manifiesto dentro del directorio de manifiestos y agregue el siguiente contenido.

class test-module::app { 
   file { "/var/www/test-server/index.html": 
      ensure => file, 
      mode => 755, 
      owner => root, 
      group => root, 
      source => "puppet:///modules/test-module/index.html", 
      require => Class["test-module::httpd"], 
   } 
}

Esta nueva clase contiene una única desaceleración de recursos. Esto copia un archivo del directorio de archivos del módulo al servidor web y establece sus permisos. El atributo requerido asegura que la clase test-module :: http complete la configuración con éxito antes de que se aplique test-module :: app.

Finalmente, necesitamos incluir un nuevo manifiesto en nuestro manifiesto init.pp principal.

class test-module ( 
   $http_port = 80 
) { 
   include test-module::httpd 
   include test-module::app 
}

Ahora, ejecute el comando apply para probar realmente lo que está sucediendo. Lo siguiente será la salida.

# puppet apply test-module/tests/init.pp --noop
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera 
defaults 

Notice: Compiled catalog for brcelprod001.brcle.com in environment 
production in 0.66 seconds 

Notice: /Stage[main]/Test-module::Httpd/Exec[iptables]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/Test-module::Httpd/Package[policycoreutilspython]/ 
ensure: current_value absent, should be present (noop) 

Notice: /Stage[main]/Test-module::Httpd/Service[iptables]: Would have 
triggered 'refresh' from 1 events 

Notice: /Stage[main]/Test-module::Httpd/File[/var/www/myserver]/ensure: 
current_value absent, should be directory (noop) 

Notice: /Stage[main]/Test-module::Httpd/Package[httpd]/ensure: 
current_value absent, should be present (noop) 

Notice: 
/Stage[main]/Test-module::Httpd/File[/etc/httpd/conf.d/myserver.conf]/ensur 
e: current_value absent, should be file (noop) 

Notice: /Stage[main]/Test-module::Httpd/Exec[semanage-port]/returns: 
current_value notrun, should be 0 (noop) 

Notice: /Stage[main]/Test-module::Httpd/Service[httpd]/ensure: 
current_value stopped, should be running (noop) 

Notice: Class[test-module::Httpd]: Would have triggered 'refresh' from 8 
Notice: 
/Stage[main]/test-module::App/File[/var/www/myserver/index.html]/ensur: 
current_value absent, should be file (noop) 

Notice: Class[test-module::App]: Would have triggered 'refresh' from 1 
Notice: Stage[main]: Would have triggered 'refresh' from 2 events Notice: 
Finished catalog run in 0.74 seconds

La línea resaltada muestra el resultado de la copia del archivo index.html en el servidor web.

Finalizando el Módulo

Con todos los pasos anteriores, nuestro nuevo módulo que creamos está listo para usar. Si queremos crear un archivo del módulo, lo podemos hacer usando el siguiente comando.

# puppet module build test-module