Ejemplo 4: Añadir control de flujo - AWS OpsWorks

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Ejemplo 4: Añadir control de flujo

importante

El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los actuales. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en AWS Re:post o a través de Premium AWS Support.

Algunas recetas son simplemente una serie de recursos de Chef. En dicho caso, al ejecutar la receta, esta se limita a ejecutar en secuencia cada uno de los proveedores de recursos. Sin embargo, a menudo es útil disponer de una ruta de ejecución más sofisticada. A continuación, mostramos dos situaciones que se producen con frecuencia:

  • Quiere que una receta ejecute el mismo recurso varias veces con diferentes valores de atributo.

  • Quiere utilizar diferentes valores de atributo en sistemas operativos distintos.

Puede abordar ambas situaciones incorporando estructuras de control de Ruby en la receta. En esta sección se muestra cómo modificar la receta del Ejemplo 3: Creación de directorios para encarar ambos casos.

Iteración

En el Ejemplo 3: Creación de directorios se mostraba cómo utilizar un recurso directory para crear un directorio o una cadena de directorios. Sin embargo, supongamos que desee crear dos directorios diferentes, /srv/www/config y /srv/www/shared. Podría implementar un recurso de directorio diferente para cada directorio, pero este enfoque puede ser demasiado laborioso si desea crear muchos directorios. En la receta siguiente se muestra una forma más sencilla de gestionar la tarea.

[ "/srv/www/config", "/srv/www/shared" ].each do |path| directory path do mode 0755 owner 'root' group 'root' recursive true action :create end end

En lugar de utilizar un recurso de directorio diferente para cada subdirectorio, la receta utiliza una recopilación de cadenas que contienen las rutas de subdirectorio. El método each de Ruby ejecuta el recurso una vez por cada elemento de recopilación, empezando por el primero. El valor del elemento está representado en el recurso por la variable path, que en este caso representa la ruta del directorio. Es fácil adaptar este ejemplo para crear cualquier cantidad de subdirectorios.

Para ejecutar la receta
  1. Quédese en el directorio createdir; utilizará ese libro de recetas en los siguientes ejemplos.

  2. Si aún no lo ha hecho, ejecute kitchen destroy para empezar con una instancia limpia.

  3. Sustituya el código de default.rb por el ejemplo y ejecute kitchen converge.

  4. Inicie sesión en la instancia, verá los directorios recién creados en /srv.

Puede utilizar una tabla hash para especificar dos valores para cada iteración. La receta siguiente crea /srv/www/config y /srv/www/shared, cada uno con un modo diferente.

{ "/srv/www/config" => 0644, "/srv/www/shared" => 0755 }.each do |path, mode_value| directory path do mode mode_value owner 'root' group 'root' recursive true action :create end end
Para ejecutar la receta
  1. Si aún no lo ha hecho, ejecute kitchen destroy para empezar con una instancia limpia.

  2. Sustituya el código de default.rb por el ejemplo y ejecute kitchen converge.

  3. Inicie sesión en la instancia; verá los directorios recién creados en /srv con los modos especificados.

nota

AWS OpsWorks Las recetas de Stacks suelen utilizar este enfoque para extraer valores del JSON de configuración e implementación de la pila (que básicamente es una gran tabla de hash) e insertarlos en un recurso. Para ver un ejemplo, consulte Recetas de implementación.

Lógica condicional

También puede utilizar la lógica condicional de Ruby para crear varias ramas de ejecución. La siguiente receta utiliza la lógica if-elsif-else para ampliar el ejemplo anterior y crear un subdirectorio denominado /srv/www/shared, aunque solo en sistemas Debian y Ubuntu. En cuanto al resto los de sistemas, registra un mensaje de error que se muestra en la salida de Test Kitchen.

