= playbooks == 2.11 introducción Playbooks * lista de jugadas (tareas) en una lista de servidores * configuraciones y variables * formato YAML:--- - name: Mi primer playbook hosts: all remote_user: become: true # a nivel de playbook, se podría hacer a nivel de tarea tasks: - name: copiar ficheros hosts copy: src=/etc/hosts dest=/etc/host - name: ... service: ... * cada guión es un playbook, puede haber varios en un fichero * **name** es opcional, pero recomendado * ''ansible-playbook [-i inventario] [ociones] playbook.yml'' == 2.12 Esenciales * hosts: lista de servidores a administrar (grupos o servidores) * si se quieren separar, usar **%%:%%** * se puede usar **&** para que estén en 2 grupos a la vez * se puede usar **!** hosts: serweb # un grupo, afecta a todas las máquinas hosts: serweb:&barcelona # dos grupos, solo los que pertenecen a los dos grupos a la vez se verán afectados hosts: serweb:!madrid # 2 grupos, solo los que pertenezcan al primero y no estén en el segundo se verán afectados hosts: serweb:dbweb # afecta a los dos grupos # usamos el inventario del directorio inventarios # usamos el fichero miPlaybook.yml # usamos --lists-hosts para ver a que servidores afectará ansible-playbook -i inventarios/ miPlaybook.yml --list-hosts # solo serweb+barcelona ansible-playbook -i --limit 'serweb:&barcelona' inventarios/ miPlaybook.yml --list-hosts * remote_user: * become: [True|False] | [1|0] * become_user: (que queremos usar) * become_method: sudo/su/pbrun/ksu * check_mode: [True|False] -> simulación == 2.13 ansible-playbook ''ansible-playbook [opiones] fichero.yml'' * opciones: * ''-i'' : especificar un inventario (fuera de **/etc/ansible/hosts**) * ''--syntax-check'' * ''--list-tasks'' * ''--list-hosts'' * ''--step'' : confirmar cada una de las tareas, cada uno de los playbooks * ''--start-at-task='' : permite saltarse tareas, le indicamos a partir de cual * ''--forks|[-f]%%=#%%'' : número de tareas en paralelo a ejecutar (por defecto, 5) * ''-v | -vv | -vvv'' : más verbosidad == 2.14 Variables * dinamización de tareas * pueden ser definidas en: * **facts** : obtenidos del servidor (sobre el que aplicamos la configuración) * **playbook** * **línea de comandos** : ''-e'' -> clave=valor * se pueden usar en: * tareas * plantillas (lógica) * otros (condiciones, bucles, roles, etc..) * uso:%%''{{variable}}''%% (con dobles comillas, dobles llaves) === ejemplo template sencillo, definimos una variable propia y las otras dos las da el propio servidor {{ miip }} {{ ansible_hostname}} {{ ansible_fqdn }} - name: crear ficher usando variables hosts: localhost connection: local vars: - miip: "1.2.3.4" tasks: - name: Crear fichero hosts template: src=hosts.j2 dest=/tmp/hosts ansible-playbook playbook.yml # el módulo template se encarga de buscar el fichero que necesita y hacer las sustituciones ansible localhost -m setup | grep -e ansible_hostname -e ansible_fqdn ansible-playbook -e miip="5.6.7.8" playbook.yml == 2.15 Sintaxis * formato YAML: * simplifica definición playbooks * diferentes opciones para mejorar la legbilidad === ejemplos * partir línea de configuración larga: - name: copiar fichero copy: src=/etc/hosts dest=/etc/hosts owner=root group=root mode=0644 - name: copiar fichero copy: src: /etc/hosts dest: /etc/hosts owner: root group: root mode: 0644 * definir lista de variables: - instalar: - apache - php5 - mariadb - instalar: ["apache","php5","mariadb"] * definir diccionario: - instalar: web: apache2 bd: mariadb script: php5 -instalar: {web:"apache", bd:"mariadb",script:"php5"} para hacer referencia, se usará ''instalar.web'' o ''instalar.script'' * texto / líneas de texto largas - texto_largo: | primera linea segunda linea - linea_larga: > primera parte segunda parte * módulo **debug** : muestra un texto o un valor de una variable - debug: var=miip - debug: var=texto_largo - debug: linea_larga - debug: instalar.web == 2.16 Handlers es una tarea que se ejecuta solo cuando la llama otra tarea - tasks: - name: configurar sshd.config copy: src=sshd_config dest=/etc/sshd.config notify: reiniciar_sshd - handlers: - name: reinicar_sshd service: name=sshd state=restarted los **handlers** se ejecutan al final de las tareas del **playbook** == 2.17 Include y Roles === include * dividir el distintas partes para facilitar edición y tratado * **include** permite añadir otro fichero que contiene un playbook o una tarea ==== ejemplos * inclusión de una tarea: - name: primer playbook hosts: servweb tasks: - name: tarea de este fichero apt: name=apache2 state=latest - include: otra_tarea.yml - name: tarea en fichero anexo service: name=nombre state=started * inclusión de otro playbook: - name: primer playbook hosts: servweb tasks: - name: tarea de este fichero apt: name=apache2 state=latest - name: Segundo playbook include: segundo_playbook.yml - hosts: servweb tasks: - name: tarea de este fichero apt: name=vim state=latest === roles * estructura de ficheros y directorios para separar los elementos * permite ser reusados facilmente * es posible descargar roles predefinidos : Ansible Galaxy * roles/ * / * files/ * templates/ * tasks/main.yml <-- único obligatorio * handlers/main.yml * vars/main.yml * defaults/main.yml * meta/main.yml * uso en el playbook: - roles: - rol1 - rol2 - roles: - {role: rol1, clave: valor} - rol2 == 2.18 Templates * instrucciones en tamplates: * expresiones: {{ variable }} * control: {% ... %} * condicional:{% if ansible_distribution == "Debian" %} si se cumple la condición {% endif %} * bucle:{% for usuario in lista_usuarios %} {{ usuario }} {% endfor %} lista_usuarios: ["root","alberto","www-data"] roles: - { role: apache2, lista_usuarios: ["usuario1","root1"] } * comentarios: {# comentario #} == 2.19 Prioridad variables en orden de menos a mas - **Defaults** dentro de un **rol** - variables de grupo (inventario->group_vars/all->group_vars/) - variables de servidor (inventario->host_vars/) - **facts** del servidor - variables del **playbook** (->vars_prompt->vars_files) - variables del **rol** (definidas en /roles//vars/main.yml) - variables de bloque -> variables de tareas - parámetros **rol** -> include_parvars -> include_vars - set_facts / registered_vars - extra vars -> ''-e'' == 2.20 Condiciones se puede condicionar: * ejecución de una tarea * inclusión de un fichero * el uso de un rol usando la expresión ''when'' - name: instalar apache2 apt: name=apache2 state=latest when: ansible_distribution == "Debian" - name: instalar apache2 apt: name=apache2 state=latest when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu" - name: Instalar apache2 include: instalar-apache2.yml when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu" - name: Instalar httpd include: instalar-httpd.yml when: ansible_distribution == "CentOS" - { role: apache2, when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu" } - { role: apache2, when: ansible_distribution == "CentOS" } == 2.21 Bucles ya vimos como usarlo en las plantillas () ahora en tareas (palabra clave): ''with_items'' - name: Instalar soft necesario apt: name={{ item }} state=latest with_items: - mariadb - php5 - phpmyadmin - name: Crear usuarios user: name={{ item.nombre }} state=present groups={{ item.grupo }} with_items: - {nombre: usuario1, grupo: www-data} - {nombre: usuario2, grupo: www-data} /defaults/main.yml)> - name: Instalar paquetes apt: {{ item }} with_items: "{{ lista_paquetes }}" - name: Crar usuarios user: {{ item }} with_items: "{{ dic_usuarios }}" lista_paquetes: ["php5","phpmyadmin","mysql-server"] dic_usuarios: - {nombre: "usuario1", grupo: "www-data"} - {nombre: "usuario2", grupo: "www-data"} == 2.22 Register ''register'' nos permite guardar en una varibale el resultado de la acción realizada por un módulo en una tarea - name: ejecutar comando command: uptime register: salida_uptime - name: mostrar uptime debug: var=salida[.stdout] los valores devueltos son: * changed * failed * skipped * rc * == 0 -> OK * != 0 -> KO * stdout / stderr / stdout_lines / stderr_lines * en lines se podría rehusar como bucle y se pueden usar esos estados para filtrar la ejecución de otras tareas - name: copiar fichero index.html template: src=index.html.j2 dest=/var/www/html/index.html register: out_copia - name: mostrar contenido command: cat /var/www/html/index.html register: out_salida when: out_copia|changed - debug: var=out_copia.stdout when: out_copia|changed == 2.23 Ignore Errors las tareas erróneas paran el playbook, usando ''ignore_errrors = True'' evitamos que la tarea errónea pare la ejecución - name: comprobar si fichero existe command: ls /noexiste.conf registar: existe ignore_errors = true - name: mostrar errores debug: var=existe.stderr_lines se puede usar a nivel de tarea o de playbook <- CUIDADO! todos los errores serán ignorados se pueden usar condicionales ''not |failed'' para realizar tareas complementarias en caso de error - name: mostrar salida debug: var=existe.stdout_lines when: not salida|failed [ when: salida|failed != False ] # expresión equivalente - name: mostrar errores debug: var=existe.stderr_lines when: salida|failed == 2.24 Failed When ''failed_when'' o ''changed_when'' permiten especificar las condiciones para marcar una tarea como fallida o cambiada, respectivamente un comando es marcado como erróneo si su **rc** (return code) es != 0 -> ''$?'' - name: ejecutar comando command: ip a - name: ejecutar comando command: ip a register: salida failed_when: "'eth2' not in salida.stdout" - name: no marcar nunca como cambiado command: uptime changed_when: False se pueden combinar en la misma tarea juntas