informatica:ciberseguridad:cursos:curso_ansible_automatizacion_it:conceptos_avanzados
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:ciberseguridad:cursos:curso_ansible_automatizacion_it:conceptos_avanzados [2023/05/08 18:03] – [Tareas, Plays y Playbooks II] tempwin | informatica:ciberseguridad:cursos:curso_ansible_automatizacion_it:conceptos_avanzados [2023/05/08 21:32] (actual) – [Templates I] tempwin | ||
|---|---|---|---|
| Línea 143: | Línea 143: | ||
| * Deben comenzar con letra | * Deben comenzar con letra | ||
| * Pueden contener letras, números y guiones bajos. | * Pueden contener letras, números y guiones bajos. | ||
| + | |||
| ===== Tareas, Plays y Playbooks I ===== | ===== Tareas, Plays y Playbooks I ===== | ||
| Línea 277: | Línea 278: | ||
| < | < | ||
| - | ansible-playbook primer_playbook.yaml --syntax-check | + | ansible-playbook |
| </ | </ | ||
| + | |||
| + | Vemos que falla porque no el usuario no tiene permisos para instalar el paquete '' | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=present | ||
| + | </ | ||
| + | |||
| + | En la máquina destino, tenemos que evitar que pida la contraseña el usar '' | ||
| + | |||
| + | < | ||
| + | %sudo ALL=(ALL) NOPASSWD: ALL | ||
| + | </ | ||
| + | |||
| + | Modificamos más el playbook para incluir variables: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: absent | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state={{ state }} | ||
| + | </ | ||
| + | |||
| + | Lo que añadamos entre llaves ('' | ||
| + | |||
| + | <code yaml> | ||
| + | apt: name=nginx state=absent | ||
| + | </ | ||
| + | |||
| + | Si ejecutamos ahora ese playbook, desinstalará nginx. | ||
| ===== Qué son los handlers y para qué se usan ===== | ===== Qué son los handlers y para qué se usan ===== | ||
| + | |||
| + | Los **handlers** son tareas especiales que se ejecutan al final de una play si son notificadas por otra tarea cuando ocurre un cambio. | ||
| + | |||
| + | <code yaml> | ||
| + | tasks: | ||
| + | - name: httpd package is present | ||
| + | yum: | ||
| + | name: httpd | ||
| + | state: latest | ||
| + | notify: restart httpd | ||
| + | | ||
| + | - name: latest index.html file is present | ||
| + | copy: | ||
| + | src: files/ | ||
| + | dest: / | ||
| + | | ||
| + | handlers: | ||
| + | - name: restart httpd | ||
| + | service: | ||
| + | name: httpd | ||
| + | state: restarted | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Los handlers se definen al final del Playbook | ||
| + | </ | ||
| + | |||
| + | Seguimos trabajando con nuestro playbook: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Lo ejecutamos: | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | Si observamos el resultado, vemos que el servidor web nginx se reinicia, pero esto no nos interesa. Queremos que se reinicie solo cuando sea necesario. Aquí entran en escena los **handlers**: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Si lanzamos ahora el playbook, conseguiremos que solo se reinice nginx cuando se instale. | ||
| + | |||
| + | Vamos a pasar variables por línea de comando con la opción '' | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | Ansible, en lugar de usar la varible '' | ||
| ===== Condicionales ===== | ===== Condicionales ===== | ||
| + | |||
| + | Ansible permite incluir condiciones a la hora de ejecutar las tareas basándose en la evaluación de una variable, fact u otra tarea previa en tiempo de ejecución. | ||
| + | |||
| + | <code yaml> | ||
| + | --- | ||
| + | - name: install Apache webserver | ||
| + | hosts: all | ||
| + | tasks: | ||
| + | - name: Install Apache on Ubuntu Server | ||
| + | apt: name=apache2 state=present | ||
| + | become: yes | ||
| + | when: ansible_os_family == " | ||
| + | </ | ||
| + | |||
| + | Trabajando con nuestro '' | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | when: ansible_os_family == " | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo 60%> | ||
| + | Poner ejemplo de salida | ||
| + | </ | ||
| + | |||
| + | Veremos ahora el uso de condicionales utilizando una variable que hemos usado como salida de una tarea: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo 60%> | ||
| + | Poner ejemplo de salida de ejecución del anterior playbook | ||
| + | </ | ||
| ===== Tags ===== | ===== Tags ===== | ||
| + | |||
| + | Los //tags// permiten ejecutar un subconjunto de tareas en un playbook. | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Lo ejecutamos añadiendo la opción '' | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo 60%> | ||
| + | Poner ejemplo de salida del comando anterior. | ||
| + | </ | ||
| + | |||
| + | También podríamos incluir //tags// en una play entera: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo 60%> | ||
| + | Poner ejemplo de salida del comando anterior. | ||
| + | </ | ||
| ===== Templates I ===== | ===== Templates I ===== | ||
| + | |||
| + | Ansible integra el motor de // | ||
| + | |||
| + | * Fijar y modificar variables | ||
| + | * Utilizar lógica condicional | ||
| + | * Generar ficheros de configuración utilizando variables | ||
| + | |||
| + | Insertar una variable: | ||
| + | |||
| + | < | ||
| + | INTERFACES=" | ||
| + | </ | ||
| + | |||
| + | Iterar sobre una lista: | ||
| + | |||
| + | < | ||
| + | search ws.nsrc.org | ||
| + | {$ for host in use_dns_servers %} | ||
| + | nameserver {{ host }} | ||
| + | {% endfor %} | ||
| + | </ | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | Se puede probar jinga online por ejemplo desde este [[http:// | ||
| + | </ | ||
| + | |||
| + | Jinja2 permite utilizar [[https:// | ||
| ===== Templates II ===== | ===== Templates II ===== | ||
| + | |||
| + | Usaremos jinja2 con Ansible. Vamos a crear un fichero '' | ||
| + | |||
| + | < | ||
| + | Hola! | ||
| + | |||
| + | Nginx en la versión {{ version }} se está ejecutando en {{ servidor }} | ||
| + | </ | ||
| + | |||
| + | Modificamos nuestro Playbook para añadir una tercera play: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: no | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.js # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Revisamos sintaxis: | ||
| + | |||
| + | < | ||
| + | ansible-playbook --syntax-check primer_playbook.yaml | ||
| + | </ | ||
| + | |||
| + | Lanzamos el playbook centrándonos en la última play que hemos hecho: | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | Si todo ha funcionado bien, se habrá creado el fichero ''/ | ||
| + | |||
| + | < | ||
| + | Hola! | ||
| + | |||
| + | Nginx en la versión 5.13 se está ejecutando en Ubuntu. | ||
| + | </ | ||
| + | |||
| + | Vamos a añadir más variables en la tercera play: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: no | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Creamos la plantilla '' | ||
| + | |||
| + | < | ||
| + | La lista de coches contiene las siguientes marcas: | ||
| + | |||
| + | {% for item in coches %} | ||
| + | |||
| + | {{ item }} | ||
| + | {% endfor %} | ||
| + | </ | ||
| + | |||
| + | Revisamos sintaxis: | ||
| + | |||
| + | < | ||
| + | ansible-playbook --syntax-check primer_playbook.yaml | ||
| + | </ | ||
| + | |||
| + | Lanzamos el playbook centrándonos en la última play que hemos hecho: | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | En el equipo destino tendremos un nuevo archivo ''/ | ||
| + | |||
| + | < | ||
| + | La lista de coches contiene las siguientes marcas: | ||
| + | |||
| + | Mercedes | ||
| + | | ||
| + | Nissan | ||
| + | | ||
| + | Renault | ||
| + | | ||
| + | Ford | ||
| + | </ | ||
| + | |||
| + | Si no queremos el espacio tras cada elemento, usaríamos un guion antes del cierre del foreach: | ||
| + | |||
| + | < | ||
| + | {%- endfor %} | ||
| + | </ | ||
| + | |||
| + | Si queremos que se transforme el texto a todo mayúscula, podemos usar el filtro '' | ||
| + | |||
| + | < | ||
| + | La lista de coches contiene las siguientes marcas: | ||
| + | |||
| + | {% for item in coches %} | ||
| + | |||
| + | {{ item | upper }} | ||
| + | {% endfor %} | ||
| + | </ | ||
| + | |||
| + | Finalmente, veremos inyección de variables en código HTML. Creamos el fichero '' | ||
| + | |||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | En nuestro Playbook vamos a añadir una tercera tarea en la tercera play: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: ls | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: yes # para tener permisos para escribir en la carpeta del servidor web | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | - name: mostrar un nuevo fichero index | ||
| + | | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Revisamos sintaxis: | ||
| + | |||
| + | < | ||
| + | ansible-playbook --syntax-check primer_playbook.yaml | ||
| + | </ | ||
| + | |||
| + | Lanzamos el playbook centrándonos en la última play que hemos hecho: | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| ===== Bloques y gestión de errores ===== | ===== Bloques y gestión de errores ===== | ||
| + | |||
| + | Los bloques crean grupos lógicos de tareas y además permiten gestionar errores. | ||
| + | |||
| + | Para ignorar errores podemos usar la etiqueta '' | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios | ||
| + | command: lz # Ponemos un comando incorrecto a propósito | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | ignore_errors: | ||
| + | | ||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: yes # para tener permisos para escribir en la carpeta del servidor web | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | - name: mostrar un nuevo fichero index | ||
| + | | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Al ejecutar, dará error cuando llegue a " | ||
| + | |||
| + | Vamos a crear dos bloques en nuestro playbook: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios y comprobar ficheros | ||
| + | block: | ||
| + | - name: listar directorios | ||
| + | command: lz # Ponemos un comando incorrecto a propósito | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | |||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | |||
| + | - name: instalar nginx y copiar index | ||
| + | block: | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: yes # para tener permisos para escribir en la carpeta del servidor web | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | - name: mostrar un nuevo fichero index | ||
| + | | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Vamos a hacer también una gestión más inteligente de los errores con la etiqueta '' | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios y comprobar ficheros | ||
| + | block: | ||
| + | - name: listar directorios | ||
| + | command: lz # Ponemos un comando incorrecto a propósito | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | |||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | |||
| + | |||
| + | rescue: | ||
| + | - name: listar directorios | ||
| + | commando: ls | ||
| + | |||
| + | |||
| + | - name: instalar nginx y copiar index | ||
| + | block: | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: yes # para tener permisos para escribir en la carpeta del servidor web | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | - name: mostrar un nuevo fichero index | ||
| + | | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Cuando ejecutamos el playbook, al llegar al bloque " | ||
| + | |||
| + | También podríamos usar la etiqueta '' | ||
| + | |||
| + | <code yaml> | ||
| + | ... | ||
| + | tasks: | ||
| + | - name: listar directorios y comprobar ficheros | ||
| + | block: | ||
| + | - name: listar directorios | ||
| + | command: lz # Ponemos un comando incorrecto a propósito | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | |||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | |||
| + | rescue: | ||
| + | - name: listar directorios | ||
| + | commando: ls | ||
| + | |||
| + | always: | ||
| + | - name: mensaje de always | ||
| + | debug: | ||
| + | msg: "Este código se ejecuta siempre" | ||
| + | </ | ||
| ===== Bucles ===== | ===== Bucles ===== | ||
| + | Los bucles se usan para realizar una tarea múltiples veces, como por ejemplo crear muchos usuarios, instalar varios paquetes, etc. | ||
| + | |||
| + | Se emplea la palabra reservada '' | ||
| + | |||
| + | Vamos a modificar la primera play de nuestro playbook de ejemplo: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | # gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: echo items | ||
| + | command: echo "{{ item }}" | ||
| + | loop: | ||
| + | - uno | ||
| + | - dos | ||
| + | |||
| + | - name: segunda play | ||
| + | hosts: servidor_web | ||
| + | become: yes | ||
| + | tags: segunda_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | - name: listar directorios y comprobar ficheros | ||
| + | block: | ||
| + | - name: listar directorios | ||
| + | command: lz # Ponemos un comando incorrecto a propósito | ||
| + | register: contenido # registro de la salida de ' | ||
| + | tags: | ||
| + | - listar | ||
| + | |||
| + | - name: comprobar ficheros | ||
| + | debug: | ||
| + | msg: "El directorio no está vacío" | ||
| + | when: contenido.stdout != "" | ||
| + | |||
| + | |||
| + | rescue: | ||
| + | - name: listar directorios | ||
| + | commando: ls | ||
| + | |||
| + | |||
| + | - name: instalar nginx y copiar index | ||
| + | block: | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: copiar index | ||
| + | copy: | ||
| + | src: index.html | ||
| + | dest: / | ||
| + | |||
| + | |||
| + | - name: tercera play | ||
| + | hosts: all | ||
| + | become: yes # para tener permisos para escribir en la carpeta del servidor web | ||
| + | tags: tercera_play | ||
| + | vars: | ||
| + | version: " | ||
| + | servidor: " | ||
| + | coches: [" | ||
| + | |||
| + | tasks: | ||
| + | - name: imprimir template | ||
| + | template: | ||
| + | src: template_ejemplo.j2 # fichero con template Jinja2 | ||
| + | dest: / | ||
| + | |||
| + | - name: ejemplo loop con templates | ||
| + | template: | ||
| + | src: template_ejemplo_2.j2 | ||
| + | dest: / | ||
| + | |||
| + | - name: mostrar un nuevo fichero index | ||
| + | | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Al ejecutar el playbook, veremos en la salida que se muestra esos dos elementos (uno y dos) para cada uno de los equipos del inventario. | ||
| + | |||
| + | Añadimos más cosas: | ||
| + | |||
| + | <code yaml> | ||
| + | (...) | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: echo items | ||
| + | command: echo "{{ item }}" | ||
| + | loop: | ||
| + | - uno | ||
| + | - dos | ||
| + | |||
| + | - name: listar inventario | ||
| + | debug: | ||
| + | msg: "{{ item }}" | ||
| + | loop: "{{ groups[' | ||
| + | |||
| + | (...) | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo 60%> | ||
| + | Mostrar salida del comando anterior | ||
| + | </ | ||
| + | |||
| + | Vamos a usar ahora diccionarios: | ||
| + | |||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | hosts: all | ||
| + | become: yes | ||
| + | gather_facts: | ||
| + | | ||
| + | tasks: | ||
| + | - name: comprobar conexión | ||
| + | ping: | ||
| + | data: funcionando | ||
| + | |||
| + | - name: echo items | ||
| + | command: echo "{{ item }}" | ||
| + | loop: | ||
| + | - uno | ||
| + | - dos | ||
| + | |||
| + | - name: listar inventario | ||
| + | debug: | ||
| + | msg: "{{ item }}" | ||
| + | loop: "{{ groups[' | ||
| + | | ||
| + | - name: crear usuarios | ||
| + | user: | ||
| + | name: "{{ item.name }}" | ||
| + | state: present | ||
| + | groups: "{{ item.groups }}" | ||
| + | loop: | ||
| + | - { name: ' | ||
| + | - { name: ' | ||
| + | | ||
| + | (...) | ||
| + | </ | ||
| + | |||
| + | Revisamos sintaxis: | ||
| + | |||
| + | < | ||
| + | ansible-playbook --syntax-check primer_playbook.yaml | ||
| + | </ | ||
| + | |||
| + | Lanzamos el playbook centrándonos en la última play que hemos hecho: | ||
| + | |||
| + | < | ||
| + | ansible-playbook -i / | ||
| + | </ | ||
| + | |||
| + | Si vamos al equipo/s destino, se habrían creado los usuarios '' | ||
| + | |||
| + | Si quisiéramos eliminar los usarios, cambiaríamos el valor de '' | ||
| + | |||
| + | <code yaml> | ||
| + | (...) | ||
| + | - name: crear usuarios | ||
| + | user: | ||
| + | name: "{{ item.name }}" | ||
| + | state: absent | ||
| + | groups: "{{ item.groups }}" | ||
| + | loop: | ||
| + | - { name: ' | ||
| + | - { name: ' | ||
| + | (...) | ||
| + | </ | ||
| ===== Qué son los Roles en Ansible ===== | ===== Qué son los Roles en Ansible ===== | ||
| + | Los roles permiten organizar, paquetizar y reusar nuestro código de forma más práctica. | ||
| + | |||
| + | Tendríamos una estructura de carpetas donde incluiremos los roles que queramos. | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| ===== Creando nuestro primer Rol ===== | ===== Creando nuestro primer Rol ===== | ||
| + | |||
| + | Crearemos la carpeta principal '' | ||
| + | |||
| + | < | ||
| + | mkdir roles | ||
| + | </ | ||
| + | |||
| + | Dentro de ella, vamos a crear el rol '' | ||
| + | |||
| + | < | ||
| + | mkdir nginx | ||
| + | </ | ||
| + | |||
| + | Dentro de '' | ||
| + | |||
| + | < | ||
| + | mkdir defaults files handlers tasks templates | ||
| + | </ | ||
| + | |||
| + | Por tanto, si nos vamos al directorio padre, tendríamos la siguiente estructura de carpetas: | ||
| + | |||
| + | < | ||
| + | ├── roles | ||
| + | │ └── nginx | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | </ | ||
| + | |||
| + | Partimos del siguiente playbook: | ||
| + | <code yaml> | ||
| + | # Este es nuestro primer playbook | ||
| + | - name: primera play | ||
| + | become: yes | ||
| + | hosts: servidor_web | ||
| + | tags: primera_play | ||
| + | gather_facts: | ||
| + | vars: | ||
| + | state: present | ||
| + | | ||
| + | tasks: | ||
| + | |||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: crear index | ||
| + | template: | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | - name: copiar script | ||
| + | copy: | ||
| + | src: simple_script.sh | ||
| + | dest: / | ||
| + | |||
| + | | ||
| + | - name: reiniciar nginx | ||
| + | | ||
| + | name: nginx | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Vamos a mover los distintos elemenos de ese playbooks a donde deben estar. Por ejemplo, las tareas irán a '' | ||
| + | |||
| + | <code yaml> | ||
| + | --- | ||
| + | - name: instalar nginx | ||
| + | apt: name=nginx state=" | ||
| + | notify: reiniciar nginx # Mismo nombre que el handler | ||
| + | | ||
| + | - name: crear index | ||
| + | template: | ||
| + | src: template_ejemplo_3.j2 | ||
| + | dest: / | ||
| + | mode: 0755 | ||
| + | |||
| + | - name: copiar script | ||
| + | copy: | ||
| + | src: simple_script.sh | ||
| + | dest: / | ||
| + | </ | ||
| + | |||
| + | Colocaremos ahora el template que usamos en el Playbook ('' | ||
| + | |||
| + | Hacemos lo mismo con el script '' | ||
| + | |||
| + | Ahora es el turno de los handlers. Añadiremos un fichero '' | ||
| + | |||
| + | <code yaml> | ||
| + | --- | ||
| + | - name: reiniciar nginx | ||
| + | service: | ||
| + | name: nginx | ||
| + | state: restarted | ||
| + | </ | ||
| + | |||
| + | Nos quedan las variables, crearemos el fichero '' | ||
| + | |||
| + | <code yaml> | ||
| + | --- | ||
| + | state: present | ||
| + | </ | ||
| + | |||
| + | Nos falta incluir este nuevo rol en algún sitio. En la carpeta raíz, creamos uno llamado, por ejemplo, '' | ||
| + | |||
| + | <code yaml> | ||
| + | --- | ||
| + | - hosts: web # Solo aplicamos a uno de los hosts | ||
| + | become: yes | ||
| + | roles: | ||
| + | - nginx # Rol que vamos a incluir | ||
| + | </ | ||
| + | |||
| + | Algo tarde, pero no es mal momento para comentar que podemos crear un fichero de configuración de Ansible: '' | ||
| + | |||
| + | < | ||
| + | [defaults] | ||
| + | inventory = / | ||
| + | remote_user = ansible | ||
| + | private_key_file = / | ||
| + | </ | ||
| + | |||
| + | Ahora es más cómodo lanzar el playbook de la siguiente manera: | ||
| + | |||
| + | < | ||
| + | ansible-playbook nginx_role.yaml -vv | ||
| + | </ | ||
| + | |||
| ===== Recursos ===== | ===== Recursos ===== | ||
| * [[https:// | * [[https:// | ||
| * [[https:// | * [[https:// | ||
informatica/ciberseguridad/cursos/curso_ansible_automatizacion_it/conceptos_avanzados.1683561837.txt.gz · Última modificación: por tempwin