if platform?("debian", "ubuntu") directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end
Para ejecutar la receta del ejemplo
  1. Si la instancia sigue estando activa, ejecute kitchen destroy para cerrarla.

  2. Sustituya el código de default.rb por el código del ejemplo.

  3. Edite .kitchen.yml para añadir un sistema CentOS 6.4 a la lista de plataformas. La sección platforms del archivo debe parecerse a lo siguiente.

    ... platforms: - name: ubuntu-12.04 - name: centos-6.4 ...
  4. Ejecute kitchen converge, lo que creará una instancia y ejecutará las recetas para cada plataforma de .kitchen.yml, en secuencia.

    nota

    Si desea converger solo una instancia, añada el nombre de la instancia como parámetro. Por ejemplo, para converger la receta únicamente en la plataforma Ubuntu, ejecute kitchen converge default-ubuntu-1204. Si no recuerda los nombres de plataforma, ejecute kitchen list.

Deberá ver el mensaje de registro en la parte CentOS de la salida de Test Kitchen, que tendrá un aspecto similar al siguiente:

... Converging 1 resources Recipe: createdir::default * log[Unsupported system] action write[2014-06-23T19:10:30+00:00] INFO: Processing log[Unsupported system] action write (createdir::default line 12) [2014-06-23T19:10:30+00:00] INFO: Unsupported system [2014-06-23T19:10:30+00:00] INFO: Chef Run complete in 0.004972162 seconds

Ahora puede iniciar sesión en las instancias y verificar si los directorios se han creado o no. Sin embargo, ahora no puede limitarse a ejecutar kitchen login. Debe especificar la instancia anexando el nombre de la plataforma; por ejemplo, kitchen login default-ubuntu-1204.

nota

Si un comando de Test Kitchen toma el nombre de una instancia, no es necesario escribir el nombre completo. Test Kitchen trata el nombre de una instancia como una expresión regular de Ruby, por lo que solo necesita los suficientes caracteres para proporcionar una coincidencia única. Por ejemplo, puede converger solo la instancia de Ubuntu ejecutando kitchen converge ub o iniciando sesión en la instancia de CentOS ejecutando kitchen login 64.

Probablemente se esté preguntando cómo sabe la receta en qué plataforma se está ejecutando. Chef ejecuta una herramienta llamada Ohai por cada ejecución que recopila datos del sistema, incluida la plataforma, y los representa como un conjunto de atributos en una estructura denominada el objeto de nodo. El método platform? de Chef compara los sistemas que están entre paréntesis con el valor de la plataforma Ohai y devuelve true si uno de ellos coincide.

Puede hacer referencia al valor de un atributo de nodo directamente en su código usando node['attribute_name']. El valor de la plataforma, por ejemplo, está representado por node['platform']. Podría, por ejemplo, haber escrito el ejemplo anterior tal y como se indica a continuación.

if node[:platform] == 'debian' or node[:platform] == 'ubuntu' directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end

Por lo general, una lógica condicional se incluye en una receta para tener en cuenta el hecho de que las diferentes familias de Linux a veces utilizan denominaciones distintas para paquetes, directorios, etc. Por ejemplo, el nombre del paquete Apache es httpd en los sistemas CentOS y apache2 en los sistemas Ubuntu.

Si solo necesita una cadena diferente para diferentes sistemas, el método value_for_platform de Chef es una solución más sencilla que if-elsif-else. En la siguiente receta se crea un directorio /srv/www/shared en los sistemas CentOS, un directorio /srv/www/data en los sistemas Ubuntu y /srv/www/config en todos los demás.

data_dir = value_for_platform( "centos" => { "default" => "/srv/www/shared" }, "ubuntu" => { "default" => "/srv/www/data" }, "default" => "/srv/www/config" ) directory data_dir do mode 0755 owner 'root' group 'root' recursive true action :create end

value_for_platform asigna la ruta apropiada a data_dir y el recurso directory utiliza dicho valor para crear el directorio.

Para ejecutar la receta del ejemplo
  1. Si la instancia sigue estando activa, ejecute kitchen destroy para cerrarla.

  2. Sustituya el código de default.rb por el código del ejemplo.

  3. Ejecute kitchen converge y, a continuación, inicie sesión en cada instancia para verificar que contengan los directorios adecuados.