0% found this document useful (0 votes)
3K views534 pages

Rh294 8.0 Student Guide

This document is a student workbook for Red Hat Enterprise Linux Automation with Ansible. It covers topics such as installing and implementing Ansible, writing and executing Ansible playbooks, and managing variables and secrets.

Uploaded by

pleomartinez
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3K views534 pages

Rh294 8.0 Student Guide

This document is a student workbook for Red Hat Enterprise Linux Automation with Ansible. It covers topics such as installing and implementing Ansible, writing and executing Ansible playbooks, and managing variables and secrets.

Uploaded by

pleomartinez
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 534

Libro de trabajo del estudiante (ROLE)

Red Hat Enterprise Linux 8.0 RH294


Red Hat Enterprise Linux Automation with
Ansible
Edición 1

RH294-RHEL8.0-es-1-20200501 Copyright ©2019 Red Hat, Inc.


Red Hat Enterprise
Linux Automation
with Ansible

RH294-RHEL8.0-es-1-20200501 Copyright ©2019 Red Hat, Inc.


Red Hat Enterprise Linux 8.0 RH294
Red Hat Enterprise Linux Automation with Ansible
Edición 1 20200501
fecha de publicación 20190531

Autores: Trey Feagle, Herve Quatremain, Dallas Spohn, Adolfo Vazquez,


Morgan Weetman
Editor: Philip Sweany, Seth Kenlon, Jeff Tyson, Nicole Muller
Copyright © 2019 Red Hat, Inc.

The contents of this course and all its modules and related materials, including handouts to audience members, are
Copyright © 2019 Red Hat, Inc.

No part of this publication may be stored in a retrieval system, transmitted or reproduced in any way, including, but
not limited to, photocopy, photograph, magnetic, electronic or other record, without the prior written permission of
Red Hat, Inc.

This instructional program, including all material provided herein, is supplied without any guarantees from Red Hat,
Inc. Red Hat, Inc. assumes no liability for damages or legal action arising from the use or misuse of contents or details
contained herein.

If you believe Red Hat training materials are being used, copied, or otherwise improperly distributed, please send
email to [email protected] or phone toll-free (USA) +1 (866) 626-2994 or +1 (919) 754-3700.

Red Hat, Red Hat Enterprise Linux, the Red Hat logo, JBoss, Hibernate, Fedora, the Infinity logo, and RHCE are
trademarks of Red Hat, Inc., registered in the United States and other countries.

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.

Java® is a registered trademark of Oracle and/or its affiliates.

XFS® is a registered trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or
other countries.

The OpenStack® word mark and the Square O Design, together or apart, are trademarks or registered trademarks
of OpenStack Foundation in the United States and other countries, and are used with the OpenStack Foundation's
permission. Red Hat, Inc. is not affiliated with, endorsed by, or sponsored by the OpenStack Foundation or the
OpenStack community.

All other trademarks are the property of their respective owners.

Algunas partes de este curso se adaptaron del proyecto Ansible Lightbulb. El material de ese
proyecto está disponible en https://github.com/ansible/lightbulb con la Licencia de MIT.
Convenciones del documento ix

Introducción xi
Red Hat Enterprise Linux Automation with Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Orientación sobre el entorno del aula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Internacionalización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii

1. Presentación de Ansible 1
Automatización de la administración de Linux con Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Cuestionario: Automatización de la administración de Linux con Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Instalación de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Ejercicio Guiado: Instalación de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2. Implementación de Ansible 19
Compilación de un inventario de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Ejercicio Guiado: Compilación de un inventario de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Administración de archivos de configuración de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Ejercicio Guiado: Administración de archivos de configuración de Ansible . . . . . . . . . . . . . . . . . . . . . . . 38
Ejecución de comandos ad hoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Ejercicio Guiado: Ejecución de comandos ad hoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Trabajo de laboratorio: Implementación de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

3. Implementación de guías 65
Escritura y ejecución de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Ejercicio Guiado: Escritura y ejecución de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Implementación de varias reproducciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Ejercicio Guiado: Implementación de varias reproducciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Trabajo de laboratorio: Implementación de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

4. Administración de variables y hechos 103


Gestión de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Ejercicio Guiado: Gestión de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Gestión de secretos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Ejercicio Guiado: Gestión de secretos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Gestión de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Ejercicio Guiado: Gestión de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Trabajo de laboratorio: Administración de variables y datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

5. Implementación del control de tareas 157


Escritura de bucles y tareas condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Ejercicio Guiado: Escritura de bucles y tareas condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Implementación de manejadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Ejercicio Guiado: Implementación de manejadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Manejo de fallas de tareas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Ejercicio Guiado: Manejo de fallas de tareas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Trabajo de laboratorio: Implementación del control de tareas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

6. Implementación de archivos en hosts administrados 203


Modificación y copia de archivos a hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Ejercicio Guiado: Modificación y copia de archivos a hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Implementación de archivos personalizados con plantillas Jinja2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Ejercicio Guiado: Implementación de archivos personalizados con plantillas Jinja2 . . . . . . . . . . . 225
Trabajo de laboratorio: Implementación de archivos en hosts administrados . . . . . . . . . . . . . . . . . . . 228

RH294-RHEL8.0-es-1-20200501 v
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

7. Administración de proyectos grandes 235


Selección de hosts con patrones de hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Ejercicio Guiado: Selección de hosts con patrones de hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Administración de inventarios dinámicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Ejercicio Guiado: Administración de inventarios dinámicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Configuración del paralelismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Ejercicio Guiado: Configuración del paralelismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Inclusión e importación de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Ejercicio Guiado: Inclusión e importación de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Trabajo de laboratorio: Administración de proyectos grandes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289

8. Simplificación de guías con roles 291


Descripción de la estructura del rol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Cuestionario: Descripción de la estructura del rol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Reutilización de contenido con roles de sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Ejercicio Guiado: Reutilización de contenido con roles de sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Creación de roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Ejercicio Guiado: Creación de roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Implementación de roles con Ansible Galaxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Ejercicio Guiado: Implementación de roles con Ansible Galaxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Trabajo de laboratorio: Simplificación de guías con roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

9. Resolución de problemas de Ansible 355


Solución de problemas de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Ejercicio Guiado: Solución de problemas de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Solución de problemas en hosts administrados de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Ejercicio Guiado: Solución de problemas en hosts administrados de Ansible . . . . . . . . . . . . . . . . . . . 372
Trabajo de laboratorio: Solución de problemas de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385

10. Automatización de tareas de administración de Linux 387


Administración de software y suscripciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
Ejercicio Guiado: Administración de software y suscripciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Administración de usuarios y autenticación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Ejercicio Guiado: Administración de usuarios y autenticación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Administración del proceso de arranque y procesos programados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Ejercicio Guiado: Administración del proceso de arranque y procesos programados . . . . . . . . . 419
Administración del almacenamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Ejercicio Guiado: Administración del almacenamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Administración de la configuración de red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Ejercicio Guiado: Administración de la configuración de red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
Trabajo de laboratorio: Automatización de tareas de administración de Linux . . . . . . . . . . . . . . . . . 460
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

11. Revisión completa: Automation with Ansible 475


Revisión completa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Trabajo de laboratorio: Implementación de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
Trabajo de laboratorio: Creación de guías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Trabajo de laboratorio: Creación de roles y uso de inventario dinámico . . . . . . . . . . . . . . . . . . . . . . . . . . 493

A. Temas suplementarios 507


Examen de las opciones de configuración de Ansible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508

B. Licencias de Ansible Lightbulb 511

vi RH294-RHEL8.0-es-1-20200501
Licencia de Ansible Lightbulb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

RH294-RHEL8.0-es-1-20200501 vii
viii RH294-RHEL8.0-es-1-20200501
Convenciones del documento

Referencias
En "Referencias", se describe el lugar donde se puede encontrar documentación
externa relevante para un tema.

nota
Las "notas" son consejos, atajos o enfoques alternativos para una tarea
determinada. Omitir una nota no debería tener consecuencias negativas, pero
quizás se pase por alto algún truco que puede simplificar una tarea.

Importante
En los cuadros "Importante", se detallan cosas que se olvidan con facilidad: cambios
de configuración que solo se aplican a la sesión actual o servicios que se deben
reiniciar para poder aplicar una actualización. Ignorar un cuadro con la etiqueta
"Importante" no provocará pérdida de datos, pero puede causar irritación y
frustración.

Advertencia
No se deben ignorar las "Advertencias". Es muy probable que omitir las advertencias
provoque pérdida de datos.

RH294-RHEL8.0-es-1-20200501 ix
x RH294-RHEL8.0-es-1-20200501
Introducción

Red Hat Enterprise Linux Automation with Ansible


Red Hat Enterprise Linux Automation with Ansible(RH294) para los
administradores y desarrolladores de sistemas Linux que necesitan
automatizar el aprovisionamiento, la configuración, la implementación de
aplicaciones y la orquestación.

Los estudiantes aprenderán cómo instalar y configurar Ansible en una


estación de trabajo de gestión y prepararán hosts administrados para
la automatización. Los estudiantes escribirán Ansible Playbooks para
automatizar tareas y las ejecutarán para garantizar que los servidores estén
correctamente implementados y configurados. Se explorarán ejemplos de
enfoques para automatizar tareas comunes de administración del sistema
Linux.

Objetivos del • Instalar y configurar Ansible o Red Hat Ansible


curso Engine en un nodo de control.
• Cree y administre inventarios de hosts
administrados y prepárelos para la
automatización de Ansible.
• Ejecute tareas de automatización ad hoc
individuales desde la línea de comandos.
• Escriba guías Ansible para automatizar de
manera coherente varias tareas y aplicarlas a
hosts administrados.
• Parametrice las guías con variables y hechos,
y proteja los datos confidenciales con Ansible
Vault.
• Escriba y reutilice los roles existentes de Ansible
para simplificar la creación de guías y reutilizar
el código.
• Automatice las tareas de administración
comunes del sistema Red Hat Enterprise Linux
con Ansible.

RH294-RHEL8.0-es-1-20200501 xi
Introducción

Destinatarios • Administradores de sistemas Linux, ingenieros


de DevOps, ingenieros de automatización
de infraestructura e ingenieros de diseño de
sistemas responsables de la automatización
de la administración de configuración, la
implementación de aplicaciones coherente
y repetible, el aprovisionamiento y la
implementación de servidores de desarrollo,
pruebas y producción, y la integración con flujos
de trabajo de CI/CD de DevOps.

Requisitos • Certificación Red Hat Certified System


previos Administrator (EX200/RHCSA) o conocimiento
y experiencia en Red Hat Enterprise Linux
equivalente.

xii RH294-RHEL8.0-es-1-20200501
Introducción

Orientación sobre el entorno del aula

Figura 0.1: Entorno del aula

En este curso, el sistema de cómputo principal utilizado para las actividades prácticas de
aprendizaje es workstation. Los estudiantes también usan otras cuatro máquinas para estas
actividades: servera, serverb, serverc y serverd. Estos cinco sistemas se encuentran en el
dominio DNS lab.example.com.

Todos los sistemas de cómputo de los estudiantes tienen una cuenta de usuario estándar
(student) con la contraseña student. La contraseña root de todos los sistemas de los
estudiantes es redhat.

Máquinas del aula

Nombre de la máquina Direcciones IP Rol

bastion.lab.example.com 172.25.250.254 Sistema de puerta de enlace


para conectar la red privada
de los estudiantes al servidor
del aula (debe estar siempre
en ejecución)

workstation.lab.example.com 172.25.250.9 Estación de trabajo gráfica


usada para la administración
del sistema

servera.lab.example.com 172.25.250.10 Host administrado con


Ansible

RH294-RHEL8.0-es-1-20200501 xiii
Introducción

Nombre de la máquina Direcciones IP Rol

serverb.lab.example.com 172.25.250.11 Host administrado con


Ansible

serverc.lab.example.com 172.25.250.12 Host administrado con


Ansible

serverd.lab.example.com 172.25.250.13 Host administrado con


Ansible

La función principal de bastion es que actúa como enrutador entre la red que conecta las
máquinas de los estudiantes y la red del aula. Si bastion está apagada, otras máquinas de
estudiantes solo podrán acceder a sistemas en la red de estudiantes individuales.

Varios sistemas en el aula brindan servicios de soporte. Dos servidores, content.example.com


y materials.example.com, son fuentes de software y materiales del trabajo de laboratorio
usados en actividades prácticas. Se provee información sobre cómo usar estos servidores en
las instrucciones para estas actividades. Estas instrucciones las proporciona la máquina virtual
classroom.example.com. Tanto classroom como bastion se deben estar ejecutando
siempre para el uso adecuado del entorno de laboratorio.

Control de sus sistemas


A los estudiantes se les asignan computadoras remotas en un aula de aprendizaje en línea de
Red Hat. Se accede a ellas a través de una aplicación web alojada en rol.redhat.com [http://
rol.redhat.com]. Los estudiantes deben iniciar sesión en este sitio usando sus credenciales de
usuario del Portal de clientes de Red Hat.

Control de las máquinas virtuales


Las máquinas virtuales del entorno de su aula se controlan a través de una página web. El estado
de cada máquina virtual en el aula se muestra en la página en la pestaña Online Lab (Trabajo de
laboratorio en línea).

Estados de la máquina

Estado de la Descripción
máquina virtual

STARTING (EN La máquina virtual está por arrancar.


INICIO)

STARTED (INICIADA) La máquina virtual se está ejecutando y está disponible (o bien,


cuando arranque, pronto lo estará).

STOPPING (EN La máquina virtual está por apagarse.


DETENCIÓN)

STOPPED La máquina virtual se ha apagado completamente. Al iniciarse, la


(DETENIDA) máquina virtual arranca en el mismo estado en que se hallaba en el
momento de apagarse (el disco se habrá preservado).

PUBLISHING Se está llevando a cabo la creación inicial de la máquina virtual.


(PUBLICADA)

xiv RH294-RHEL8.0-es-1-20200501
Introducción

Estado de la Descripción
máquina virtual

WAITING_TO_START La máquina virtual está esperando que inicien las demás máquinas
(EN ESPERA PARA virtuales.
INICIARSE)

Según el estado de una máquina, se dispone de una selección de las siguientes acciones.

Acciones de aula/máquina

Botón o acción Descripción

PROVISION LAB Cree el aula de ROL. Crea todas las máquinas virtuales necesarias para
(APROVISIONAR el aula y las inicia. Puede tardar algunos minutos en completarse.
TRABAJO DE
LABORATORIO)

DELETE LAB Elimine el aula de ROL. Esta acción destruye todas las máquinas
(ELIMINAR virtuales del aula. Precaución: Se perderán los trabajos generados
TRABAJO DE en los discos.
LABORATORIO)

START LAB Inicie todas las máquinas virtuales en el aula.


(INICIAR
TRABAJO DE
LABORATORIO)

SHUTDOWN Detenga todas las máquinas virtuales en el aula.


LAB (APAGAR
TRABAJO DE
LABORATORIO)

OPEN CONSOLE Abra una nueva pestaña en el explorador y conéctese a la consola de


(ABRIR CONSOLA) la máquina virtual. Los estudiantes pueden iniciar sesión directamente
en la máquina virtual y ejecutar los comandos. En la mayoría de los
casos, los estudiantes deben iniciar sesión en la máquina virtual
workstation y usar ssh para conectarse a las otras máquinas
virtuales.

ACTION (ACCIÓN) Inicie (power on [encender]) la máquina virtual.


→ Start(Iniciar)

ACTION Apague la máquina virtual correctamente y preserve el contenido del


(ACCIÓN) → disco.
Shutdown(Apagar)

ACTION (ACCIÓN) Fuerce el apagado de la máquina virtual y preserve el contenido del


→ Power disco. Esto equivale a desenchufar una máquina física.
Off(Desconectar)

ACTION Fuerce el apagado de la máquina virtual y restablezca el disco para que


(ACCIÓN) → vuelva a su estado original. Precaución: Se perderán los trabajos
Reset(Restablecer) generados en el disco.

RH294-RHEL8.0-es-1-20200501 xv
Introducción

Al inicio de un ejercicio, si se le indica que restablezca el nodo de una máquina virtual, haga clic en
ACTION (ACCIÓN) → Reset (Restablecer) solo para la máquina virtual específica.

Al inicio de un ejercicio, si se le indica que restablezca todas las máquinas virtuales, haga clic en
ACTION (ACCIÓN) → Reset (Restablecer).

Si desea que el entorno del aula vuelva a su estado original al inicio del curso, puede hacer
clic en DELETE LAB (ELIMINAR TRABAJO DE LABORATORIO) para eliminar el entorno del
aula completo. Después de eliminar el trabajo de laboratorio, puede hacer clic en PROVISION
LAB (APROVISIONAR TRABAJO DE LABORATORIO) para aprovisionar un nuevo conjunto de
sistemas del aula.

Advertencia
La operación DELETE LAB (ELIMINAR TRABAJO DE LABORATORIO) no puede
deshacerse. Se perderán todos los trabajos que haya completado en el entorno del
aula hasta el momento.

Temporizador de detención automática


La inscripción al aprendizaje en línea de Red Hat otorga a los estudiantes derecho a una cierta
cantidad de tiempo de uso del equipo. Para ahorrar tiempo asignado de la computadora, el aula de
ROL tiene un temporizador de cuenta regresiva asociado, el cual apaga el entorno del aula cuando
se termina el tiempo.

Para ajustar el temporizador, haga clic en MODIFY (MODIFICAR) para que aparezca el cuadro
de diálogo New Autostop Time (Nuevo tiempo de detención automática). Defina la cantidad de
horas y minutos hasta que el aula deba detenerse automáticamente. Haga clic en ADJUST TIME
(AJUSTAR TIEMPO) para aplicar este cambio en los ajustes del temporizador.

xvi RH294-RHEL8.0-es-1-20200501
Introducción

Internacionalización

Compatibilidad de idioma
Red Hat Enterprise Linux 8 admite oficialmente 22 idiomas: inglés, asamés, bengalí, chino
(simplificado), chino (tradicional), francés, alemán, guyaratí, hindi, italiano, japonés, canarés,
coreano, malayalam, maratí, oriya, portugués (brasileño), panyabí, ruso, español, tamil y telugú.

Selección de idioma por usuario


Es posible que los usuarios prefieran usar un idioma para su entorno de escritorio distinto al
predeterminado del sistema. Quizás también quieran definir su cuenta para usar una distribución
del teclado o un método de entrada distinto.

Configuración de idioma
En el entorno de escritorio GNOME, posiblemente el usuario deba definir el idioma de su
preferencia y el método de entrada la primera vez que inicie sesión. Si no es así, la manera
más simple para un usuario individual de definir el idioma de su preferencia y el método
de entrada es usando la aplicación Region & Language (Región e idioma). Ejecute el
comando gnome-control-center region o, en la barra superior, seleccione (Usuario) →
Settings(Configuración). En la ventana que se abre, seleccione Region & Language. El usuario
puede hacer clic en la caja (box) Language (Idioma) y seleccionar el idioma de su preferencia en
la lista que aparece. Esto también actualizará la configuración de Formats (Formatos) mediante la
adopción del valor predeterminado para ese idioma. La próxima vez que el usuario inicie sesión, se
efectuarán los cambios.

Estas configuraciones afectan el entorno de escritorio GNOME y todas las aplicaciones, incluida
gnome-terminal, que se inician dentro de este. Sin embargo, no se aplican a la cuenta si el
acceso a ella es mediante un inicio de sesión ssh desde un sistema remoto o desde una consola
de texto local (como tty2).

RH294-RHEL8.0-es-1-20200501 xvii
Introducción

nota
Un usuario puede hacer que su entorno de intérprete de comandos use la misma
configuración de LANG que su entorno gráfico, incluso cuando inicia sesión
mediante una consola de texto o mediante ssh. Una manera de hacer esto es
colocar un código similar al siguiente en el archivo ~/.bashrc del usuario. Este
código de ejemplo definirá el idioma empleado en un inicio de sesión en interfaz de
texto de modo que coincida con el idioma actualmente definido en el entorno de
escritorio GNOME del usuario:

i=$(grep 'Language=' /var/lib/AccountService/users/${USER} \


| sed 's/Language=//')
if [ "$i" != "" ]; then
export LANG=$i
fi

Es posible que algunos idiomas, como el japonés, coreano, chino y otros con un
conjunto de caracteres no latinos, no se vean correctamente en consolas de texto
locales.

Se pueden crear comandos individuales para usar otro idioma mediante la configuración de la
variable LANG en la línea de comandos:

[user@host ~]$ LANG=fr_FR.utf8 date


jeu. avril 24 17:55:01 CDT 2014

Los comandos subsiguientes se revertirán y usarán el idioma de salida predeterminado del


sistema. El comando locale se puede usar para comprobar el valor actual de LANG y otras
variables de entorno relacionadas.

Valores del método de entrada


GNOME 3 en Red Hat Enterprise Linux 8 emplea de manera automática el sistema de selección
de método de entrada IBus, que permite cambiar las distribuciones del teclado y los métodos de
entrada de manera rápida y sencilla.

La aplicación Region & Language (Región e idioma) también se puede usar para habilitar métodos
de entrada alternativos. En la ventana de la aplicación Region & Language (Región e idioma), la
caja (box) Input Sources (Fuentes de entrada) muestra los métodos de entrada disponibles en
este momento. De forma predeterminada, es posible que English (US) (Inglés [EE. UU.]) sea
el único método disponible. Resalte English (US) (inglés de EE. UU.) y haga clic en el icono de
teclado para ver la distribución actual del teclado.

Para agregar otro método de entrada, haga clic en el botón +, en la parte inferior izquierda de
la ventana Input Sources (Fuentes de entrada). Se abrirá la ventana Add an Input Source
(Agregar una fuente de entrada). Seleccione su idioma y, luego, el método de entrada o la
distribución del teclado de su preferencia.

Una vez que haya más de un método de entrada configurado, el usuario puede alternar entre ellos
rápidamente escribiendo Super+Space (en ocasiones denominado Windows+Space). También
aparecerá un indicador de estado en la barra superior de GNOME con dos funciones: por un lado,
indica el método de entrada activo; por el otro lado, funciona como un menú que puede usarse

xviii RH294-RHEL8.0-es-1-20200501
Introducción

para cambiar de un método de entrada a otro o para seleccionar funciones avanzadas de métodos
de entrada más complejos.

Algunos de los métodos están marcados con engranajes, que indican que tienen opciones de
configuración y capacidades avanzadas. Por ejemplo, el método de entrada japonés Japanese
(Kana Kanji) le permite al usuario editar previamente texto en latín y usar las teclas de flecha
hacia abajo y flecha hacia arriba para seleccionar los caracteres correctos que se
usarán.

El indicador también puede ser de utilidad para los hablantes de inglés de Estados Unidos. Por
ejemplo, dentro de English (United States) (Inglés [Estados Unidos]) está la configuración del
teclado English (international AltGr dead keys) (Inglés [internacional, teclas inactivas AltGr]),
que trata AltGr (o la tecla Alt derecha) en un teclado de 104/105 teclas de una PC como una
tecla modificadora "Bloq Mayús secundaria" y tecla de activación de teclas inactivas para escribir
caracteres adicionales. Hay otras distribuciones alternativas disponibles, como Dvorak.

nota
Cualquier carácter Unicode puede ingresarse en el entorno de escritorio GNOME,
si el usuario conoce el código Unicode del carácter, escribiendo Ctrl+Shift+U,
seguido por el código. Después de ingresar Ctrl+Shift+U, aparecerá una u
subrayada que indicará que el sistema espera la entrada del código Unicode.

Por ejemplo, la letra del alfabeto griego en minúscula lambda tiene el código U
+03BB y puede ingresarse escribiendo Ctrl+Shift+U, luego 03bb y por último
Enter.

Valores de idioma predeterminado en todo el sistema


El idioma predeterminado del sistema está definido en US English, que utiliza la codificación
UTF-8 de Unicode como su conjunto de caracteres (en_US.utf8), pero puede cambiarse
durante o después de la instalación.

Desde la línea de comandos, root puede cambiar los ajustes de configuración regional de todo
el sistema con el comando localectl. Si localectl se ejecuta sin argumentos, mostrará los
ajustes actuales de configuración regional de todo el sistema.

Para configurar el idioma de todo el sistema, ejecute el comando localectl set-locale


LANG=locale, donde locale es el $LANG adecuado de la tabla "Referencia de códigos de idioma"
en este capítulo. El cambio tendrá efecto para usuarios en su próximo inicio de sesión y se
almacena en /etc/locale.conf.

[root@host ~]# localectl set-locale LANG=fr_FR.utf8

En GNOME, un usuario administrativo puede cambiar esta configuración en Region & Language
(Región e idioma) y con un clic en el botón Login Screen (Pantalla de inicio de sesión) ubicado
en la esquina superior derecha de la ventana. Al cambiar la opción de Language de la pantalla
de inicio de sesión, también ajustará el valor de idioma predeterminado de todo el sistema en el
archivo de configuración /etc/locale.conf.

RH294-RHEL8.0-es-1-20200501 xix
Introducción

Importante
Las consolas de texto locales como tty2 están más limitadas en las fuentes
que pueden mostrar que las sesiones gnome-terminal y ssh. Por ejemplo, los
caracteres del japonés, coreano y chino posiblemente no se visualicen como se
espera en una consola de texto local. Por este motivo, es posible que tenga sentido
usar el inglés u otro idioma con un conjunto de caracteres latinos para la consola de
texto del sistema.

De manera similar, las consolas de texto locales admiten una cantidad de métodos
de entrada también más limitada, y esto se administra de manera separada desde
el entorno de escritorio gráfico. La configuración de entrada global disponible se
puede configurar mediante localectl tanto para consolas virtuales de texto
locales como para el entorno gráfico X11. Para obtener más información, consulte las
páginas del manual localectl(1), kbd(4) y vconsole.conf(5).

Paquetes de idiomas
Si utiliza un idioma diferente al inglés, posiblemente desee instalar “paquetes de idiomas”
adicionales para disponer de traducciones adicionales, diccionarios, etc. Para ver la lista de
paquetes de idiomas disponibles, ejecute yum langavailable. Para ver la lista de paquetes de
idiomas actualmente instalados en el sistema, ejecute yum langlist. Para agregar un paquete
de idioma adicional al sistema, ejecute yum langinstall code, donde code es el código en
corchetes después del nombre del idioma en la salida de yum langavailable.

Referencias
Páginas del manual: locale(7), localectl(1), kbd(4), locale.conf(5),
vconsole.conf(5), unicode(7), utf-8(7) y yum-langpacks(8).

Las conversiones entre los nombres de los diseños X11 del entorno de escritorio
gráfico y sus nombres en localectl se pueden encontrar en el archivo /usr/
share/X11/xkb/rules/base.lst.

Referencia de códigos de idioma

Códigos de idioma

Idioma Valor $LANG

Inglés (EE. UU.) en_US.utf8

Asamés as_IN.utf8

Bengalí bn_IN.utf8

Chino (simplificado) zh_CN.utf8

Chino (tradicional) zh_TW.utf8

Francés fr_FR.utf8

Alemán de_DE.utf8

xx RH294-RHEL8.0-es-1-20200501
Introducción

Idioma Valor $LANG

Guyaratí gu_IN.utf8

Hindi hi_IN.utf8

Italiano it_IT.utf8

Japonés ja_JP.utf8

Canarés kn_IN.utf8

Coreano ko_KR.utf8

Malayalam ml_IN.utf8

Maratí mr_IN.utf8

Odia or_IN.utf8

Portugués (brasileño) pt_BR.utf8

Panyabí pa_IN.utf8

Ruso ru_RU.utf8

Español es_ES.utf8

Tamil ta_IN.utf8

Telugú te_IN.utf8

RH294-RHEL8.0-es-1-20200501 xxi
xxii RH294-RHEL8.0-es-1-20200501
capítulo 1

Presentación de Ansible
Meta Describir los conceptos fundamentales de Ansible
y la forma de usarlo, e instalar Red Hat Ansible
Engine.

Objetivos • Describir la motivación para automatizar las


tareas de administración de Linux con Ansible,
los conceptos fundamentales de Ansible y la
arquitectura básica de Ansible.
• Instalar Ansible en un nodo de control y
describir la distinción entre la comunidad
Ansible y Red Hat Ansible Engine.

Secciones • Automatización de la administración de Linux


con Ansible (y cuestionario)
• Instalación de Ansible (y ejercicio guiado)

RH294-RHEL8.0-es-1-20200501 1
capítulo 1 | Presentación de Ansible

Automatización de la administración de
Linux con Ansible

Objetivo
Tras finalizar esta sección, deberá ser capaz de describir la motivación para automatizar las tareas
de administración de Linux con Ansible, los conceptos fundamentales de Ansible y la arquitectura
básica de Ansible.

Automatización y administración de sistemas Linux


Durante muchos años, la mayor parte de la administración de sistemas y de infraestructuras se
ha basado en tareas manuales realizadas a través de interfaces de usuario tanto gráficas como
de línea de comandos. Los administradores de sistemas suelen usar listas de verificación, otra
documentación o una rutina memorizada para realizar tareas estándares.

Este enfoque es propenso a errores. Es fácil que un administrador de sistemas omita un paso o
realice un paso por error. A menudo, se hace una verificación limitada para comprobar que los
pasos se hayan realizado correctamente o que produzcan el resultado esperado.

Además, al administrar cada servidor de forma manual e independiente, es muy fácil que muchos
servidores que se supone que deben tener una configuración idéntica tengan diferencias menores
(o importantes). Esto puede dificultar el mantenimiento e introducir errores o inestabilidad en el
entorno de TI.

La automatización puede ayudar a evitar los problemas causados por la administración manual
del sistema y la administración de la infraestructura. Como administrador de sistemas, puede
usarla para garantizar que todos sus sistemas se implementen y se configuren de forma rápida y
correcta. Esto permite automatizar las tareas repetitivas de su cronograma diario a fin de tener
más tiempo para enfocarse en tareas más importantes. Para su organización, esto significa que
puede implementar más rápidamente la próxima versión de una aplicación o las actualizaciones de
un servicio.

Infraestructura como código


Un buen sistema de automatización permite implementar prácticas de infraestructura como
código. La infraestructura como código significa que puede usar un lenguaje de automatización
legible por máquinas para definir y describir el estado en el que desea que se encuentre su
infraestructura de TI. Idealmente, este lenguaje de automatización también debería ser muy fácil
de leer para los humanos, lo que permite entender fácilmente el estado y modificarlo. Este código
se aplica a su infraestructura para garantizar que realmente se encuentre en ese estado.

Si el lenguaje de automatización se representa como archivos de texto simples, puede


administrarse fácilmente en un sistema de control de versiones como el código de software. La
ventaja de esto es que cada cambio se puede registrar en el sistema de control de versiones,
por lo que tiene un historial de los cambios que realiza con el tiempo. Si quiere volver a una
configuración anterior de eficacia comprobada, basta con revisar esa versión del código y aplicarla
a su infraestructura.

Esto crea la base para ayudarlo a seguir las prácticas recomendadas en DevOps. Los
desarrolladores pueden definir su configuración deseada en el lenguaje de automatización. Los
operadores pueden revisar esos cambios con mayor facilidad para proporcionar comentarios y

2 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

usar esa automatización para garantizar de manera reproducible que los sistemas se encuentren
en el estado esperado por los desarrolladores.

Mitigación del error humano


Al reducir las tareas realizadas manualmente en los servidores mediante la automatización de
tareas y las prácticas de infraestructura como código, sus servidores tendrán configuraciones
coherentes con mayor frecuencia. Esto significa que debe acostumbrarse a hacer cambios
actualizando el código de automatización en lugar de aplicarlos manualmente a los servidores. De
lo contrario, corre el riesgo de perder cambios aplicados manualmente la próxima vez que aplique
cambios mediante la automatización.

La automatización le permite usar la revisión de código, la revisión por varios colegas expertos en
la materia y la documentación del procedimiento mediante la automatización misma para reducir
los riesgos operativos.

En última instancia, puede hacer que los cambios en su infraestructura de TI deban hacerse a
través de la automatización para mitigar los errores humanos.

¿Qué es Ansible?
Ansible es una plataforma de automatización de código abierto. Es un lenguaje de automatización
simple que puede describir perfectamente una infraestructura de aplicaciones de TI en Ansible
Playbooks. También es un motor de automatización que ejecuta Ansible Playbooks.

Ansible puede administrar tareas de automatización potentes y puede adaptarse a muchos


workflows y entornos diferentes. Al mismo tiempo, los nuevos usuarios de Ansible pueden usarla
muy rápidamente para volverse productivos.

Ansible es simple
Las guías de Ansible proporcionan automatización legible por el ojo humano. Esto significa que las
guías son herramientas de automatización que también son fáciles de leer, comprender y cambiar
para los humanos. No se necesitan habilidades de codificación especiales para escribirlas. Las
guías ejecutan tareas en orden. La simplicidad del diseño de la guía hace que sean utilizables
por todos los equipos, lo que permite que las personas que nunca usaron Ansible se vuelvan
productivas rápidamente.

Ansible es potente
Puede usar Ansible para la implementación de aplicaciones, la administración de la configuración,
la automatización de flujos de trabajo y la automatización de redes. Ansible puede usarse para
orquestar el ciclo de vida completo de la aplicación.

Ansible no tiene agentes


Ansible está diseñada alrededor de una arquitectura sin agentes. En general, Ansible se conecta
con hosts que administra con OpenSSH o WinRM y ejecuta tareas, a menudo (pero no siempre)
enviando pequeños programas denominados módulos Ansible a esos hosts. Estos programas se
usan para colocar el sistema en un estado deseado específico. Todos los módulos enviados se
eliminan cuando Ansible finaliza con sus tareas. Puede comenzar a utilizar Ansible casi de forma
inmediata, ya que no se necesita aprobar agentes especiales para usar y, luego, implementarlos
en los hosts administrados. Dado que no hay agentes ni una infraestructura de seguridad
personalizada adicional, Ansible es más eficaz y más segura que otras alternativas.

Ansible tiene varios puntos fuertes importantes:

RH294-RHEL8.0-es-1-20200501 3
capítulo 1 | Presentación de Ansible

• Compatible con diversas plataformas: Ansible proporciona soporte sin agentes para Linux,
Windows, UNIX y dispositivos de red, en entornos físicos, virtuales, de nube y en contenedores.

• Automatización legible por el ojo humano: Las Ansible Playbooks, escritas como archivos de
texto YAML, son fáciles de leer y permiten garantizar que todos entiendan lo que harán.

• Perfecta descripción de aplicaciones: Las guías de Ansible pueden realizar todas las
modificaciones, y se pueden describir y documentar todos los aspectos de su entorno de
aplicaciones.

• Fácil de administrar en el control de versiones: Las guías de Ansible y los proyectos son texto sin
formato. Puede considerarse código fuente y colocarse en su sistema de control de versiones
existente.

• Compatibilidad con inventarios dinámicos: La lista de máquinas que administra Ansible puede
actualizarse de forma dinámica desde fuentes externas para capturar la lista actual y correcta
de todos los servidores administrados todo el tiempo, independientemente de la infraestructura
o la ubicación.

• Orquestación que se integra fácilmente con otros sistemas: HP SA, Puppet, Jenkins, Red Hat
Satellite, y otros sistemas que existen en su entorno, se pueden aprovechar e integrar en su
workflow de Ansible.

Ansible: El lenguaje de DevOps

Figura 1.1: Ansible durante el ciclo de vida de la aplicación

La comunicación es la clave de DevOps. Ansible es el primer lenguaje de automatización que se


puede leer y escribir en TI. También es el único motor de automatización que puede automatizar el
ciclo de vida de la aplicación y la canalización de entrega continua de principio a fin.

Conceptos y arquitectura de Ansible


Hay dos tipos de máquinas en la arquitectura Ansible: nodos de control y hosts administrados.
Ansible se instala y se ejecuta desde un nodo de control, y esta máquina también tiene copias de
sus archivos de proyecto de Ansible. Un nodo de control podría ser un portátil de administrador, un
sistema compartido por varios administradores o un servidor que ejecuta Red Hat Ansible Tower.

Los hosts administrados aparecen en un inventario, que también organiza estos sistemas en
grupos para una administración colectiva más sencilla. El inventario puede definirse en un archivo
de texto estático, o se puede determinar de forma dinámica mediante scripts que obtienen
información de fuentes externas.

4 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

En lugar de escribir scripts complejos, los usuarios de Ansible crean reproducciones de alto nivel
para asegurarse de que un host o grupo de hosts estén en un estado particular. Una reproducción
realiza una serie de tareas en los hosts, en el orden especificado por la reproducción. Estas
reproducciones se expresan en formato YAML en un archivo de texto. Un archivo que contiene una
o más reproducciones se denomina una guía.

Cada tarea ejecuta un módulo, una pequeña parte de un código (escrito en Python, PowerShell
o cualquier otro lenguaje), con argumentos específicos. Cada módulo es esencialmente una
herramienta en su kit de herramientas. Ansible se envía con cientos de módulos útiles que pueden
realizar una amplia variedad de tareas de automatización. Pueden actuar en archivos de sistemas,
instalar software o realizar llamadas de API.

Cuando se usa en una tarea, un módulo generalmente garantiza que un aspecto específico de la
máquina tenga un estado específico. Por ejemplo, una tarea que usa un módulo puede garantizar
que exista un archivo y que tenga permisos y contenidos específicos, mientras que una tarea que
usa un módulo diferente puede asegurarse de que se monte un sistema de archivos específico. Si
el sistema no tiene ese estado, la tarea debe colocarlo en ese estado. Si el sistema ya tiene ese
estado, no realiza acciones. Si una tarea falla, el comportamiento predeterminado de Ansible es
cancelar el resto de la guía para los hosts que tuvieron una falla.

Las tareas, reproducciones y guías están diseñadas para ser idempotentes. Esto significa que
puede ejecutar de forma segura una guía en los mismos hosts varias veces. Cuando sus sistemas
tienen el estado correcto, la guía no realiza cambios cuando lo ejecuta. Esto significa que debería
poder ejecutar una guía de forma segura en los mismos hosts varias veces. Cuando, al ejecutar
sus sistemas, estos tienen el estado correcto, la guía no debería realizar cambios. Hay un puñado
de módulos que puede usar para ejecutar comandos arbitrarios. Sin embargo, debe usar esos
módulos con cuidado para asegurarse de que se ejecuten de forma idempotente.

Ansible también usa complementos (plug-ins). Los complementos (plug-ins) son códigos que
puede agregar a Ansible para ampliarla y adaptarla a los nuevos usos y las nuevas plataformas.

La arquitectura de Ansible no tiene agentes. En general, cuando un administrador ejecuta una guía
de Ansible o un comando ad hoc, el nodo de control se conecta con el host administrado mediante
SSH (de forma predeterminada) o WinRM. Esto significa que los clientes no necesitan tener un
agente específico de Ansible instalado en los hosts administrados y no necesitan permitir el tráfico
de red especial a un puerto no estándar.

Red Hat Ansible Tower es un marco (framework) empresarial que le permite controlar, asegurar
y administrar su automatización de Ansible a escala. Puede usarlo para controlar quién tiene
acceso a la ejecución de guías en qué hosts, el uso compartido de credenciales SSH sin permitir
a los usuarios transferir o ver su contenido, registrar todos sus trabajos de Ansible y administrar
el inventario, entre muchas otras cosas. Proporciona una interfaz de usuario basada en la Web (IU
web) y una API RESTful. No es una parte principal de Ansible, sino un producto diferente que le
permite usar Ansible de manera más efectiva con un equipo o a gran escala.

RH294-RHEL8.0-es-1-20200501 5
capítulo 1 | Presentación de Ansible

Figura 1.2: Arquitectura de Ansible

La manera de Ansible
La complejidad mata la productividad
Más sencillo es mejor. Ansible está diseñada de modo que sus herramientas sean simples de
usar y la automatización sea simple de escribir y leer. Debería aprovechar esto para lograr la
simplificación en el modo en que crea su automatización.

Optimizar para brindar capacidad de lectura


El lenguaje de automatización de Ansible se desarrolla alrededor de archivos de texto simples y
declarativos que son fáciles para ser leídos por humanos. Al escribirse correctamente, las guías de
Ansible pueden documentar claramente la automatización de su flujo de trabajo.

Pensar de forma declarativa


Ansible es un motor de estado deseado. Aborda el problema sobre el modo de automatizar
las implementaciones de TI expresándolas en términos del estado que desea que tengan sus
sistemas. El objetivo de Ansible es colocar sus sistemas en el estado deseado, haciendo solo los
cambios que sean necesarios. Intentar tratar a Ansible como un lenguaje de creación de scripts no
es el enfoque correcto.

6 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

Figura 1.3: Ansible proporciona automatización completa

Casos de uso
A diferencia de otras herramientas, Ansible combina y une la orquestación con la administración de
la configuración, el aprovisionamiento y la implementación de aplicaciones en una plataforma fácil
de usar.

A continuación, se incluyen algunos casos prácticos para Ansible:

Administración de configuraciones
Centralizar la implementación y administración de archivos de configuración es un caso
práctico común para Ansible, por lo que constituye el primer contacto de muchos usuarios
avanzados con la plataforma de automatización de Ansible.

Implementación de aplicaciones
Al definir su aplicación con Ansible, y administrar la implementación con Red Hat Ansible
Tower, los equipos pueden administrar con eficacia todo el ciclo de vida de la aplicación desde
desarrollo hasta producción.

Aprovisionamiento
Las aplicaciones deben implementarse o instalarse en los sistemas. Ansible y Red Hat
Ansible Tower pueden ayudar a optimizar el proceso de los sistemas de aprovisionamiento,
ya sea que esté arrancando servicios o máquinas virtuales sin sistema operativo PXE, o que
cree máquinas virtuales o instancias de cloud a partir de plantillas. Las aplicaciones deben
implementarse o instalarse en los sistemas.

Entrega continua
Crear una canalización de CI/CD requiere la coordinación y la participación de numerosos
equipos. No puede hacerlo sin una plataforma de automatización simple que pueden usar

RH294-RHEL8.0-es-1-20200501 7
capítulo 1 | Presentación de Ansible

todos en su organización. Las guías de Ansible mantienen sus aplicaciones implementadas (y


administradas) correctamente durante todo su ciclo de vida.

Seguridad y conformidad
Al definir su política de seguridad en Ansible Playbooks, la detección y la corrección
de políticas de seguridad con respecto al sitio se pueden integrar en otros procesos
automatizados. En lugar de ser algo secundario, es una parte integral de todo lo que se
implementa.

Orquestación
Las configuraciones en sí mismas no definen su entorno. Debe definir cómo interactúan
los diferentes archivos de configuración y asegurarse de que las distintas piezas se puedan
administrar como una sola.

Referencias
Ansible
https://www.ansible.com

Cómo funciona Ansible


https://www.ansible.com/how-ansible-works

8 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

Cuestionario

Automatización de la administración de
Linux con Ansible
Elija las respuestas correctas para las siguientes preguntas:

1. ¿Cuál de los siguientes términos describe mejor la arquitectura de Ansible?


a. Sin agente
b. Cliente/Servidor
c. Basado en eventos
d. Sin estado

2. ¿Qué protocolo de red usa Ansible, de manera predeterminada, para comunicarse con
nodos administrados?
a. HTTP
b. HTTPS
c. SNMP
d. SSH

3. ¿Cuál de los siguientes archivos define las acciones que Ansible realiza en nodos
administrados?
a. Inventario de host
b. Manifiesto
c. Guía
d. Script

4. ¿Qué sintaxis se utiliza para definir las Ansible Playbooks?


a. Bash
b. Perl
c. Python
d. YAML

RH294-RHEL8.0-es-1-20200501 9
capítulo 1 | Presentación de Ansible

Solución

Automatización de la administración de
Linux con Ansible
Elija las respuestas correctas para las siguientes preguntas:

1. ¿Cuál de los siguientes términos describe mejor la arquitectura de Ansible?


a. Sin agente
b. Cliente/Servidor
c. Basado en eventos
d. Sin estado

2. ¿Qué protocolo de red usa Ansible, de manera predeterminada, para comunicarse con
nodos administrados?
a. HTTP
b. HTTPS
c. SNMP
d. SSH

3. ¿Cuál de los siguientes archivos define las acciones que Ansible realiza en nodos
administrados?
a. Inventario de host
b. Manifiesto
c. Guía
d. Script

4. ¿Qué sintaxis se utiliza para definir las Ansible Playbooks?


a. Bash
b. Perl
c. Python
d. YAML

10 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

Instalación de Ansible

Objetivos
Tras completar esta sección, deberá ser capaz de instalar Ansible en un nodo de control y describir
la diferencia entre la comunidad de Ansible y Red Hat Ansible Engine.

¿Ansible o Red Hat Ansible Automation?


Red Hat proporciona software Ansible en canales especiales como una conveniencia para los
suscriptores de Red Hat Enterprise Linux, y puede usar estos paquetes de software normalmente.

Sin embargo, si desea soporte formal para Ansible y sus módulos, Red Hat ofrece una suscripción
especial para esto: Red Hat Ansible Automation. Esta suscripción incluye soporte para Ansible
mismo, como Red Hat Ansible Engine. Esto agrega soporte técnico formal con acuerdos de
nivel de servicio y un alcance de cobertura publicado para Ansible y sus módulos principales.
Puede encontrar más información sobre el alcance de este soporte en Ciclo de vida de Red Hat
Ansible Engine [https://access.redhat.com/support/policy/updates/ansible-engine].

Nodos de control
Ansible es simple de instalar. El software de Ansible solo debe instalarse en el nodo (o los nodos)
de control desde el cual se ejecutará Ansible. No es necesario que los hosts que son administrados
por Ansible tengan Ansible instalado. Esta instalación implica relativamente pocos pasos y tiene
menos requisitos.

El nodo de control debería ser un sistema Linux o UNIX. Microsoft Windows no se admite como
nodo de control, si bien los sistemas Windows pueden ser hosts administrados.

Debe instalarse Python 3 (versión 3.5 o posterior) o Python 2 (versión 2.7 o posterior) en el nodo
de control.

Importante
Si está ejecutando Red Hat Enterprise Linux 8, Ansible 2.8 puede usar
automáticamente el paquete platform-python que admite utilidades del sistema
que usan Python. No es necesario instalar los paquetes python36 o python27 de
AppStream.

[root@controlnode ~]# yum list installed platform-python


Loaded plugins: langpacks, search-disabled-repos
Installed Packages
platform-python.x86_64 3.6.8-2.el8_0 @anaconda

Puede encontrar información sobre cómo instalar el paquete de software ansible en un sistema
Red Hat Enterprise Linux en el artículo de la base de conocimiento ¿Cómo descargo e instalo
Red Hat Ansible Engine? [https://access.redhat.com/articles/3174981].

RH294-RHEL8.0-es-1-20200501 11
capítulo 1 | Presentación de Ansible

Ansible está en rápido desarrollo innovador y, por lo tanto, Red Hat Ansible Engine tiene un
ciclo de vida rápido. Puede encontrar más información sobre el ciclo de vida actual en https://
access.redhat.com/support/policy/updates/ansible-engine.

Red Hat proporciona el canal ansible-2.8-for-rhel-8-x86_64-rpms para Red Hat


Enterprise Linux 8. También puede obtener la última actualización de la versión principal de
Red Hat Ansible Engine 2 para RHEL 8 en el canal ansible-2-for-rhel-8-x86_64-rpms.

Puede usar estos canales para instalar Ansible con soporte limitado con las suscripciones estándar
de Red Hat Enterprise Linux. Si necesita un soporte de Ansible más completo, puede comprar
suscripciones completas de Red Hat Ansible Engine y asociarlas a sus sistemas antes de habilitar
los canales, como se explica en el artículo de la base de conocimiento.

Si tiene una suscripción de Red Hat Ansible Engine, el procedimiento de instalación para Red Hat
Ansible Engine 2 es de la siguiente manera:

Advertencia
No es necesario que ejecute estos pasos en el entorno de su aula.

1. Registre su sistema en Red Hat Subscription Manager.

[root@host ~]# subscription-manager register

2. Establezca un rol para su sistema.

[root@host ~]# subscription-manager role --set="Red Hat Enterprise Linux Server"

3. Conecte su suscripción de Red Hat Ansible Engine. Este comando lo ayuda a encontrar su
suscripción de Red Hat Ansible Engine:

[root@host ~]# subscription-manager list --available

4. Utilice el ID de grupo de la suscripción para conectar el grupo al sistema.

[root@host ~]# subscription-manager attach --pool=<engine-subscription-pool>

5. Habilite el repositorio de Red Hat Ansible Engine.

[root@host ~]# subscription-manager repos \


> --enable ansible-2-for-rhel-8-x86_64-rpms

6. Instale Red Hat Ansible Engine.

[root@host ~]# yum install ansible

Si está utilizando la versión con soporte limitado provista con su suscripción de Red Hat Enterprise
Linux, use el siguiente procedimiento:

1. Habilite el repositorio de Red Hat Ansible Engine.

12 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

[root@host ~]# subscription-manager refresh


[root@host ~]# subscription-manager repos \
> --enable ansible-2-for-rhel-8-x86_64-rpms

2. Instale Red Hat Ansible Engine.

[root@host ~]# yum install ansible

Hosts administrados
Uno de los beneficios de Ansible es que los hosts administrados no necesitan tener un agente
especial instalado. El nodo de control de Ansible se conecta con los hosts administrados mediante
un protocolo de red estándar para garantizar que los sistemas tengan el estado especificado.

Los hosts administrados pueden tener algunos requisitos según el modo en que el nodo de control
se conecte con ellos y los módulos que se ejecutarán en ellos.

Los hosts administrados de Linux y UNIX deben tener Python 2 (versión 2.6 o posterior) o
Python 3 (versión 3.5 o posterior) instalado para que funcione la mayoría de los módulos.

Para Red Hat Enterprise Linux 8, puede ser capaz de depender del paquete platform-python.
También puede habilitar e instalar el flujo de aplicaciones python36 (o el flujo de aplicaciones
python27).

[root@host ~]# yum module install python36

Si SELinux está habilitado en los hosts administrados, también deberá asegurarse de que el
paquete python3-libselinux esté instalado antes de usar módulos que se relacionen con las
funciones de copia, archivo o plantilla. (Observe que si se instalan otros componentes de Python,
puede usar módulos de Ansible, como yum o package, para garantizar que este paquete también
esté instalado).

Importante
Algunos nombres de paquetes pueden ser diferentes en Red Hat Enterprise Linux 7
y versiones anteriores debido a la migración en curso a Python 3.

Para Red Hat Enterprise Linux 7 y versiones anteriores, instale el paquete python,
que proporciona Python 2. En lugar de python3-libselinux, tendrá que asegurarse de
que el paquete libselinux-python esté instalado.

Algunos módulos pueden tener sus propios requisitos adicionales. Por ejemplo, el módulo dnf,
que puede usarse para instalar paquetes en sistemas Fedora actuales, requiere el paquete
python3-dnf (python-dnf en RHEL 7).

RH294-RHEL8.0-es-1-20200501 13
capítulo 1 | Presentación de Ansible

nota
Algunos módulos no necesitan Python. Por ejemplo, los argumentos pasados
al módulo raw de Ansible se ejecutan directamente mediante la shell remota
configurada, en lugar de pasar por el subsistema del módulo. Esto puede ser útil
para administrar dispositivos que no tengan Python disponible o que no puedan
instalar Python, o para arrancar Python en un sistema que no lo tenga.

Sin embargo, el módulo raw es difícil de usar de manera idempotente segura. De


modo que si, en su lugar, puede usar un módulo normal, en general es mejor evitar
usar raw y módulos de comandos similares. Hablaremos sobre esto más adelante en
el curso.

Hosts administrados basados en Microsoft Windows


Ansible incluye varios módulos que están específicamente diseñados para sistemas Microsoft
Windows. Estos aparecen en la sección Módulos de Windows [https://docs.ansible.com/ansible/
latest/modules/list_of_windows_modules.html] del índice de módulos de Ansible

La mayoría de los módulos específicamente diseñados para hosts administrados Microsoft


Windows requiere PowerShell 3.0 o posterior en el host administrado en lugar de Python. Además,
los hosts administrados deben tener configurada la conexión remota de PowerShell. Ansible
también requiere al menos .NET Framework 4.0 o posterior para instalar en hosts administrados
de Windows.

Este curso usa hosts administrados basados en Linux en sus ejemplos y no profundiza sobre las
diferencias y los ajustes específicos necesarios cuando se gestionan hosts administrados basados
en Microsoft Windows. Puede encontrar más información en el sitio web de Ansible en https://
docs.ansible.com/ansible/latest/user_guide/windows.html.

Dispositivos de red administrados


También puede utilizar la automatización de Ansible para configurar dispositivos de red
administrados, como enrutadores y switches. Ansible incluye una gran cantidad de módulos
diseñados específicamente para este propósito. Esto incluye soporte para Cisco IOS, IOS XR y
NX-OS; Juniper Junos; Arista EOS; y dispositivos de red basados en VyOS, entre otros.

Puede escribir guías de Ansible para dispositivos de red utilizando las mismas técnicas básicas
que utiliza al escribir guías para servidores. Como la mayoría de los dispositivos de red no
pueden ejecutar Python, Ansible ejecuta módulos de red en el nodo de control, no en los hosts
administrados. Los métodos de conexión especiales también se utilizan para comunicarse
con dispositivos de red, generalmente utilizando CLI sobre SSH, XML sobre SSH o API sobre
HTTP(S).

Este curso no profundiza sobre la automatización de la administración de dispositivos de red.


Para obtener más información sobre este tema, consulte Ansible for Network Automation
[https://docs.ansible.com/ansible/latest/network/index.html] en el sitio web de la comunidad de
Ansible, o asista a nuestro curso alternativo Ansible for Network Automation (DO457) [https://
www.redhat.com/en/services/training/do457-ansible-network-automation].

14 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

Referencias
Página del manual (1)ansible

Principales políticas de soporte para Red Hat Ansible Automation


https://access.redhat.com/ansible-top-support-policies

Guía de instalación — Documentación Ansible


http://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

Guías de Windows — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/windows.html

Ansible para la automatización de redes & mdash; Documentación Ansible


https://docs.ansible.com/ansible/latest/network/index.html

RH294-RHEL8.0-es-1-20200501 15
capítulo 1 | Presentación de Ansible

Ejercicio Guiado

Instalación de Ansible
En este ejercicio, instalará Ansible en un nodo de control que ejecuta Red Hat
Enterprise Linux.

Resultado
Usted deberá ser capaz de instalar Ansible en un nodo de control.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student y ejecute lab
intro-install start. Este script de inicio configura el nodo de control.

[student@workstation ~]$ lab intro-install start

1. Instale Ansible en workstation de modo que se pueda usar como nodo de control.

[student@workstation ~]$ sudo yum install ansible


[sudo] password for student:
Loaded plugins: langpacks, search-disabled-repos
Resolving Dependencies
--> Running transaction check
...output omitted...
Is this ok [y/d/N]: y
...output omitted...

2. Verifique que Ansible esté instalado en el sistema. Ejecute el comando ansible con la
opción --version.

[student@workstation ~]$ ansible --version


ansible 2.8.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/student/.ansible/plugins/modules', '/
usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Apr 3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red
Hat 8.2.1-3)]

3. Verifique ansible_python_version en localhost con el módulo de configuración.

[student@workstation ~]$ ansible -m setup localhost | grep ansible_python_version


"ansible_python_version": "3.6.8",

16 RH294-RHEL8.0-es-1-20200501
capítulo 1 | Presentación de Ansible

Finalizar
En workstation, ejecute el script lab intro-install finish para limpiar este ejercicio.

[student@workstation ~]$ lab intro-install finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 17
capítulo 1 | Presentación de Ansible

Resumen
En este capítulo, aprendió lo siguiente:

• La automatización es una herramienta clave para mitigar los errores humanos y garantizar
rápidamente que su infraestructura de TI se encuentre en un estado correcto y coherente.

• Ansible es una plataforma de automatización de código abierto que puede adaptarse a muchos
flujos de trabajo y entornos diferentes.

• Ansible puede usarse para administrar muchos tipos de sistemas diferentes, incluidos los
servidores que ejecutan Linux, Microsoft Windows o UNIX, y dispositivos de red.

• Las guías de Ansible son archivos de texto legibles por humanos que describen el estado
deseado de una infraestructura de TI.

• Ansible está desarrollada en torno a una arquitectura sin agente en la cual Ansible se instala en
un nodo de control y los clientes no necesitan ningún software de agente especial.

• Ansible se conecta con hosts administrados con protocolos de red estándar, como SSH, y
ejecuta códigos o comandos en los hosts administrados para garantizar que tengan el estado
especificado por Ansible.

18 RH294-RHEL8.0-es-1-20200501
capítulo 2

Implementación de Ansible
Meta Configurar Ansible para administrar hosts y
ejecutar comandos ad hoc Ansible.

Objetivos • Describir los conceptos de inventario de Ansible


y administrar un archivo de inventario estático.
• Describir dónde se encuentran los archivos de
configuración de Ansible, cómo los selecciona
Ansible y editarlos para aplicar los cambios a la
configuración predeterminada.
• Ejecutar una única tarea de automatización
Ansible utilizando un comando ad hoc y explicar
algunos casos de uso de comandos ad hoc.

Secciones • Compilación de un inventario de Ansible (y


ejercicio guiado)
• Administración de archivos de configuración de
Ansible (y ejercicio guiado)
• Ejecución de comandos ad hoc (y ejercicio
guiado)

Trabajo de • Implementación de Ansible


laboratorio

RH294-RHEL8.0-es-1-20200501 19
capítulo 2 | Implementación de Ansible

Compilación de un inventario de Ansible

Objetivos
Tras finalizar esta sección, deberá ser capaz de describir los conceptos de inventario de Ansible y
de administrar un archivo de inventario estático.

Definición de inventario
Un inventario define un conjunto de hosts que Ansible administrará. Estos hosts también pueden
ser asignados a grupos, que pueden ser gestionados colectivamente. Los grupos pueden contener
grupos secundarios, y los hosts pueden ser miembros de múltiples grupos. El inventario también
puede establecer variables que se apliquen a los hosts y grupos que define.

Los inventarios de host se pueden definir de dos maneras diferentes. Un inventario de hosts
estático puede definirse por un archivo de texto. Un inventario de hosts dinámico puede estar
generado por un script u otro programa, según sea necesario, mediante proveedores de
información externos.

Especificación de hosts administrados con un


inventario estático
Un archivo de inventario estático es un archivo de texto que especifica los hosts administrados a
los que apunta Ansible. Puede escribir este archivo usando varios formatos diferentes, incluido un
estilo INI o YAML. El formato estilo INI es muy común y se usará para la mayoría de los ejemplos en
este curso.

nota
Hay múltiples formatos de inventario estático soportados por Ansible. En esta
sección, nos centramos en el más frecuente, el formato INI-style.

En su forma más simple, un archivo de inventario estático estilo INI es una lista de nombres de host
o direcciones IP de hosts administrados, cada uno en una línea única:

web1.example.com
web2.example.com
db1.example.com
db2.example.com
192.0.2.42

Sin embargo, normalmente organiza hosts administrados en grupos de hosts. Los grupos de hosts
le permiten ejecutar Ansible de manera más efectiva en comparación con un conjunto de sistemas.
En este caso, cada sección comienza con un nombre de grupo de hosts encerrado entre corchetes
([]). A continuación, siguen el nombre de host o una dirección IP para cada host administrado en el
grupo, cada uno en una línea única.

En el siguiente ejemplo, el inventario del host define dos grupos de hosts, webservers y db-
servers.

20 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[webservers]
web1.example.com
web2.example.com
192.0.2.42

[db-servers]
db1.example.com
db2.example.com

Los hosts pueden estar en múltiples grupos. De hecho, la práctica recomendada es organizar sus
hosts en múltiples grupos, posiblemente organizados de diferentes maneras, según el rol del host,
su ubicación física, ya sea en producción o no, y otras variables. Esto le permite aplicar fácilmente
reproducciones de Ansible a hosts específicos.

[webservers]
web1.example.com
web2.example.com
192.0.2.42

[db-servers]
db1.example.com
db2.example.com

[east-datacenter]
web1.example.com
db1.example.com

[west-datacenter]
web2.example.com
db2.example.com

[production]
web1.example.com
web2.example.com
db1.example.com
db2.example.com

[development]
192.0.2.42

Importante
Existen siempre dos grupos de hosts:

• El grupo de hosts all contiene todos los hosts detallados de manera explícita en
el inventario.

• El grupo de hosts ungrouped contiene todos los hosts detallados de manera


explícita en el inventario que no son miembros de ningún otro grupo.

RH294-RHEL8.0-es-1-20200501 21
capítulo 2 | Implementación de Ansible

Definición de grupos anidados


Los inventarios de host de Ansible pueden incluir grupos de grupos de hosts. Esto se logra
creando un nombre de grupo de host con el sufijo :children. En el siguiente ejemplo, se crea
un nuevo grupo, denominado north-america, que incluye todos los hosts de los grupos usa y
canada.

[usa]
washington1.example.com
washington2.example.com

[canada]
ontario01.example.com
ontario02.example.com

[north-america:children]
canada
usa

Un grupo puede tener hosts administrados y grupos secundarios como miembros. Por ejemplo, en
el inventario anterior, podría agregar una sección [north-america] que tenga su propia lista de
hosts administrados. Esta lista de hosts se fusionaría con los hosts adicionales que hereda el grupo
north-america de sus grupos secundarios.

Simplificación de las especificaciones de hosts con rangos


Puede especificar rangos en los nombres de hosts o direcciones IP para simplificar inventarios de
hosts de Ansible. Puede especificar rangos numéricos o alfabéticos. Los rangos tienen la siguiente
sintaxis:

[START:END]

Los rangos hacen coincidir todos los valores desde START hasta END, inclusive. Considere los
siguientes ejemplos:

• 192.168.[4:7].[0:255] coincide con todas las direcciones IPv4 en la red 192.168.4.0/22 (de
192.168.4.0 a 192.168.7.255).

• server[01:20].example.com coincide con todos los hosts denominados server01.example.com a


server20.example.com.

• [a:c].dns.example.com coincide con los hosts denominados a.dns.example.com,


b.dns.example.com y c.dns.example.com.

• 2001:db8::[a:f] coincide con todas las direcciones IPv6 de 2001:db8::a a 2001:db8::f.

Si se incluyen ceros a la izquierda en rangos numéricos, se utilizan en el patrón. El segundo


ejemplo que se muestra arriba no coincide con server1.example.com, pero coincide con
server07.example.com. Para ilustrar esto, el siguiente ejemplo usa rangos para simplificar las
definiciones de los grupos [usa] y [canada] del ejemplo anterior:

22 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[usa]
washington[1:2].example.com

[canada]
ontario[01:02].example.com

Verificación del inventario


De tener dudas, use el comando ansible para verificar la presencia de la máquina en el
inventario:

[user@controlnode ~]$ ansible washington1.example.com --list-hosts


hosts (1):
washington1.example.com
[user@controlnode ~]$ ansible washington01.example.com --list-hosts
[WARNING]: provided hosts list is empty, only localhost is available

hosts (0):

Puede ejecutar el siguiente comando para mostrar todos los hosts en un grupo:

[user@controlnode ~]$ ansible canada --list-hosts


hosts (2):
ontario01.example.com
ontario02.example.com

Importante
Si el inventario contiene un host y un grupo de hosts con el mismo nombre, el
comando ansible imprime una advertencia y el destinatario es el host. El grupo de
hosts se ignora.

Existen diversas maneras de tratar esta situación: la manera más fácil es garantizar
que los grupos de hosts no usen los mismos nombres que los hosts en el inventario.

Reemplazo de la ubicación del inventario


El archivo /etc/ansible/hosts se considera el archivo de inventario estático predeterminado
del sistema. Sin embargo, la práctica habitual es no utilizar ese archivo, sino definir una ubicación
diferente para los archivos de inventario en su archivo de configuración de Ansible. Esto se explica
en la siguiente sección.

Los comandos ansible y ansible-playbook que utiliz para ejecutar guías y comandos ad
hoc de Ansible más adelante en el curso también pueden especificar la ubicación de un archivo
de inventario en la línea de comandos con la opción --inventory PATHNAME o -i PATHNAME,
donde PATHNAME es la ruta al archivo de inventario deseado.

Definición de variables en el inventario


Los valores para las variables usadas por guías se pueden especificar en los archivos del inventario
de hosts. Estas variables solo se aplican a hosts específicos o grupos de hosts. Normalmente es

RH294-RHEL8.0-es-1-20200501 23
capítulo 2 | Implementación de Ansible

mejor definir estas variables de inventario en directorios especiales y no directamente en el archivo


de inventario. Este tema se analiza con mayor profundidad en otra parte del curso.

Descripción de un inventario dinámico


La información de inventario de Ansible también puede generarse de forma dinámica con la
información provista por bases de datos externas. La comunidad de código abierto ha escrito
varios scripts de inventario dinámicos que están disponibles desde el proyecto upstream de
Ansible. Si estos scripts no satisfacen sus necesidades, también puede escribir sus propios scripts.

Por ejemplo, un programa de inventario dinámico podría contactarse con su servidor de Red Hat
Satellite o su cuenta de Amazon EC2, y usar la información almacenada allí para construir un
inventario de Ansible. Dado que el programa hace esto cuando ejecuta Ansible, puede completar
el inventario con información actualizada provista por el servicio a medida que se agregan nuevos
hosts y se eliminan hosts anteriores.

Este tema se analiza en más detalle más adelante en el curso.

Referencias
Inventario: Documentación Ansible
http://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

24 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Ejercicio Guiado

Compilación de un inventario de Ansible


En este ejercicio, creará un nuevo inventario estático que contenga hosts y grupos.

Resultados
Deberá ser capaz de crear inventarios estáticos predeterminados y personalizados.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab deploy-inventory start. Este script


de inicio garantiza que se pueda acceder a los hosts administrados, servera, serverb,
serverc y serverd en la red.

[student@workstation ~]$ lab deploy-inventory start

1. Modifique /etc/ansible/hosts para incluir servera.lab.example.com como un


host administrado.

1.1. Añada servera.lab.example.com al final del archivo de inventario


predeterminado, /etc/ansible/hosts.

[student@workstation ~]$ sudo vim /etc/ansible/hosts


...output omitted...
## db-[99:101]-node.example.com

servera.lab.example.com

1.2. Continúe editando el archivo de inventario /etc/ansible/hosts mediante


la adición de un grupo [webservers] al final del archivo con el servidor
serverb.lab.example.com como miembro del grupo.

[student@workstation ~]$ sudo vim /etc/ansible/hosts


...output omitted...
## db-[99:101]-node.example.com

servera.lab.example.com

[webservers]
serverb.lab.example.com

2. Verifique los hosts administrados en el archivo de inventario /etc/ansible/hosts.

2.1. Use el comando ansible all --list-hosts para mostrar todos los hosts
administrados en el archivo de inventario. predeterminado

RH294-RHEL8.0-es-1-20200501 25
capítulo 2 | Implementación de Ansible

[student@workstation ~]$ ansible all --list-hosts


hosts (2):
servera.lab.example.com
serverb.lab.example.com

2.2. Use el comando ansible ungrouped --list-hosts para mostrar solo los hosts
administrados que no pertenecen a un grupo.

[student@workstation ~]$ ansible ungrouped --list-hosts


hosts (1):
servera.lab.example.com

2.3. Use el comando ansible webservers --list-hosts para mostrar solo los hosts
administrados que pertenecen al grupo webservers.

[student@workstation ~]$ ansible webservers --list-hosts


hosts (1):
serverb.lab.example.com

3. Cree un archivo de inventario estático personalizado denominado inventory en el


directorio de trabajo /home/student/deploy-inventory.
En la siguiente tabla, se encuentra la información sobre sus cuatro hosts administrados.
Asignará cada host a varios grupos con fines de administración según el propósito del host,
la ciudad donde se encuentra ubicado y el entorno de implementación al que pertenece.
Además, los grupos para ciudades de Estados Unidos (Raleigh y Mountain View) deben
configurarse como elementos secundarios del grupo us para que los hosts de Estados
Unidos puedan ser administrados como un grupo.

Especificaciones de inventario del servidor

Nombre de host Propósito Ubicación Entorno

servera.lab.example.com Servidor web Raleigh Desarrollo

serverb.lab.example.com Servidor web Raleigh Prueba

serverc.lab.example.com Servidor web Mountain View Producción

serverd.lab.example.com Servidor web Londres Producción

3.1. Cree el directorio de trabajo /home/student/deploy-inventory.

[student@workstation ~]$ mkdir ~/deploy-inventory

3.2. Cree un archivo inventory en el directorio de trabajo /home/student/deploy-


inventory. Utilice la tabla Especificaciones de inventario del servidor como guía.
Edite el archivo inventory y agregue el siguiente contenido:

26 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[student@workstation ~]$ cd ~/deploy-inventory


[student@workstation deploy-inventory]$ vim inventory
[webservers]
server[a:d].lab.example.com

[raleigh]
servera.lab.example.com
serverb.lab.example.com

[mountainview]
serverc.lab.example.com

[london]
serverd.lab.example.com

[development]
servera.lab.example.com

[testing]
serverb.lab.example.com

[production]
serverc.lab.example.com
serverd.lab.example.com

[us:children]
raleigh
mountainview

4. Use variaciones del comando ansible host-or-group -i inventory --list-hosts


para verificar los grupos y hosts administrados en el archivo de inventario /home/
student/deploy-inventory/inventory personalizado.

Importante
Su comando ansible debe incluir la opción -i inventory. Esto hace que
ansible use su archivo inventory en el directorio de trabajo actual en lugar del
archivo de inventario del sistema /etc/ansible/hosts.

4.1. Use el comando ansible all -i inventory --list-hosts para mostrar todos
los hosts administrados.

[student@workstation deploy-inventory]$ ansible all -i inventory --list-hosts


hosts (4):
servera.lab.example.com
serverb.lab.example.com
serverc.lab.example.com
serverd.lab.example.com

4.2. Use el comando ansible ungrouped -i inventory --list-hosts para


mostrar todos los hosts administrados que aparecen en el archivo de inventario pero

RH294-RHEL8.0-es-1-20200501 27
capítulo 2 | Implementación de Ansible

que no forman parte de un grupo. No hay hosts administrados sin grupo en este
archivo de inventario.

[student@workstation deploy-inventory]$ ansible ungrouped -i inventory \


> --list-hosts
[WARNING]: No hosts matched, nothing to do

hosts (0):

4.3. Use el comando ansible development -i inventory --list-hosts para


mostrar todos los hosts administrados que aparecen en el grupo development.

[student@workstation deploy-inventory]$ ansible development -i inventory \


> --list-hosts
hosts (1):
servera.lab.example.com

4.4. Use el comando ansible testing -i inventory --list-hosts para mostrar


todos los hosts administrados en el grupo testing.

[student@workstation deploy-inventory]$ ansible testing -i inventory \


> --list-hosts
hosts (1):
serverb.lab.example.com

4.5. Use el comando ansible production -i inventory --list-hosts para


mostrar todos los hosts administrados en el grupo production.

[student@workstation deploy-inventory]$ ansible production -i inventory \


> --list-hosts
hosts (2):
serverc.lab.example.com
serverd.lab.example.com

4.6. Use el comando ansible us -i inventory --list-hosts para mostrar todos


los hosts administrados en el grupo us.

[student@workstation deploy-inventory]$ ansible us -i inventory --list-hosts


hosts (3):
servera.lab.example.com
serverb.lab.example.com
serverc.lab.example.com

4.7. Se le recomienda experimentar con otras variaciones para confirmar las entradas del
host administrado en el archivo de inventario personalizado.

Finalizar
En workstation, ejecute el script lab deploy-inventory finish para limpiar este
ejercicio.

28 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[student@workstation ~]$ lab deploy-inventory finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 29
capítulo 2 | Implementación de Ansible

Administración de archivos de
configuración de Ansible

Objetivos
Tras completar esta sección, deberá ser capaz de describir dónde están ubicados los archivos
de configuración de Ansible, cómo los selecciona Ansible y editarlos para aplicar los cambios a la
configuración predeterminada.

Configuración de Ansible
El comportamiento de una instalación de Ansible puede personalizarse mediante la modificación
de los parámetros en el archivo de configuración de Ansible. Ansible elige su archivo de
configuración entre diversas posibles ubicaciones en el nodo de control.

Uso de /etc/ansible/ansible.cfg
El paquete ansible proporciona un archivo de configuración base ubicado en /etc/ansible/
ansible.cfg. Este archivo se usa si no se encuentra ningún otro archivo de configuración.

Uso de ~/.ansible.cfg
Ansible busca un archivo .ansible.cfg en el directorio principal del usuario. Esta configuración
se usa en lugar de /etc/ansible/ansible.cfg si existe y si no existe el archivo ansible.cfg
en el directorio de trabajo actual.

Uso de ./ansible.cfg
Si existe un archivo ansible.cfg en el directorio en el cual se ejecuta el comando ansible,
se usa en lugar del archivo global o del archivo personal del usuario. Esto permite que los
administradores creen una estructura de directorios donde se almacenen diferentes entornos o
proyectos en directorios separados, y que cada directorio contenga un archivo de configuración
adaptado con un exclusivo conjunto de parámetros.

Importante
La práctica recomendada es crear un archivo ansible.cfg en un directorio desde
el que ejecute comandos de Ansible. El directorio también contendría archivos
usados por su proyecto Ansible, como un inventario y una guía. Esta es la ubicación
más común usada para el archivo de configuración de Ansible. Es inusual usar un
archivo ~/.ansible.cfg o /etc/ansible/ansible.cfg en la práctica.

Uso de la variable de entorno ANSIBLE_CONFIG


Puede usar diferentes archivos de configuración si los coloca en diferentes directorios y, luego,
ejecuta comandos de Ansible desde el directorio correspondiente, pero este método puede
contener restricciones y ser difícil de administrar a medida que aumenta la cantidad de archivos de
configuración. Una opción más flexible es definir la ubicación del archivo de configuración con la
variable de entorno ANSIBLE_CONFIG. Cuando esta variable está definida, Ansible usa el archivo
de configuración que especifica la variable en lugar de alguno de los archivos de configuración
mencionados anteriormente.

30 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Precedencia de archivos de configuración


El orden de búsqueda para un archivo de configuración es de forma inversa a la lista anterior. El
primer archivo ubicado en el orden de búsqueda es el que selecciona Ansible. Ansible solo usa los
ajustes de configuración del primer archivo que encuentra.

Los archivos especificados por la variable de entorno ANSIBLE_CONFIG reemplazan todos los
demás archivos de configuración. Si no se establece esa variable, a continuación, se verifica el
directorio en el que se ejecutó el comando ansible en busca de un archivo ansible.cfg. Si
ese archivo no está presente, el directorio principal del usuario se verifica en busca de un archivo
.ansible.cfg. El archivo /etc/ansible/ansible.cfg global se usa únicamente si no se
encuentra ningún otro archivo de configuración. Si el archivo de configuración /etc/ansible/
ansible.cfg no está presente, Ansible usa los valores predeterminados que contiene.

Debido a la gran cantidad de ubicaciones donde se pueden colocar los archivos de configuración
de Ansible, puede ser confuso qué archivo de configuración está usando Ansible. Puede ejecutar
el comando ansible --version para identificar claramente la versión instalada de Ansible y el
archivo de configuración utilizado.

[user@controlnode ~]$ ansible --version


ansible 2.8.0
config file = /etc/ansible/ansible.cfg
...output omitted...

Otra manera de mostrar el archivo de configuración de Ansible activo es usar la opción -v cuando
se ejecutan comandos de Ansible en la línea de comandos.

[user@controlnode ~]$ ansible servers --list-hosts -v


Using /etc/ansible/ansible.cfg as config file
...output omitted...

Ansible solo usa los parámetros del archivo de configuración con la mayor precedencia. Aun
si existen otros archivos con menor precedencia, sus parámetros se omiten y no se combinan
con aquellos en el archivo de configuración seleccionado. Por lo tanto, si decide crear su propio
archivo de configuración en favor del archivo de configuración /etc/ansible/ansible.cfg
global, debe duplicar todos los parámetros deseados de ese archivo en su propio archivo de
configuración de su nivel de usuario. Los parámetros no definidos en el archivo de configuración
del nivel de usuario permanecerán establecidos con los valores predeterminados integrados, aun si
el archivo de configuración global establece otros valores.

Administración de parámetros en el archivo de


configuración
El archivo de configuración de Ansible consiste en varias secciones; cada sección contiene
parámetros definidos como pares de claves-valores. Los títulos de las secciones se incluyen entre
corchetes. Para la operación básica, use las siguientes dos secciones:

• [defaults] establece valores predeterminados para la operación de Ansible

• [privilege_escalation] configura el modo en que Ansible realiza la escalación de


privilegios en hosts administrados

Por ejemplo, el siguiente es un archivo ansible.cfg típico:

RH294-RHEL8.0-es-1-20200501 31
capítulo 2 | Implementación de Ansible

[defaults]
inventory = ./inventory
remote_user = user
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

Las directivas de este archivo se explican en la siguiente tabla:

Configuración de Ansible

Directiva Descripción

inventory Especifica la ruta al archivo de inventario.

remote_user El nombre del usuario para iniciar sesión como en los hosts
administrados. Si no se especifica, se usa el nombre del
usuario actual.

ask_pass Si se debe solicitar o no una contraseña SSH. Puede ser


false si se utiliza la autenticación de clave pública SSH.

become Si se debe cambiar automáticamente el usuario en el


host administrado (por lo general, a root) después de la
conexión. Esto también puede ser especificado por una
reproducción.

become_method Cómo cambiar de usuario (por lo general ,sudo, que es el


valor predeterminado, pero su es una opción).

become_user El usuario para cambiar en el host administrado (por lo


general, root, que es el valor predeterminado).

become_ask_pass Si se debe solicitar una contraseña para su


become_method . El valor predeterminado es false.

Configuración de conexiones
Ansible debe saber cómo comunicarse con sus hosts administrados. Uno de los motivos más
comunes para cambiar el archivo de configuración es controlar los métodos y usuarios que usa
Ansible para manejar hosts administrados. A continuación, se detalla parte de la información
necesaria:

• La ubicación del inventario que muestra los hosts y grupos de hosts administrados.

• Qué protocolo de conexión se debe usar para comunicarse con los hosts administrados (de
forma predeterminada, SSH), y si se necesita un puerto de red no estándar para conectarse con
el servidor.

• Qué usuario remoto se debe usar en los hosts administrados; este podría ser root o podría ser
un usuario sin privilegios.

32 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

• Si el usuario remoto no tiene privilegios, Ansible debe saber si debe intentar escalar los
privilegios a root y cómo hacerlo (por ejemplo, mediante el uso de sudo).

• Si se debe solicitar o no una contraseña SSH o una contraseña sudo para iniciar sesión u
obtener privilegios.

Ubicación del inventario


En la sección [defaults], la directiva inventory puede apuntar directamente a un archivo
de inventario estático o a un directorio que contenga múltiples archivos de inventario estático y
scripts de inventario dinámico.

[defaults]
inventory = ./inventory

Ajustes de conexión
De forma predeterminada, Ansible se conecta a los hosts administrados mediante el protocolo
SSH. Los parámetros más importantes que controlan el modo en que Ansible se conecta a los
hosts administrados se establecen en la sección [defaults].

De forma predeterminada, Ansible intenta conectarse a los hosts administrados con el mismo
nombre de usuario que el usuario local que ejecuta los comandos de Ansible. Para especificar un
usuario remoto diferente, establezca el parámetro remote_user con ese nombre de usuario.

Si el usuario local que ejecuta Ansible tiene claves SSH privadas configuradas que le permiten
autenticarse como el usuario remoto en los hosts administrados, Ansible inicia sesión de forma
automática. Si este no es el caso, puede configurar Ansible para que solicite al usuario local la
contraseña usada por el usuario remoto al establecer la directiva ask_pass = true.

[defaults]
inventory = ./inventory

remote_user = root
ask_pass = true

Suponiendo que usa un nodo de control de Linux y OpenSSH en sus hosts administrados, si
puede iniciar sesión en el usuario remoto con una contraseña, probablemente pueda configurar la
autenticación basada en claves mediante SSH, que le permitiría establecer ask_pass = false.

El primer paso es garantizar que el usuario en el nodo de control tenga un par de claves SSH
configurado en ~/.ssh. Puede ejecutar el comando ssh-keygen para lograr esto.

Para un solo host administrado existente, puede instalar su clave pública en el host administrado
y usar el comando ssh-copy-id para completar su archivo ~/.ssh/known_hosts local con su
clave de host, de la siguiente manera:

[user@controlnode ~]$ ssh-copy-id [email protected]


The authenticity of host 'web1.example.com (192.168.122.181)' can't be
established.
ECDSA key fingerprint is 70:9c:03:cd:de:ba:2f:11:98:fa:a0:b3:7c:40:86:4b.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter
out any that are already installed

RH294-RHEL8.0-es-1-20200501 33
capítulo 2 | Implementación de Ansible

/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted


now it is to install the new keys
[email protected]'s password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh '[email protected]'"


and check to make sure that only the key(s) you wanted were added.

nota
También puede usar una guía de Ansible para implementar su clave pública
en la cuenta remote_user en todos los hosts administrados con el módulo
authorized_key.

En este curso, aún no se analizan las Ansible Playbooks en detalle. Una reproducción
que garantice que su clave pública se implementa en las cuentas root de los hosts
administrados debe decir lo siguiente:

- name: Public key is deployed to managed hosts for Ansible


hosts: all

tasks:
- name: Ensure key is in root's ~/.ssh/authorized_hosts
authorized_key:
user: root
state: present
key: '{{ item }}'
with_file:
- ~/.ssh/id_rsa.pub

Dado que los hosts administrados aún no tendrían autenticación basada en claves
mediante SSH configurada, tendría que ejecutar la guía mediante el comando
ansible-playbook con la opción --ask-pass para que el comando se
autentique como usuario remoto.

Aumento de privilegios
Por motivos de seguridad y auditoría, Ansible puede tener que conectarse a hosts remotos
como un usuario sin privilegios antes de escalar privilegios para obtener acceso administrativo
como root. Esto se puede configurar en la sección [privilege_escalation] del archivo de
configuración de Ansible.

Para habilitar la escalación de privilegios de manera predeterminada, establezca la directiva


become = true en el archivo de configuración. Aunque esto se establezca de manera
predeterminada, existen diversas maneras de anularlo cuando se ejecutan comandos ad hoc o
guías de Ansible. (Por ejemplo, puede haber momentos en los que desea ejecutar una tarea o
reproducción que no aumente los privilegios).

La directiva become_method especifica cómo aumentar los privilegios. Hay varias opciones
disponibles, pero la opción predeterminada es utilizar sudo. Del mismo modo, la directiva
become_user especifica el usuario al que se desea escalar, pero el predeterminado es root.

34 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Si el mecanismo become_method elegido requiere que el usuario introduzca una contraseña para
aumentar los privilegios, puede establecer la directiva become_ask_pass = true en el archivo
de configuración.

nota
En Red Hat Enterprise Linux 7, la configuración predeterminada de /etc/sudoers
garantiza que todos los usuarios en el grupo wheel tengan la capacidad de utilizar
sudo para convertirse en root después de introducir su contraseña.

Una manera de permitir que un usuario (someuser en el siguiente ejemplo) utilice


sudo para convertirse en root sin una contraseña es instalando un archivo con las
directivas adecuadas en el directorio /etc/sudoers.d (propiedad de root, con
permisos octales 0400):

## password-less sudo for Ansible user


someuser ALL=(ALL) NOPASSWD:ALL

Examine las implicaciones de seguridad del enfoque que elija para la escalación de
privilegios. Las distintas organizaciones e implementaciones pueden tener distintas
ventajas y desventajas para considerar.

El siguiente archivo ansible.cfg de ejemplo supone que puede conectarse a los hosts
administrados como someuser mediante la autenticación basada en claves SSH, y que someuser
puede usar sudo para ejecutar comandos como root sin introducir una contraseña:

[defaults]
inventory = ./inventory
remote_user = someuser
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

Conexiones no SSH
El protocolo utilizado por Ansible para conectarse a hosts administrados se establece de manera
predeterminada en smart, que determina la manera más eficaz de utilizar SSH. Esto se puede
establecer de muchas otras maneras en otros valores.

Por ejemplo, existe una excepción a la regla de que SSH se utiliza de manera predeterminada.
Si no tiene localhost en su inventario, Ansible establece una entrada implicit localhost para
permitirle ejecutar comandos ad hoc y guías que se dirijan a localhost . Esta entrada de
inventario especial no se incluye en los grupos de hosts all o ungrouped. Además, en lugar de
usar el tipo de conexión SSH smart, Ansible se conecta de manera predeterminada mediante el
tipo de conexión local especial.

RH294-RHEL8.0-es-1-20200501 35
capítulo 2 | Implementación de Ansible

[user@controlnode ~]$ ansible localhost --list-hosts


[WARNING]: provided hosts list is empty, only localhost is available

hosts (1):
localhost

El tipo de conexión local ignora el parámetro remote_user y ejecuta comandos directamente


en el sistema local. Si se utiliza la escalación de privilegios, ejecuta sudo desde la cuenta de
usuario que ejecuta el comando Ansible, no remote_user. Esto puede generar confusión si los
dos usuarios tienen privilegios sudo diferentes.

Si quiere estar seguro de conectarse a localhost mediante SSH como otros hosts
administrados, un enfoque es enumerarlo en su inventario. Sin embargo, esta acción lo incluye en
los grupos all y ungrouped, situación que quizás usted no desea.

Otro enfoque es cambiar el protocolo usado para conectarse a localhost. La mejor manera
de hacerlo es establecer la ansible_connection variable de host para localhost .
Para ello, en el directorio desde el que ejecuta los comandos Ansible, cree un subdirectorio
host_vars. En ese subdirectorio, cree un archivo denominado localhost que contenga la línea
ansible_connection: smart. Esto garantiza que se use el protocolo de conexión (SSH)
smart en lugar de local para localhost.

Puede utilizar esto a la inversa. Si tiene 127.0.0.1 enumerado en su inventario, se conectará


a este de manera predeterminada mediante smart. También puede crear un archivo
host_vars/127.0.0.1 que contenga la línea ansible_connection: local y, en cambio,
utilizará local.

Las variables de host se analizan en más detalle posteriormente en el curso.

nota
También puede usar group variables para cambiar el tipo de conexión para un grupo
de hosts completo. Para ello, coloque los archivos con el mismo nombre como un
grupo en un directorio group_vars y asegúrese de que esos archivos contengan
parámetros para las variables de conexión.

Por ejemplo, puede querer que todos sus hosts administrados de Microsoft
Windows utilicen el protocolo winrm y el puerto 5986 para las conexiones. Para
configurar esto, puede colocar todos los hosts administrados en el grupo windows
y, luego, crear un archivo denominado group_vars/windows que contenga las
siguientes líneas:

ansible_connection: winrm
ansible_port: 5986

Comentarios de archivos de configuración


Existen dos caracteres de comentarios permitidos por los archivos de configuración Ansible: la
almohadilla o numeral (#), y el punto y coma (;).

El numeral al inicio de una línea comenta toda la línea. No debe estar en la misma línea con una
directiva.

36 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

El punto y coma comenta todo hacia la derecha en la línea. Puede estar en la misma línea que una
directiva, siempre que esa directiva se encuentre a su izquierda.

Referencias
Páginas del manual: ansible(1), ansible-config(1), ssh-keygen(1) y ssh-
copy-id(1)

Archivo de configuración: Documentación Ansible


https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html

RH294-RHEL8.0-es-1-20200501 37
capítulo 2 | Implementación de Ansible

Ejercicio Guiado

Administración de archivos de
configuración de Ansible
En este ejercicio, personalizará su entorno de Ansible al editar un archivo de configuración
de Ansible.

Resultados
Usted deberá ser capaz de crear un archivo de configuración para configurar su entorno de
Ansible con parámetros personalizados persistentes.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab deploy-manage start. Este script garantiza


que se pueda acceder al host administrado, servera, en la red.

[student@workstation ~]$ lab deploy-manage start

1. Cree el directorio /home/student/deploy-manage, que contendrá los archivos para


este ejercicio. Cambie a este directorio creado recientemente.

[student@workstation ~]$ mkdir ~/deploy-manage


[student@workstation ~]$ cd ~/deploy-manage

2. En su directorio /home/student/deploy-manage, use un editor de texto para iniciar la


edición de un nuevo archivo, ansible.cfg.
Cree una sección [defaults] en ese archivo. En esa sección, agregue una línea que
utilice la directiva inventory para especificar el archivo ./inventory como el inventario
predeterminado.

[defaults]
inventory = ./inventory

Guarde su trabajo y salga del editor de texto.

3. En el directorio /home/student/deploy-manage, use un editor de texto para iniciar la


edición del nuevo archivo de inventario estático, inventory.
El inventario estático debe contener cuatro grupos de hosts:

• [myself] debe contener el host localhost.


• [intranetweb] debe contener el host servera.lab.example.com.
• [internetweb] debe contener el host serverb.lab.example.com.
• [web] debe contener los grupos de hosts intranetweb e internetweb.

38 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

3.1. En /home/student/deploy-manage/inventory, agregue las siguientes líneas


para crear el grupo de hosts myself:

[myself]
localhost

3.2. En /home/student/deploy-manage/inventory, agregue las siguientes líneas


para crear el grupo de hosts intranetweb:

[intranetweb]
servera.lab.example.com

3.3. En /home/student/deploy-manage/inventory, agregue las siguientes líneas


para crear el grupo de hosts internetweb:

[internetweb]
serverb.lab.example.com

3.4. En /home/student/deploy-manage/inventory, agregue las siguientes líneas


para crear el grupo de hosts web:

[web:children]
intranetweb
internetweb

3.5. Confirme que su archivo inventory final tiene el siguiente aspecto:

[myself]
localhost

[intranetweb]
servera.lab.example.com

[internetweb]
serverb.lab.example.com

[web:children]
intranetweb
internetweb

Guarde su trabajo y salga del editor de texto.

4. Use el comando ansible con la opción --list-hosts para probar la configuración de


los grupos de hosts de su archivo de inventario. Esto no se conecta realmente a esos hosts.

[student@workstation deploy-manage]$ ansible myself --list-hosts


hosts (1):
localhost
[student@workstation deploy-manage]$ ansible intranetweb --list-hosts
hosts (1):
servera.lab.example.com
[student@workstation deploy-manage]$ ansible internetweb --list-hosts

RH294-RHEL8.0-es-1-20200501 39
capítulo 2 | Implementación de Ansible

hosts (1):
serverb.lab.example.com
[student@workstation deploy-manage]$ ansible web --list-hosts
hosts (2):
servera.lab.example.com
serverb.lab.example.com
[student@workstation deploy-manage]$ ansible all --list-hosts
hosts (3):
localhost
servera.lab.example.com
serverb.lab.example.com

5. Abra el archivo /home/student/deploy-manage/ansible.cfg en un editor de


texto. Agregue una sección [privilege_escalation] para configurar Ansible para
usar automáticamente el comando sudo a fin de cambiar de student a root cuando
se ejecuten tareas en los hosts administrados. Ansible también debería configurarse para
solicitarle la contraseña que usa student para el comando sudo.

5.1. Agregue la siguiente entrada para crear la sección [privilege_escalation[ en el


archivo de configuración /home/student/deploy-manage/ansible.cfg:

[privilege_escalation]

5.2. Establezca la directiva become en true para habilitar la escalación de privilegios.

become = true

5.3. Establezca la directiva become_method en sudo para configurar la escalación de


privilegios para usar el comando sudo.

become_method = sudo

5.4. Establezca la directiva become_user en root para configurar el usuario con


escalación de privilegios.

become_user = root

5.5. Establezca la directiva become_ask_pass en true para habilitar la solicitud de


contraseña para la escalación de privilegios.

become_ask_pass = true

5.6. Confirme que el archivo ansible.cfg completo se vea de la siguiente manera:

40 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[defaults]
inventory = ./inventory

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = true

Guarde su trabajo y salga del editor de texto.

6. Ejecute el comando ansible --list-hosts nuevamente para verificar que ahora se le


solicite la contraseña de sudo.
Cuando se le solicite la contraseña sudo, ingrese student, a pesar de que no se usa para
esta ejecución práctica.

[student@workstation deploy-manage]$ ansible intranetweb --list-hosts


BECOME password: student
hosts (1):
servera.lab.example.com

Finalizar
En workstation, ejecute el script lab deploy-manage finish para limpiar este ejercicio.

[student@workstation ~]$ lab deploy-manage finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 41
capítulo 2 | Implementación de Ansible

Ejecución de comandos ad hoc

Objetivos
Después de completar esta sección, debe ser capaz de ejecutar una única tarea de
automatización Ansible usando un comando ad hoc y explicar algunos casos de uso de comandos
ad hoc.

Ejecución de comandos ad hoc con Ansible


Un comando ad hoc es una manera de ejecutar una sola tarea de Ansible con rapidez; una que no
necesite guardar para ejecutarse nuevamente más tarde. Son operaciones simples, en línea, que
pueden ejecutarse sin escribir una guía.

Los comandos ad hoc son útiles para pruebas y cambios rápidos. Por ejemplo, puede usar un
comando ad hoc para asegurarse de que exista una determinada línea en el archivo /etc/hosts
en un grupo de servidores. Puede usar otro comando ad hoc para reiniciar un servicio de manera
eficiente en muchas máquinas diferentes o asegurarse de que un paquete de software específico
esté actualizado.

Los comandos ad hoc son una herramienta muy útil para realizar rápidamente tareas simples con
Ansible. Tienen sus límites y, en general, se recomienda usar Ansible Playbooks para desarrollar
la potencia máxima de Ansible. Sin embargo, en muchas situaciones, los comandos ad hoc son
exactamente la herramienta que necesita para realizar tareas simples de manera rápida.

Ejecución de comandos ad hoc


Use el comando ansible para ejecutar comandos ad hoc:

ansible host-pattern -m module [-a 'module arguments'] [-i inventory]

El argumento host-pattern se usa para especificar los hosts administrados en los cuales se debería
ejecutar el comando ad hoc. Podría ser un host administrado específico o un grupo de hosts en
el inventario. Ya vio esto, usado junto con la opción --list-hosts, que le muestra qué hosts
coinciden con un patrón de host específico. Ya vio también que puede usar la opción -i para
especificar una ubicación diferente del inventario para usar en lugar de la predeterminada en el
archivo de configuración actual de Ansible.

La opción -m toma como argumento el nombre del módulo que Ansible debería ejecutar en los
hosts de destino. Los módulos son pequeños programas que se ejecutan para implementar una
tarea. Algunos módulos no necesitan información adicional, pero otros necesitan argumentos
adicionales para especificar los detalles de su funcionamiento. La opción -a toma una lista de
estos argumentos como cadena entre comillas.

Uno de los comandos ad hoc más simples usa el módulo ping. Este módulo no realiza un
ping ICMP, sino que verifica para ver si lpuede ejecutar os módulos basados en Python en
hosts administrados. Por ejemplo, el siguiente comando ad hoc determina si todos los hosts
administrados en el inventario pueden ejecutar módulos estándares:

42 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[user@controlnode ~]$ ansible all -m ping


servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}

Realización de tareas con módulos con comandos ad hoc


Los módulos son las herramientas que los comandos ad hoc usan para realizar tareas. Ansible
proporciona cientos de módulos que realizan diferentes acciones. En general, puede buscar
un módulo probado, con un propósito especial, que realice lo que necesita como parte de la
instalación estándar.

El comando ansible-doc -l detalla todos los módulos instalados en un sistema. Puede usar
ansible-doc para ver la documentación de módulos específicos por nombre y para buscar
información respecto de los argumentos que los módulos toman como opciones. Por ejemplo, el
siguiente comando muestra documentación para el módulo ping:

[user@controlnode ~]$ ansible-doc ping


> PING (/usr/lib/python3.6/site-packages/ansible/modules/system/ping.py)

A trivial test module, this module always returns `pong' on successful


contact. It does not make sense in playbooks, but it is useful from `/usr/bin/
ansible' to
verify the ability to login and that a usable Python is configured. This
is NOT ICMP ping, this is just a trivial test module that requires Python on the
remote-node. For Windows targets, use the [win_ping] module instead. For
Network targets, use the [net_ping] module instead.

* This module is maintained by The Ansible Core Team


OPTIONS (= is mandatory):

- data
Data to return for the `ping' return value.
If this parameter is set to `crash', the module will cause an exception.
[Default: pong]
type: str

SEE ALSO:
* Module net_ping
The official documentation on the net_ping module.
https://docs.ansible.com/ansible/latest/modules/net_ping_module.html
* Module win_ping
The official documentation on the win_ping module.
https://docs.ansible.com/ansible/latest/modules/win_ping_module.html

AUTHOR: Ansible Core Team, Michael DeHaan


METADATA:
status:

RH294-RHEL8.0-es-1-20200501 43
capítulo 2 | Implementación de Ansible

- stableinterface
supported_by: core

EXAMPLES:

# Test we can logon to 'webservers' and execute python with json lib.
# ansible webservers -m ping

# Example from an Ansible Playbook


- ping:

# Induce an exception to see what happens


- ping:
data: crash

RETURN VALUES:

ping:
description: value provided with the data parameter
returned: success
type: str
sample: pong

Para obtener más información sobre los módulos, acceda a la documentación de Ansible en línea
en http://docs.ansible.com/ansible/latest/modules/modules_by_category.html.

En la siguiente tabla, se enumera una serie de ejemplos de módulos útiles. Existen muchos otros.

Módulos de Ansible

Categoría de módulo Los módulos

Módulos de archivos • copy: copiar un archivo local en el host administrado


• file: establecer permisos y otras propiedades de archivos
• lineinfile: garantizar que una línea particular esté o no esté en
un archivo
• synchronize: sincronizar contenido usando rsync

Módulos de paquete de • package: administrar los paquetes utilizando el gestor de


software paquetes autodetectado nativo del sistema operativo
• yum: administrar paquetes usando el administrador de paquetes
YUM
• apt: administrar paquetes usando el administrador de paquetes
APT
• dnf: administrar paquetes usando el administrador de paquetes
DNF
• gem: administrar gems de Ruby
• pip: administrar paquetes de Python desde PyPI

44 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Categoría de módulo Los módulos

Módulos del sistema • firewalld: administrar puertos y servicios arbitrarios con


firewalld
• reboot: reiniciar una máquina
• service: administrar servicios
• user: agregar, eliminar y administrar cuentas de usuario

Módulos de • get_url: descargar archivos por HTTP, HTTPS o FTP


herramientas de red • nmcli: administrar redes
• uri: interactuar con servicios web

La mayoría de los módulos toman argumentos. Puede encontrar la lista de argumentos disponibles
para un módulo en la documentación del módulo. Los comandos ad hoc pasan argumentos a
los módulos con la opción -a. Cuando no se necesite ningún argumento, omita la opción -a
del comando ad hoc. Si se deben especificar varios argumentos, suminístrelos como una lista
separada por espacios entre comillas.

Por ejemplo, el siguiente comando ad hoc usa el módulo user para asegurarse de que exista el
usuario newbie y que tenga un UID 4000 en servera.lab.example.com:

[user@controlnode ~]$ ansible -m user -a 'name=newbie uid=4000 state=present' \


> servera.lab.example.com
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"comment": "",
"createhome": true,
"group": 4000,
"home": "/home/newbie",
"name": "newbie",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 4000
}

La mayoría de los módulos son idempotent, lo que significa que pueden ejecutarse de forma
segura varias veces, y si el sistema ya tiene el estado correcto, no hacen nada. Por ejemplo, si se
ejecuta el comando ad hoc anterior nuevamente, este no debe informar ningún cambio:

[user@controlnode ~]$ ansible -m user -a 'name=newbie uid=4000 state=present' \


> servera.lab.example.com
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"append": false,
"changed": false
"comment": "",
"group": 4000,
"home": "/home/newbie",

RH294-RHEL8.0-es-1-20200501 45
capítulo 2 | Implementación de Ansible

"move_home": false,
"name": "newbie",
"shell": "/bin/bash",
"state": "present",
"uid": 4000
}

Ejecución de comandos arbitrarios en hosts administrados


El módulo command permite a los administradores ejecutar comandos arbitrarios en la línea de
comandos de hosts administrados. El comando que se debe ejecutar se especifica como un
argumento al módulo con la opción -a. Por ejemplo, el siguiente comando ejecuta el comando
hostname en el host administrado al que hace referencia el patrón del host mymanagedhosts.

[user@controlnode ~]$ ansible mymanagedhosts -m command -a /usr/bin/hostname


host1.lab.example.com | CHANGED | rc=0 >>
host1.lab.example.com
host2.lab.example.com | CHANGED | rc=0 >>
host2.lab.example.com

El ejemplo de comando ad hoc anterior arrojó dos líneas de salida para cada host administrado.
La primera línea es un informe de estado, donde se muestra el nombre del host administrado en el
que se ejecutó la operación ad hoc, así como el resultado de la operación. La segunda línea es la
salida del comando ejecutado de forma remota con el módulo command de Ansible.

Para obtener una mejor legibilidad y análisis de la salida del comando ad hoc, los administradores
pueden encontrar útil tener una sola línea de salida para cada operación realizada en un host
administrado. Utilice la opción -o para mostrar la salida de los comandos ad hoc de Ansible en un
formato de una sola línea.

[user@controlnode ~]$ ansible mymanagedhosts -m command -a /usr/bin/hostname -o


host1.lab.example.com | CHANGED | rc=0 >> (stdout) host1.lab.example.com
host2.lab.example.com | CHANGED | rc=0 >> (stdout) host2.lab.example.com

El módulo command permite a los administradores ejecutar rápidamente comandos remotos en


hosts administrados. Estos comandos no son procesados por la shell en los hosts administrados.
Como tal, no pueden acceder a las variables del entorno de la shell ni realizar operaciones de la
shell, como redirección y canalización.

nota
Si un comando ad hoc no especifica qué módulo usar con la opción -m, Red Hat
Ansible Engine usa el módulo command de manera predeterminada.

Para las situaciones en las que los comandos requieren procesamiento de la shell, los
administradores pueden usar el módulo shell. Al igual que el módulo command, pase los
comandos que se deben ejecutar como argumentos al módulo en un comando ad hoc. A
continuación, Ansible ejecuta el comando de forma remota en los hosts administrados. A
diferencia del módulo command, los comandos se procesan a través de una shell en los hosts
administrados. Por lo tanto, se podrá acceder a las variables del entorno de la shell, y también está
disponible el uso de las operaciones de la shell, como redirección y tubería.

46 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

El siguiente ejemplo ilustra la diferencia entre los módulos command y shell. Si intenta ejecutar el
comando Bash integrado, set, con estos dos módulos, solo es satisfactorio con el módulo shell.

[user@controlnode ~]$ ansible localhost -m command -a set


localhost | FAILED | rc=2 >>
[Errno 2] No such file or directory
[user@controlnode ~]$ ansible localhost -m shell -a set
localhost | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interact
ive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
...output omitted...

Ambos módulos command y shell requieren una instalación Python de trabajo en el host
administrado. Un tercer módulo, raw, puede ejecutar comandos directamente con la shell remota
y eludir el subsistema del módulo. Esto es útil cuando administra sistemas que no pueden tener
Python instalado (por ejemplo, un enrutador de red). También puede usarse para instalar Python
en un host.

Importante
En la mayoría de las circunstancias, la práctica recomendada es evitar los módulos
de "ejecución de comandos" command, shell y raw.

La mayoría de los demás módulos son idempotentes y pueden realizar el control


de cambios de forma automática. Pueden probar el estado de los sistemas y no
hacer nada si estos sistemas ya tienen el estado correcto. Por el contrario, es mucho
más complicado usar módulos de "ejecución de comandos" de modo que sean
idempotentes. Según estos, resulta difícil que confíe en que volver a ejecutar un
comando ad hoc o una guía no provocará una falla inesperada. Cuando un módulo
shell o command se ejecuta normalmente, informa un estado CHANGED (CON
CAMBIOS) basado en si cree que afectó el estado de la máquina.

Hay veces en las que los módulos de "ejecución de comandos" son herramientas
valiosas y una buena solución a un problema. Si no necesita usarlos, probablemente
sea mejor intentar usar el módulo command primero, y recurrir a los módulos shell
o raw solo si necesita sus funciones especiales.

Configuración de conexiones para comandos ad hoc


Las directivas para las conexiones de los hosts administrados y la escalación de privilegios se
pueden configurar en el archivo de configuración de Ansible, y también pueden definirse con las
opciones en los comandos ad hoc. Cuando se definen con las opciones en los comandos ad hoc,
prevalecen sobre la directiva configurada en el archivo de configuración de Ansible. En la siguiente
tabla, se muestran las opciones de la línea de comandos análogas para cada directiva del archivo
de configuración.

Opciones de la línea de comandos de Ansible

Directivas del archivo de configuración Opción de la línea de comandos

inventory -i

RH294-RHEL8.0-es-1-20200501 47
capítulo 2 | Implementación de Ansible

Directivas del archivo de configuración Opción de la línea de comandos

remote_user -u

become --become, -b

become_method --become-method

become_user --become-user

become_ask_pass --ask-become-pass, -K

Antes de configurar estas directivas con las opciones de la línea de comandos, sus valores
definidos actualmente pueden determinarse al consultar la salida de ansible --help.

[user@controlnode ~]$ ansible --help


...output omitted...
-b, --become run operations with become (nopasswd implied)
--become-method=BECOME_METHOD
privilege escalation method to use (default=sudo),
valid choices: [ sudo | su | pbrun | pfexec | runas |
doas ]
--become-user=BECOME_USER
...output omitted...
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=None)

Referencias
Página del manual (1)ansible

Trabajo con patrones: Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html

Introducción a los comandos ad hoc: Documentación de Ansible


http://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html

Índice de módulos: Documentación de Ansible


http://docs.ansible.com/ansible/latest/modules/modules_by_category

command: ejecuta un comando en un nodo remoto: Documentación de Ansible


http://docs.ansible.com/ansible/latest/modules/command_module.html

shell: ejecuta comandos en nodos: Documentación de Ansible


http://docs.ansible.com/ansible/latest/modules/shell_module.html

48 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Ejercicio Guiado

Ejecución de comandos ad hoc


En este ejercicio, ejecutará comandos ad hoc en varios hosts administrados.

Resultados
Usted debe poder ejecutar comandos ad hoc en hosts administrados con escalación de
privilegios.

Ejecutará comandos ad hoc en workstation y servera con la cuenta de usuario devops.


Esta cuenta tiene la misma configuración sudo en workstation y servera.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab deploy-adhoc start. Este script garantiza


que se pueda acceder al host administrado servera en la red. Además, crea y completa
el directorio de trabajo /home/student/deploy-adhoc con materiales usados en este
ejercicio.

[student@workstation ~]$ lab deploy-adhoc start

1. Determine la configuración sudo para la cuenta devops en workstation y servera.

1.1. Determine la configuración sudo para la cuenta devops que se configuró cuando se
creó workstation. Ingrese student si se le solicita la contraseña, para la cuenta
student.

[student@workstation ~]$ sudo cat /etc/sudoers.d/devops


[sudo] password for student: student
devops ALL=(ALL) NOPASSWD: ALL

Tenga en cuenta que el usuario tiene plenos privilegios sudo, pero no requiere
autenticación de contraseña.

1.2. Determine la configuración sudo para la cuenta devops que se configuró cuando se
creó servera.

[student@workstation ~]$ ssh [email protected]


[devops@servera ~]$ sudo cat /etc/sudoers.d/devops
devops ALL=(ALL) NOPASSWD: ALL
[devops@servera ~]$ exit

Tenga en cuenta que el usuario tiene plenos privilegios sudo, pero no requiere
autenticación de contraseña.

2. Cambie el directorio a /home/student/deploy-adhoc y examine el contenido de los


archivos ansible.cfg y inventory.

RH294-RHEL8.0-es-1-20200501 49
capítulo 2 | Implementación de Ansible

[student@workstation ~]$ cd ~/deploy-adhoc


[student@workstation deploy-adhoc]$ cat ansible.cfg
[defaults]
inventory=inventory
[student@workstation deploy-adhoc]$ cat inventory
[control_node]
localhost

[intranetweb]
servera.lab.example.com

El archivo de configuración usa el archivo inventory del directorio como inventario


de Ansible. Observe que aún no se ha configurado Ansible para usar la escalación de
privilegios.

3. Con el grupo de hosts all y el módulo ping, ejecute un comando ad hoc para asegurarse
de que todos los hosts administrados puedan ejecutar módulos de Ansible con Python.

[student@workstation deploy-adhoc]$ ansible all -m ping


servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
localhost | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}

4. Con el módulo command, ejecute un comando ad hoc en workstation para identificar la


cuenta de usuario usada por Ansible para realizar operaciones en los hosts administrados.
Use el patrón del host localhost para conectarse con workstation para la ejecución
del comando ad hoc. Dado que se conecta de forma local, workstation es tanto el nodo
de control como el host administrado.

[student@workstation deploy-adhoc]$ ansible localhost -m command -a 'id'


localhost | CHANGED | rc=0 >>
uid=1000(student) gid=1000(student) groups=1000(student),10(wheel)
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Observe que el comando ad hoc se ejecutó en el host administrado como usuario


student.

50 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

5. Ejecute el comando ad hoc anterior en workstation, pero conecte y realice la operación


con la cuenta de usuario devops con la opción -u.

[student@workstation deploy-adhoc]$ ansible localhost -m command -a 'id' -u devops


localhost | CHANGED | rc=0 >>
uid=1001(devops) gid=1001(devops) groups=1001(devops)
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Observe que el comando ad hoc se ejecutó en el host administrado como usuario devops.

6. Con el módulo copy, ejecute un comando ad hoc en workstation para cambiar el


contenido del archivo /etc/motd de modo que contenga la cadena "Managed by
Ansible" (Administrado por Ansible) seguida de una nueva línea. Ejecute el comando con la
cuenta devops, pero no use la opción --become para cambiar a root. El comando ad hoc
debe fallar debido a la falta de permisos.

[student@workstation deploy-adhoc]$ ansible localhost -m copy \


> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops
localhost | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"msg": "Destination /etc not writable"
}

El comando ad hoc falló porque el usuario devops no tiene permiso para escribir en el
archivo.

7. Ejecute el comando nuevamente usando la escalación de privilegios. Podría corregir los


ajustes en el archivo ansible.cfg; sin embargo, para este ejemplo, solo use las opciones
correctas de la línea de comandos del comando ansible.
Con el módulo copy, ejecute un comando anterior en workstation para cambiar
el contenido del archivo /etc/motd de modo que contenga la cadena "Managed by
Ansible" (Administrado por Ansible) seguida de una nueva línea. Use el usuario devops
para realizar la conexión con el host administrado, pero realice la operación con el usuario
root con la opción --become. El uso de la opción --become es suficiente porque el valor
predeterminado para la directiva become_user se establece en root en el archivo /etc/
ansible/ansible.cfg.

[student@workstation deploy-adhoc]$ ansible localhost -m copy \


> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops --become
localhost | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
"mode": "0644",

RH294-RHEL8.0-es-1-20200501 51
capítulo 2 | Implementación de Ansible

"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 19,
"src": "/home/devops/.ansible/tmp/ansible-
tmp-1558954193.0260043-131348380629718/source",
"state": "file",
"uid": 0
}

Tenga en cuenta que el comando se ejecutó satisfactoriamente esta vez porque el


comando ad hoc se ejecutó con escalación de privilegios.

8. Ejecute de nuevo el comando ad hoc anterior en todos los hosts usando el grupo de hosts
all. Esto garantiza que /etc/motd en workstation y servera contengan el texto
“Managed by Ansible” (Administrado por Ansible).

[student@workstation deploy-adhoc]$ ansible all -m copy \


> -a 'content="Managed by Ansible\n" dest=/etc/motd' -u devops --become
servera.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 19,
"src": "/home/devops/.ansible/tmp/ansible-
tmp-1558954250.7893758-136255396678462/source",
"state": "file",
"uid": 0
}
localhost | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/motd",
"secontext": "system_u:object_r:etc_t:s0",

52 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

"size": 19,
"state": "file",
"uid": 0
}

Debe ver SUCCESS para localhost y CHANGED para servera. Sin embargo, localhost
debe informar "changed": false, ya que el archivo ya tiene el estado correcto. Por
el contrario, servera debe informar "changed": true, ya que el comando ad hoc
actualizó el archivo con el estado correcto.

9. Con el módulo command, ejecute un comando ad hoc para ejecutar cat /etc/motd
a fin de verificar que el contenido del archivo se haya modificado correctamente en
workstation y servera. Use el grupo de hosts all y el usuario devops para especificar
los hosts administrados y realizar la conexión con ellos. No es necesario aumentar los
privilegios para que funcione este comando.

[student@workstation deploy-adhoc]$ ansible all -m command \


> -a 'cat /etc/motd' -u devops
servera.lab.example.com | CHANGED | rc=0 >>
Managed by Ansible

localhost | CHANGED | rc=0 >>


Managed by Ansible

Finalizar
En workstation, ejecute el script lab deploy-adhoc finish para limpiar este ejercicio.

[student@workstation ~]$ lab deploy-adhoc finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 53
capítulo 2 | Implementación de Ansible

Trabajo de laboratorio

Implementación de Ansible
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará un nodo de control de Ansible para las conexiones
con los hosts de inventario y usará comandos ad hoc para realizar acciones en hosts
administrados.

Resultados
Usted deberá ser capaz de configurar un nodo de control para ejecutar comandos ad hoc en
hosts administrados.

Usará Ansible para administrar varios hosts desde workstation.lab.example.com


con el usuario student. Configurará un directorio de proyecto que contenga un archivo
ansible.cfg con valores predeterminados específicos, y un directorio inventory que
contenga un archivo de inventario.

Usará comandos ad hoc para garantizar que el archivo /etc/motd en todos los hosts
administrados esté compuesto por contenido especificado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab deploy-review start. Este script garantiza


que se pueda acceder a los hosts administrados en la red.

[student@workstation ~]$ lab deploy-review start

1. Verifique que el paquete ansible esté instalado en el nodo de control y ejecute el comando
ansible --version.
2. En el directorio principal del usuario student en workstation, /home/student, cree un
nuevo directorio denominado deploy-review. Cambie a ese directorio.
3. Cree un archivo ansible.cfg en el directorio deploy-review, el cual usará para
configurar los siguientes valores predeterminados de Ansible:

• Conéctese con hosts administrados con el usuario devops.

• Use el subdirectorio inventory para contener el archivo de inventario.

• Deshabilite la escalación de privilegios de forma predeterminada. Si se habilita


la escalación de privilegios desde la línea de comandos, configure los valores
predeterminados para que Ansible use el método sudo para cambiar a la cuenta de
usuario root. Ansible no debería solicitar la contraseña de inicio de sesión devops ni la
contraseña sudo.

54 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Los hosts administrados se configuraron con un usuario devops que puede iniciar sesión
con autenticación basada en claves mediante SSH y que puede ejecutar cualquier comando
como root con el comando sudo sin contraseña.
4. Cree el directorio /home/student/deploy-review/inventory.
Descargue el archivo http://materials.example.com/labs/deploy-review/
inventory y guárdelo como un archivo de inventario estático denominado /home/
student/deploy-review/inventory/inventory.
5. Ejecute el comando id como comando ad hoc con el grupo de hosts all como destino
para verificar que devops es ahora el usuario remoto y que la escalación de privilegios está
deshabilitada de forma predeterminada.
6. Ejecute un comando ad hoc, con el grupo de hosts all como destino, que usa el módulo
copy para modificar el contenido del archivo /etc/motd en todos los hosts.
Use la opción content del módulo copy para garantizar que el archivo /etc/motd esté
compuesto por la cadena This server is managed by Ansible.\n (Este servidor es
administrado por Ansible.\n) como una sola línea. (\n, usado con la opción content, hace
que el módulo coloque una nueva línea al final de la cadena.)
Debe solicitar el aumento de privilegios desde la línea de comandos para hacer este trabajo
con sus valores predeterminados de ansible.cfg actuales.
7. Si ejecuta nuevamente el mismo comando ad hoc, debería ver que el módulo copy detecta
que los archivos ya son correctos, por lo que estos no se modifican. Busque el comando
ad hoc para informar SUCCESS y la línea "changed": false para cada host administrado.
8. Para confirmar esta otra manera, ejecute un comando ad hoc con el grupo all como destino,
con el módulo command para ejecutar el comando cat /etc/motd. La salida del comando
ansible debería mostrar la cadena This server is managed by Ansible. (Este
servidor es administrado por Ansible) para todos los hosts. No es necesario aumentar los
privilegios para este comando ad hoc.
9. Ejecute lab deploy-review grade en workstation para verificar su trabajo.

[student@workstation deploy-review]$ lab deploy-review grade

Finalizar
En workstation, ejecute el script lab deploy-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab deploy-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 55
capítulo 2 | Implementación de Ansible

Solución

Implementación de Ansible
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará un nodo de control de Ansible para las conexiones
con los hosts de inventario y usará comandos ad hoc para realizar acciones en hosts
administrados.

Resultados
Usted deberá ser capaz de configurar un nodo de control para ejecutar comandos ad hoc en
hosts administrados.

Usará Ansible para administrar varios hosts desde workstation.lab.example.com


con el usuario student. Configurará un directorio de proyecto que contenga un archivo
ansible.cfg con valores predeterminados específicos, y un directorio inventory que
contenga un archivo de inventario.

Usará comandos ad hoc para garantizar que el archivo /etc/motd en todos los hosts
administrados esté compuesto por contenido especificado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab deploy-review start. Este script garantiza


que se pueda acceder a los hosts administrados en la red.

[student@workstation ~]$ lab deploy-review start

1. Verifique que el paquete ansible esté instalado en el nodo de control y ejecute el comando
ansible --version.

1.1. Verifique que el paquete ansible esté instalado.

[student@workstation ~]$ yum list installed ansible


Installed Packages
ansible.noarch 2.8.0-1.el8ae @rhel-8-server-ansible-2.8-rpms

1.2. Ejecute el comando ansible --version para confirmar la versión de Ansible que
está instalada.

56 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[student@workstation ~]$ ansible --version


ansible 2.8.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/student/.ansible/plugins/modules', '/
usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Apr 3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red
Hat 8.2.1-3)]

2. En el directorio principal del usuario student en workstation, /home/student, cree un


nuevo directorio denominado deploy-review. Cambie a ese directorio.

[student@workstation ~]$ mkdir ~/deploy-review


[student@workstation ~]$ cd ~/deploy-review

3. Cree un archivo ansible.cfg en el directorio deploy-review, el cual usará para


configurar los siguientes valores predeterminados de Ansible:

• Conéctese con hosts administrados con el usuario devops.

• Use el subdirectorio inventory para contener el archivo de inventario.

• Deshabilite la escalación de privilegios de forma predeterminada. Si se habilita


la escalación de privilegios desde la línea de comandos, configure los valores
predeterminados para que Ansible use el método sudo para cambiar a la cuenta de
usuario root. Ansible no debería solicitar la contraseña de inicio de sesión devops ni la
contraseña sudo.

Los hosts administrados se configuraron con un usuario devops que puede iniciar sesión
con autenticación basada en claves mediante SSH y que puede ejecutar cualquier comando
como root con el comando sudo sin contraseña.

3.1. Use un editor de texto para crear el archivo /home/student/deploy-review/


ansible.cfg. Cree una sección [defaults]. Agregue una directiva de
remote_user para que Ansible use el usuario devops al conectarse con hosts
administrados. Agregue una directiva de inventory (inventario) para configurar
Ansible a fin de que use el directorio /home/student/deploy-review/inventory
como inventario predeterminado para el archivo de inventario.

[defaults]
remote_user = devops
inventory = inventory

3.2. En el archivo /home/student/deploy-review/ansible.cfg, cree la sección


[privilege_escalation] y agregue las siguientes entradas para deshabilitar el
aumento de privilegios. Establezca el método de aumento de privilegios para usar la
cuenta root con sudo, sin autenticación de contraseña.

RH294-RHEL8.0-es-1-20200501 57
capítulo 2 | Implementación de Ansible

[privilege_escalation]
become = False
become_method = sudo
become_user = root
become_ask_pass = False

3.3. Al completarse, se debería leer lo siguiente en el archivo ansible.cfg:

[defaults]
remote_user = devops
inventory = inventory

[privilege_escalation]
become = False
become_method = sudo
become_user = root
become_ask_pass = False

Guarde su trabajo y salga del editor.

4. Cree el directorio /home/student/deploy-review/inventory.


Descargue el archivo http://materials.example.com/labs/deploy-review/
inventory y guárdelo como un archivo de inventario estático denominado /home/
student/deploy-review/inventory/inventory.

4.1. Cree el directorio /home/student/deploy-review/inventory.

[student@workstation deploy-review]$ mkdir inventory

4.2. Descargue el archivo http://materials.example.com/labs/deploy-review/


inventory en el directorio /home/student/deploy-review/inventory.

[student@workstation deploy-review]$ wget -O inventory/inventory \


> http://materials.example.com/labs/deploy-review/inventory

4.3. Investigue el contenido del archivo /home/student/deploy-review/inventory/


inventory.

[student@workstation deploy-review]$ cat inventory/inventory


[internetweb]
serverb.lab.example.com

[intranetweb]
servera.lab.example.com
serverc.lab.example.com
serverd.lab.example.com

5. Ejecute el comando id como comando ad hoc con el grupo de hosts all como destino
para verificar que devops es ahora el usuario remoto y que la escalación de privilegios está
deshabilitada de forma predeterminada.

58 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

[student@workstation deploy-review]$ ansible all -m command -a 'id'


serverb.lab.example.com | CHANGED | rc=0 >>
uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u:
unconfined_r:unconfined_t:s0-s0:c0.c1023

serverc.lab.example.com | CHANGED | rc=0 >>


uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u:
unconfined_r:unconfined_t:s0-s0:c0.c1023

servera.lab.example.com | CHANGED | rc=0 >>


uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u:
unconfined_r:unconfined_t:s0-s0:c0.c1023

serverd.lab.example.com | CHANGED | rc=0 >>


uid=1001(devops) gid=1001(devops) groups=1001(devops) context=unconfined_u:
unconfined_r:unconfined_t:s0-s0:c0.c1023

Sus resultados pueden mostrarse en un orden diferente.


6. Ejecute un comando ad hoc, con el grupo de hosts all como destino, que usa el módulo
copy para modificar el contenido del archivo /etc/motd en todos los hosts.
Use la opción content del módulo copy para garantizar que el archivo /etc/motd esté
compuesto por la cadena This server is managed by Ansible.\n (Este servidor es
administrado por Ansible.\n) como una sola línea. (\n, usado con la opción content, hace
que el módulo coloque una nueva línea al final de la cadena.)
Debe solicitar el aumento de privilegios desde la línea de comandos para hacer este trabajo
con sus valores predeterminados de ansible.cfg actuales.

[student@workstation deploy-review]$ ansible all -m copy \


> -a 'content="This server is managed by Ansible.\n" dest=/etc/motd' --become
serverd.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "af74293c7b2a783c4f87064374e9417a",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"src": "/home/devops/.ansible/tmp/ansible-
tmp-1558954517.7426903-24998924904061/source",
"state": "file",
"uid": 0
}
servera.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},

RH294-RHEL8.0-es-1-20200501 59
capítulo 2 | Implementación de Ansible

"changed": true,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "af74293c7b2a783c4f87064374e9417a",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"src": "/home/devops/.ansible/tmp/ansible-
tmp-1558954517.7165847-103324013882266/source",
"state": "file",
"uid": 0
}
serverc.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "af74293c7b2a783c4f87064374e9417a",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"src": "/home/devops/.ansible/tmp/ansible-tmp-1558954517.75727-94151722302122/
source",
"state": "file",
"uid": 0
}
serverb.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "af74293c7b2a783c4f87064374e9417a",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"src": "/home/devops/.ansible/tmp/ansible-
tmp-1558954517.6649802-53313238077104/source",
"state": "file",
"uid": 0
}

60 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

7. Si ejecuta nuevamente el mismo comando ad hoc, debería ver que el módulo copy detecta
que los archivos ya son correctos, por lo que estos no se modifican. Busque el comando
ad hoc para informar SUCCESS y la línea "changed": false para cada host administrado.

[student@workstation deploy-review]$ ansible all -m copy \


> -a 'content="This server is managed by Ansible.\n" dest=/etc/motd' --become
serverb.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/motd",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"state": "file",
"uid": 0
}
serverc.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/motd",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"state": "file",
"uid": 0
}
serverd.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/motd",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,

RH294-RHEL8.0-es-1-20200501 61
capítulo 2 | Implementación de Ansible

"state": "file",
"uid": 0
}
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"checksum": "93d304488245bb2769752b95e0180607effc69ad",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/motd",
"secontext": "system_u:object_r:etc_t:s0",
"size": 35,
"state": "file",
"uid": 0
}

8. Para confirmar esta otra manera, ejecute un comando ad hoc con el grupo all como destino,
con el módulo command para ejecutar el comando cat /etc/motd. La salida del comando
ansible debería mostrar la cadena This server is managed by Ansible. (Este
servidor es administrado por Ansible) para todos los hosts. No es necesario aumentar los
privilegios para este comando ad hoc.

[student@workstation deploy-review]$ ansible all -m command -a 'cat /etc/motd'


serverb.lab.example.com | CHANGED | rc=0 >>
This server is managed by Ansible.

servera.lab.example.com | CHANGED | rc=0 >>


This server is managed by Ansible.

serverd.lab.example.com | CHANGED | rc=0 >>


This server is managed by Ansible.

serverc.lab.example.com | CHANGED | rc=0 >>


This server is managed by Ansible.

9. Ejecute lab deploy-review grade en workstation para verificar su trabajo.

[student@workstation deploy-review]$ lab deploy-review grade

Finalizar
En workstation, ejecute el script lab deploy-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab deploy-review finish

Esto concluye el trabajo de laboratorio.

62 RH294-RHEL8.0-es-1-20200501
capítulo 2 | Implementación de Ansible

Resumen
En este capítulo, aprendió lo siguiente:

• Cualquier sistema en el que se instale Ansible y que tenga acceso a las guías y los archivos
de configuración requeridos para administrar sistemas remotos (managed hosts [hosts
administrados]) se denomina un nodo de control.

• Los hosts administrados se definen en el inventario. Los patrones del host se usan para hacer
referencia a los hosts administrados definidos en un inventario.

• Los inventarios pueden ser archivos estáticos o pueden ser generados de forma dinámica
por un programa desde una fuente externa, como un servicio de directorio o un sistema de
administración de la nube.

• Ansible busca su archivo de configuración en varios lugares en orden de precedencia. Se usa el


primer archivo de configuración encontrado; todos los demás se omiten.

• El comando ansible se usa para realizar comandos ad hoc en hosts administrados.

• Los comandos ad hoc determinan la operación que se realizará mediante el uso de módulos y
sus argumentos, y pueden hacer uso de las características de aumento de privilegios de Ansible.

RH294-RHEL8.0-es-1-20200501 63
64 RH294-RHEL8.0-es-1-20200501
capítulo 3

Implementación de guías
Meta Escribir un Ansible Playbook simple y ejecutarlo
para automatizar tareas en varios hosts.

Objetivos • Escribir una guía de Ansible básica y ejecutarla


con el comando ansible-playbook.
• Escribir una guía que use varias reproducciones
y escalamiento de privilegios por reproducción.
• Usar con eficacia ansible-doc para aprender
a usar nuevos módulos a fin de implementar
tareas para una reproducción.

Secciones • Escritura y ejecución de guías (y ejercicio


guiado)
• Implementación de varias reproducciones (y
ejercicio guiado)

Trabajo de • Implementación de guías


laboratorio

RH294-RHEL8.0-es-1-20200501 65
capítulo 3 | Implementación de guías

Escritura y ejecución de guías

Objetivos
Tras finalizar esta sección, deberá ser capaz de escribir una guía de Ansible básica y ejecutarla con
el comando ansible-playbook.

Comandos ad hoc y guías de Ansible


Los comandos ad hoc pueden ejecutar una sola tarea simple respecto de un conjunto de hosts de
destino como un comando que se ejecuta una sola vez. Sin embargo, el poder real de Ansible se
encuentra en aprender a usar guías para ejecutar varias tareas complejas respecto de un conjunto
de hosts de destino de una manera fácilmente repetible.

Una reproducción es un conjunto ordenado de tareas que se ejecutan respecto de hosts


seleccionados de su inventario. Una guía es un archivo de texto que contiene una lista de una o
más reproducciones para ejecutar en un orden específico.

Las reproducciones le permiten modificar un conjunto complejo y extenso de tareas


administrativas manuales en una rutina fácilmente repetible con resultados predecibles y
satisfactorios. En una guía, puede guardar la secuencia de tareas en una reproducción de una
forma inmediatamente ejecutable y legible por el ojo humano. Las tareas en sí, debido a la
manera en la que se escriben, documentan los pasos necesarios para implementar su aplicación o
infraestructura.

Formato de una Ansible Playbook


Para ayudar a entender el formato de una guía, revise este comando ad hoc de un capítulo
anterior:

[student@workstation ~]$ ansible -m user -a "name=newbie uid=4000 state=present" \


> servera.lab.example.com

Este se puede reescribir como una reproducción de una sola tarea y se puede guardar en una guía.
La guía resultante puede verse de la siguiente manera:

Ejemplo 3.1. Una guía simple

---
- name: Configure important user consistently
hosts: servera.lab.example.com
tasks:
- name: newbie exists with UID 4000
user:
name: newbie
uid: 4000
state: present

66 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Una guía es un archivo de texto escrito en formato YAML, y se guarda generalmente con la
extensión yml. La guía usa sangría con caracteres de espacio para indicar la estructura de sus
datos. YAML no establece requisitos estrictos sobre cuántos espacios se usan para la sangría, pero
hay dos reglas básicas.

• Los elementos de datos en el mismo nivel en la jerarquía (como ítems en la misma lista) deben
tener la misma sangría.

• Los elementos que son elementos secundarios de otro elemento deben tener más sangría que
sus elementos principales.

También puede agregar líneas en blanco para la capacidad de lectura.

Importante
Solo el carácter de espacio se puede usar para sangría; no se permiten caracteres
de tabulación.

Si usa el editor de texto vi, puede aplicar algunos parámetros que pueden facilitar
la edición de sus guías. Por ejemplo, puede agregar la siguiente línea a su archivo
$HOME/.vimrc y, si vi detecta que usted está editando un archivo YAML, realiza
una sangría de dos espacios cuando presiona la tecla Tab y realiza una sangría
automática de las líneas posteriores.

autocmd FileType yaml setlocal ai ts=2 sw=2 et

La guía comienza con una línea que consiste en tres guiones (---) como un marcador del inicio de
documento. También puede finalizar con tres puntos (...) como marcador de fin del documento,
si bien en la práctica por lo general se omite.

Entre estos marcadores, la guía se define como una lista de reproducciones. Un elemento en una
lista YAML comienza con un solo guión seguido de un espacio. Por ejemplo, una lista YAML puede
verse de la siguiente manera:

- apple
- orange
- grape

En Ejemplo 3.1, “Una guía simple”, la línea después de --- comienza con un guión y comienza la
primera (y la única) reproducción en la lista de reproducciones.

Cada reproducción en sí es una recopilación de pares de claves-valores. Las claves en la misma


reproducción deben tener la misma sangría. El siguiente ejemplo muestra un fragmento de código
YAML con tres claves. Las primeras dos claves tienen valores simples. La tercera tiene una lista de
tres ítems como valor.

name: just an example


hosts: webservers
tasks:
- first
- second
- third

RH294-RHEL8.0-es-1-20200501 67
capítulo 3 | Implementación de guías

La reproducción original a modo de ejemplo tiene tres claves, name, hosts y tasks, porque todas
estas claves tienen la misma sangría.

La primera línea de la reproducción de ejemplo comienza con un guión y un espacio (que indican
que la reproducción es el primer ítem de una lista); luego, sigue la primera clave, el atributo name
(nombre). La clave name asocia una cadena arbitraria con la reproducción como etiqueta. Esta
identifica para qué es la reproducción. La clave name es opcional, pero se recomienda, ya que
ayuda a documentar su guía. Esto es especialmente útil cuando una guía contiene reproducciones
múltiples.

- name: Configure important user consistently

La segunda clave en la reproducción es un atributo hosts, que especifica los hosts respecto
de los cuales se deben ejecutar las tareas de la reproducción. Al igual que el argumento para el
comando ansible, el atributo hosts toma un patrón de host como valor, como los nombres de
los hosts administrados o grupos en el inventario.

hosts: servera.lab.example.com

Finalmente, la última clave en la reproducción es el atributo tasks (tareas), cuyo valor especifica
una lista de tareas para ejecutar para esta reproducción. Este ejemplo tiene una sola tarea que
ejecuta el módulo user con argumentos específicos (para garantizar que el usuario newbie exista
y tenga una UID de 4000).

tasks:
- name: newbie exists with UID 4000
user:
name: newbie
uid: 4000
state: present

El atributo tasks (tareas) es la parte de la reproducción que detalla realmente, en orden, las
tareas que se ejecutarán en los hosts administrados. Cada tarea en la lista es en sí una recopilación
de pares de claves-valores.

En este ejemplo, la única tarea en la reproducción tiene dos claves:

• name es una etiqueta opcional que documenta el propósito de la tarea. Es una buena idea
asignarles nombres a todas sus tareas para poder documentar el propósito de cada paso del
proceso de automatización.

• user es el módulo que se ejecutará para esta tarea. Sus argumentos se pasan como una
recopilación de pares de claves-valores, que son elementos secundarios del módulo (name, uid
y state).

A continuación, se incluye otro ejemplo de un atributo tasks con varias tareas, que usan el
módulo service para garantizar que varios servicios de red estén habilitados para iniciarse en el
arranque:

tasks:
- name: web server is enabled
service:
name: httpd
enabled: true

68 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

- name: NTP server is enabled


service:
name: chronyd
enabled: true

- name: Postfix is enabled


service:
name: postfix
enabled: true

Importante
El orden en el que se muestran las reproducciones y tareas en una guía es
importante, ya que Ansible las ejecuta en el mismo orden.

Las guías que vio hasta ahora son ejemplos básicos, y verá ejemplos más sofisticados de lo que
puede hacer con reproducciones y tareas a medida que continúe este curso.

Ejecución de guías
El comando ansible-playbook se usa para ejecutar guías. El comando se ejecuta en el nodo de
control y el nombre de la guía que debe ejecutarse se pasa como un argumento:

[student@workstation ~]$ ansible-playbook site.yml

Cuando ejecuta la guía, se genera la salida para mostrar la reproducción y las tareas que se están
ejecutando. En la salida, también se reportan los resultados de cada tarea ejecutada.

El siguiente ejemplo muestra el contenido de una guía simple y, luego, el resultado de su ejecución.

[student@workstation playdemo]$ cat webserver.yml


---
- name: play to setup web server
hosts: servera.lab.example.com
tasks:
- name: latest httpd version installed
yum:
name: httpd
state: latest
...output omitted...
[student@workstation playdemo]$ ansible-playbook webserver.yml

PLAY [play to setup web server] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [latest httpd version installed] ******************************************


changed: [servera.lab.example.com]

RH294-RHEL8.0-es-1-20200501 69
capítulo 3 | Implementación de guías

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

Observe que el valor de la clave name establecido para cada reproducción y tarea se muestra
cuando se ejecuta la guía. (La tarea Gathering Facts [Recopilación de datos] es una
tarea especial que el módulo setup en general ejecuta de forma automática al inicio de una
reproducción. Esto se analizará más adelante en el curso). En el caso de las guías con varias
reproducciones y tareas, el hecho de establecer los atributos name (nombre) facilita el monitoreo
del progreso de la ejecución de una guía.

También debe ver que la tarea latest httpd version installed (versión httpd más
reciente instalada) se cambie por servera.lab.example.com. Esto significa que la tarea
modificó algo en ese host para garantizar que se cumpla su especificación. En este caso, significa
que el paquete httpd probablemente no se instaló o no era la versión más reciente.

En general, las tareas en las Ansible Playbooks son idempotentes, y es seguro ejecutar una
guía varias veces. Si los hosts administrados de destino ya tienen el estado correcto, no se
deberían realizar cambios. Por ejemplo, supongamos que la guía del ejemplo anterior se ejecuta
nuevamente:

[student@workstation playdemo]$ ansible-playbook webserver.yml

PLAY [play to setup web server] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [latest httpd version installed] ******************************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0

Esta vez, todas las tareas pasaron con el estado ok y no se informaron cambios.

Aumento de detalles de la salida


La salida por defecto proporcionada por el comando ansible-playbook no proporciona
información detallada sobre la ejecución de la tarea. El comando ansible-playbook -v aporta
información adicional, con hasta cuatro niveles totales.

Configuración de detalles de la salida de la ejecución de la guía

Opción Descripción

-v Se muestran los resultados de la tarea.

-vv Se muestran tanto los resultados de la tarea como la configuración


de la tarea.

-vvv Incluye información acerca de las conexiones a los hosts


administrados.

70 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Opción Descripción

-vvvv Agrega opciones de detalle adicionales a los complementos


(plug-ins) de conexión, incluidos los usuarios que se usan en los
hosts administrados para ejecutar scripts, y los scripts que fueron
ejecutados.

Verificación de la sintaxis
Antes de ejecutar una guía, se recomienda realizar la verificación para garantizar que la sintaxis
de su contenido sea la correcta. El comando ansible-playbook ofrece una opción --syntax-
check, que se puede utilizar para verificar la sintaxis de una guía. El siguiente ejemplo muestra la
verificación correcta de la sintaxis de una guía.

[student@workstation ~]$ ansible-playbook --syntax-check webserver.yml

playbook: webserver.yml

Cuando falla la verificación de la sintaxis, se reporta un error de sintaxis. La salida también incluye
la ubicación aproximada del problema de sintaxis en la guía. El siguiente ejemplo muestra la
verificación de sintaxis fallida de una guía en donde falta el separador de espacio después del
atributo name para la reproducción.

[student@workstation ~]$ ansible-playbook --syntax-check webserver.yml


ERROR! Syntax Error while loading YAML.
mapping values are not allowed in this context

The error appears to have been in ...output omitted... line 3, column 8, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name:play to setup web server


hosts: servera.lab.example.com
^ here

Ejecución de un simulacro
Puede usar la opción -C para realizar un simulacro de la ejecución de la guía. Esto hace que
Ansible reporte los cambios que habrían ocurrido si se hubiese ejecutado la guía, aunque no realiza
ningún cambio real a los hosts administrados.

El siguiente ejemplo muestra la ejecución práctica de una guía que contiene una única tarea para
garantizar que la última versión del paquete httpd esté instalada en un host administrado. Observe
que la ejecución práctica informa que la tarea realizaría un cambio en el host administrado.

[student@workstation ~]$ ansible-playbook -C webserver.yml

PLAY [play to setup web server] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

RH294-RHEL8.0-es-1-20200501 71
capítulo 3 | Implementación de guías

TASK [latest httpd version installed] ******************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

Referencias
Página del manual: ansible-playbook(1)

Introducción a guías — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html

Guías — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks.html

Modo de verificación ("Simulacro") — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html

72 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Ejercicio Guiado

Escritura y ejecución de guías


En este ejercicio, escribirá y ejecutará una guía Ansible.

Resultados
Usted deberá ser capaz de escribir una guía con una sintaxis YAML básica y una estructura
de Ansible Playbook, y ejecutarla correctamente con el comando ansible-playbook.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab playbook-basic start. Esta función


garantiza que se pueda acceder a los hosts administrados, serverc.lab.example.com y
serverd.lab.example.com, en la red. También garantiza que el archivo de configuración
y el archivo de inventario Ansible correctos estén instalados en el nodo de control.

[student@workstation ~]$ lab playbook-basic start

Se creó el directorio de trabajo /home/student/playbook-basic en workstation para


este ejercicio. Este directorio ya se completó con un archivo de configuración ansible.cfg,
y un archivo de inventario inventory, que define un grupo web que incluye los dos hosts
administrados que se detallaron anteriormente como miembros.

En este directorio, use un editor de texto para crear una guía denominada site.yml. Esta
guía contiene una reproducción, que debe destinarse a miembros del grupo de host web. La
guía debería usar tareas para garantizar que se cumplan las siguientes condiciones en los hosts
administrados:

• El paquete httpd está presente, con el módulo yum.

• El archivo files/index.html local se copia en /var/www/html/index.html en cada host


administrado, con el módulo copy.

• El servicio httpd se inicia y se habilita con el módulo service.

Puede usar el comando ansible-doc para poder entender las palabras clave necesarias para
cada uno de los módulos.

Después de que se escriba la guía, verifique su sintaxis y, luego, use ansible-playbook para
ejecutar la guía a fin de implementar la configuración.

1. Cambie al directorio /home/student/playbook-basic.

[student@workstation ~]$ cd ~/playbook-basic

RH294-RHEL8.0-es-1-20200501 73
capítulo 3 | Implementación de guías

2. Use un editor de texto para crear una nueva guía denominada /home/student/
playbook-basic/site.yml. Comience a escribir una reproducción que destine los
hosts en el grupo de hosts web.

2.1. Cree y abra ~/playbook-basic/site.yml. La primera línea del archivo deberían


ser tres guiones para indicar el inicio de la guía.

---

2.2. La siguiente línea inicia la reproducción. Debe iniciar con un guión y un espacio antes
de la primera palabra clave en la reproducción. Asígnele a la reproducción el nombre
de una cadena arbitraria que documente el propósito de la reproducción, con la
palabra clave name.

---
- name: Install and start Apache HTTPD

2.3. Agregue un par palabra clave-valor hosts para especificar que la reproducción se
ejecute en hosts en el grupo de hosts web del inventario. Asegúrese de que la palabra
clave hosts esté indentada dos espacios para que se alinee con la palabra clave
name en la línea anterior.
El archivo site.yml completo ahora debe verse de la siguiente manera:

---
- name: Install and start Apache HTTPD
hosts: web

3. Continúe editando el archivo /home/student/playbook-basic/site.yml, y agregue


una palabra clave tasks y las tres tareas para su reproducción que se especificaron en las
instrucciones.

3.1. Agregue una palabra clave tasks con una sangría de dos espacios (alineada con la
palabra clave hosts) para iniciar la lista de tareas. Su archivo ahora debe verse de la
siguiente manera:

---
- name: Install and start Apache HTTPD
hosts: web
tasks:

3.2. Agregue la primera tarea. Aplique una sangría de cuatro espacios, e inicie la tarea con
un guión y un espacio; luego, asigne un nombre a la tarea, como httpd package
is present (el paquete httpd está presente). Use el módulo yum para esta tarea.
Agregue una sangría de dos espacios más a las palabras clave del módulo; configure
el nombre del paquete en httpd y el estado del paquete en present (presente). La
tarea debe verse de la siguiente manera:

- name: httpd package is present


yum:
name: httpd
state: present

74 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

3.3. Agregue la segunda tarea. Haga coincidir el formato de la tarea anterior y asígnele
un nombre a la tarea, como correct index.html is present (el index.html
correcto está presente). Use el módulo copy. Las palabras clave del módulo deben
configurar la clave src para files/index. html y la clave dest para /var/www/
html/index.html. La tarea debe verse de la siguiente manera:

- name: correct index.html is present


copy:
src: files/index.html
dest: /var/www/html/index.html

3.4. Agregue la tercera tarea para iniciar y habilitar el servicio httpd. Haga coincidir el
formato de las dos tareas anteriores y asígnele un nombre a la nueva tarea, como
httpd is started (se inició httpd). Use el módulo service para esta tarea.
Configure la clave name (nombre) del servicio en httpd, el state (estado) en
started (iniciado) y enabled (habilitado) en true (verdadero). La tarea debe
verse de la siguiente manera:

- name: httpd is started


service:
name: httpd
state: started
enabled: true

3.5. Su guía Ansible site.yml completa debe coincidir con el siguiente ejemplo.
Asegúrese de que la sangría de las palabras clave de su reproducción, la lista de
tareas y las palabras clave de cada tarea sean todas correctas.

---
- name: Install and start Apache HTTPD
hosts: web
tasks:
- name: httpd package is present
yum:
name: httpd
state: present

- name: correct index.html is present


copy:
src: files/index.html
dest: /var/www/html/index.html

- name: httpd is started


service:
name: httpd
state: started
enabled: true

Guarde el archivo y salga de su editor de texto.

4. Antes de ejecutar la guía, ejecute el comando ansible-playbook --syntax-check


site.yml para verificar que su sintaxis sea correcta. Si informa errores, corríjalos antes de
pasar al siguiente paso. Debe ver una salida similar a la siguiente:

RH294-RHEL8.0-es-1-20200501 75
capítulo 3 | Implementación de guías

[student@workstation playbook-basic]$ ansible-playbook --syntax-check site.yml

playbook: site.yml

5. Ejecute su guía. Lea la salida generada para garantizar que todas las tareas se hayan
completado satisfactoriamente.

[student@workstation playbook-basic]$ ansible-playbook site.yml

PLAY [Install and start Apache HTTPD] ******************************************

TASK [Gathering Facts] *********************************************************


ok: [serverd.lab.example.com]
ok: [serverc.lab.example.com]

TASK [httpd package is present] ************************************************


changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]

TASK [correct index.html is present] *******************************************


changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]

TASK [httpd is started] ********************************************************


changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]

PLAY RECAP *********************************************************************


serverc.lab.example.com : ok=4 changed=3 unreachable=0 failed=0
serverd.lab.example.com : ok=4 changed=3 unreachable=0 failed=0

6. Si todo fue bien, usted deberá ser capaz de ejecutar la guía por segunda vez y ver todas las
tareas completas sin cambios en los hosts administrados.

[student@workstation playbook-basic]$ ansible-playbook site.yml

PLAY [Install and start Apache HTTPD] ******************************************

TASK [Gathering Facts] *********************************************************


ok: [serverd.lab.example.com]
ok: [serverc.lab.example.com]

TASK [httpd package is present] ************************************************


ok: [serverd.lab.example.com]
ok: [serverc.lab.example.com]

TASK [correct index.html is present] *******************************************


ok: [serverc.lab.example.com]
ok: [serverd.lab.example.com]

TASK [httpd is started] ********************************************************


ok: [serverd.lab.example.com]

76 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

ok: [serverc.lab.example.com]

PLAY RECAP *********************************************************************


serverc.lab.example.com : ok=4 changed=0 unreachable=0 failed=0
serverd.lab.example.com : ok=4 changed=0 unreachable=0 failed=0

7. Use el comando curl para verificar que serverc y serverd se hayan configurado como
un servidor HTTPD.

[student@workstation playbook-basic]$ curl serverc.lab.example.com


This is a test page.
[student@workstation playbook-basic]$ curl serverd.lab.example.com
This is a test page.

Finalizar
En workstation, ejecute el script lab playbook-basic finish para limpiar los recursos
creados en este ejercicio.

[student@workstation ~]$ lab playbook-basic finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 77
capítulo 3 | Implementación de guías

Implementación de varias
reproducciones

Objetivos
Tras finalizar esta sección, usted deberá ser capaz de realizar lo siguiente:

• Escribir una guía que use varias reproducciones y aumento de privilegios por reproducción.

• Use con eficacia ansible-doc para aprender a usar nuevos módulos a fin de implementar
tareas para una reproducción.

Escritura de varias reproducciones


Una guía es un archivo YAML que contiene una lista de una o más reproducciones. Recuerde
que una sola reproducción es una lista ordenada de tareas para ejecutar respecto de hosts
seleccionados del inventario. Por lo tanto, si una guía contiene varias reproducciones, cada
reproducción puede aplicar sus tareas a un conjunto de hosts diferente.

Esto puede ser muy útil cuando se organiza una implementación compleja que puede involucrar
diferentes tareas en diferentes hosts. Puede escribir una guía que ejecute una reproducción
respecto de un conjunto de hosts y que, cuando esta finaliza, ejecute otra reproducción respecto
de otro conjunto de hosts.

Escribir una guía que contenga varias reproducciones es muy sencillo. Cada reproducción en la
guía se escribe como un ítem de lista de nivel superior en la guía. Cada reproducción es un ítem de
una lista que contiene las palabras clave de reproducciones habituales.

El siguiente ejemplo muestra una guía simple con dos reproducciones. La primera reproducción se
ejecuta respecto de web.example.com, y la segunda, respecto de database.example.com.

---
# This is a simple playbook with two plays

- name: first play


hosts: web.example.com
tasks:
- name: first task
yum:
name: httpd
status: present

- name: second task


service:
name: httpd
enabled: true

- name: second play


hosts: database.example.com
tasks:
- name: first task

78 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

service:
name: mariadb
enabled: true

Usuarios remotos y escalamiento de privilegios en las


reproducciones
Las reproducciones pueden usar usuarios remotos o parámetros de escalamiento de privilegios
para una reproducción diferentes a aquellos especificados por los valores predeterminados en el
archivo de configuración. Estos se establecen en la reproducción en sí en el mismo nivel que las
palabras clave hosts o tasks.

Atributos de usuario
Las tareas en guías se ejecutan generalmente a través de una conexión de red en los hosts
administrados. Al igual que con comandos ad hoc, la cuenta de usuario usada para la ejecución
de tareas depende de diferentes palabras clave en el archivo de configuración de Ansible, /etc/
ansible/ansible.cfg. El usuario que ejecuta las tareas puede estar definido por la palabra
clave remote_user. Sin embargo, si se activa el aumento de privilegios, otras palabras clave
como become_user también pueden causar un impacto.

Si el usuario remoto definido en la configuración Ansible para la ejecución de las tareas no


es adecuado, se lo puede sobrescribir usando la palabra clave remote_user dentro de una
reproducción.

remote_user: remoteuser

Atributos de escalamiento de privilegios


También se dispone de palabras clave adicionales para definir los parámetros de escalamiento
de privilegios desde dentro de una guía. El parámetro booleano become se puede utilizar para
habilitar o deshabilitar el escalamiento de privilegios, independientemente de cómo se define en el
archivo de configuración Ansible. Puede seleccionar yes (sí) o true (verdadero) para habilitar el
escalamiento de privilegios, o no o false (falso) para deshabilitarla.

become: true

Si se habilita el escalamiento de privilegios, la palabra clave become_method se puede utilizar


para definir el método de escalamiento de privilegios para usar durante una reproducción
específica. En el siguiente ejemplo, se especifica que se utilice sudo para el escalamiento de
privilegios.

become_method: sudo

Asimismo, con el escalamiento de privilegios habilitado, la palabra clave become_user puede


definir la cuenta del usuario que debe utilizarse para el escalamiento de privilegios dentro del
contexto de una reproducción específica.

become_user: privileged_user

El siguiente ejemplo demuestra el uso de estas palabras clave en una reproducción:

RH294-RHEL8.0-es-1-20200501 79
capítulo 3 | Implementación de guías

- name: /etc/hosts is up to date


hosts: datacenter-west
remote_user: automation
become: yes

tasks:
- name: server.example.com in /etc/hosts
lineinfile:
path: /etc/hosts
line: '192.0.2.42 server.example.com server'
state: present

Búsqueda de módulos para tareas


Documentación de módulos
La gran cantidad de módulos incluidos con Ansible brinda a los administradores muchas
herramientas para tareas administrativas comunes. Anteriormente en este curso, analizamos
el sitio web de documentación de Ansible en http://docs.ansible.com. El Índice de módulos en
el sitio web es una manera sencilla de examinar la lista de módulos enviados con Ansible. Por
ejemplo, los módulos para la gestión de usuarios y servicios se pueden encontrar en los Systems
Modules (Módulos de sistemas) y los módulos para la administración de bases de datos se pueden
encontrar en Database Modules (Módulos de bases de datos).

Por cada módulo, el sitio web de la documentación de Ansible brinda un resumen de sus funciones
e instrucciones sobre cómo se puede invocar cada función específica con opciones para el
módulo. La documentación también proporciona ejemplos útiles que muestran cómo usar cada
módulo y cómo establecer sus palabras clave en una tarea.

Ya trabajó con el comando ansible-doc para buscar información acerca de módulos instalados
en el sistema local. Como revisión, para ver una lista de los módulos disponibles en un nodo de
control, ejecute el comando ansible-doc -l. Esto muestra una lista de nombres de módulos y
una sinopsis de sus funciones.

[student@workstation modules]$ ansible-doc -l


a10_server Manage A10 Networks ... devices' server object.
a10_server_axapi3 Manage A10 Networks ... devices
a10_service_group Manage A10 Networks ... devices' service groups.
a10_virtual_server Manage A10 Networks ... devices' virtual servers.
...output omitted...
zfs_facts Gather facts about ZFS datasets.
znode Create, ... and update znodes using ZooKeeper
zpool_facts Gather facts about ZFS pools.
zypper Manage packages on SUSE and openSUSE
zypper_repository Add and remove Zypper repositories

Use el comando ansible-doc [module name] para mostrar documentación detallada de un


módulo. Como el sitio web de la documentación de Ansible, el comando provee una sinopsis de
la función del módulo, detalles de sus diferentes opciones, y ejemplos. En el siguiente ejemplo, se
muestra la documentación para el módulo yum.

80 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

[student@workstation modules]$ ansible-doc yum


> YUM (/usr/lib/python3.6/site-packages/ansible/modules/packaging/os/yum.py)

Installs, upgrade, downgrades, removes, and lists packages and groups with
the `yum' package manager. This module only works on Python 2. If you require
Python
3 support see the [dnf] module.

* This module is maintained by The Ansible Core Team


* note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

- allow_downgrade
Specify if the named package and version is allowed to downgrade a maybe
already installed higher version of that package. Note that setting
allow_downgrade=True can make this module behave in a non-idempotent way.
The task could end up with a set of packages that does not match the complete
list of
specified packages to install (because dependencies between the downgraded
package and others can cause changes to the packages which were in the earlier
transaction).
[Default: no]
type: bool
version_added: 2.4

- autoremove
If `yes', removes all "leaf" packages from the system that were originally
installed as dependencies of user-installed packages but which are no longer
required
by any such package. Should be used alone or when state is `absent'
NOTE: This feature requires yum >= 3.4.3 (RHEL/CentOS 7+)
[Default: no]
type: bool
version_added: 2.7

- bugfix
If set to `yes', and `state=latest' then only installs updates that have
been marked bugfix related.
[Default: no]
version_added: 2.6

- conf_file
The remote yum configuration file to use for the transaction.
[Default: (null)]
version_added: 0.6

- disable_excludes
Disable the excludes defined in YUM config files.
If set to `all', disables all excludes.
If set to `main', disable excludes defined in [main] in yum.conf.
If set to `repoid', disable excludes defined for given repo id.
[Default: (null)]
version_added: 2.7

RH294-RHEL8.0-es-1-20200501 81
capítulo 3 | Implementación de guías

- disable_gpg_check
Whether to disable the GPG checking of signatures of packages being
installed. Has an effect only if state is `present' or `latest'.
[Default: no]
type: bool
version_added: 1.2

- disable_plugin
`Plugin' name to disable for the install/update operation. The disabled
plugins will not persist beyond the transaction.
[Default: (null)]
version_added: 2.5

- disablerepo
`Repoid' of repositories to disable for the install/update operation.
These repos will not persist beyond the transaction. When specifying multiple
repos,
separate them with a `","'.
As of Ansible 2.7, this can alternatively be a list instead of `","'
separated string
[Default: (null)]

El comando ansible-doc también ofrece la opción -s, la cual genera una salida a modo de
ejemplo, la cual puede servir como modelo de cómo utilizar un módulo particular en una guía. Esta
salida puede servir como plantilla de inicio, la cual se puede incluir en una guía para implementar
el módulo para la ejecución de la tarea. Los comentarios se incluyen en la salida para recordarles a
los administradores el uso de cada opción. En el siguiente ejemplo, se muestra esta salida para el
módulo yum.

[student@workstation ~]$ ansible-doc -s yum


- name: Manages packages with the `yum' package manager
yum:
allow_downgrade: # Specify if the named package ...
autoremove: # If `yes', removes all "leaf" packages ...
bugfix: # If set to `yes', ...
conf_file: # The remote yum configuration file ...
disable_excludes: # Disable the excludes ...
disable_gpg_check: # Whether to disable the GPG ...
disable_plugin: # `Plugin' name to disable ...
disablerepo: # `Repoid' of repositories ...
download_only: # Only download the packages, ...
enable_plugin: # `Plugin' name to enable ...
enablerepo: # `Repoid' of repositories to enable ...
exclude: # Package name(s) to exclude ...
installroot: # Specifies an alternative installroot, ...
list: # Package name to run ...
name: # A package name or package specifier ...
releasever: # Specifies an alternative release ...
security: # If set to `yes', ...
skip_broken: # Skip packages with ...
state: # Whether to install ... or remove ... a package.
update_cache: # Force yum to check if cache ...

82 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

update_only: # When using latest, only update ...


use_backend: # This module supports `yum' ...
validate_certs: # This only applies if using a https url ...

Mantenimiento de módulos
Ansible se proporciona con una gran cantidad de módulos que pueden usarse para muchas tareas.
La comunidad creativa es muy activa, y estos módulos pueden estar en diferentes etapas del
desarrollo. Se espera que la documentación de ansible-doc para el módulo especifique quién
realiza el mantenimiento de ese módulo en la comunidad creativa de Ansible y cuál es el estado
de su desarrollo. Esto se indica en la sección METADATA al final de la salida de ansible-doc para
ese módulo.

El campo status registra el estado de desarrollo del módulo:

• stableinterface: las palabras clave del módulo son estables, y se harán todos los esfuerzos
para no eliminar palabras clave ni cambiar su significado.

• preview: el módulo está en la vista previa de tecnología y puede ser inestable; sus palabras
clave pueden cambiar, o puede requerir librerías o servicios web que estén sujetos a cambios
incompatibles.

• deprecated: el módulo es obsoleto y ya no estará disponible en alguna versión futura.

• removed: el módulo se eliminó de la versión, pero existe un stub con fines de documentación
para ayudar a usuarios anteriores a migrar a nuevos módulos.

nota
El estado stableinterface solo indica que la interfaz de un módulo es estable;
no califica la calidad del código del módulo.

El campo supported_by registra quién mantiene el módulo en la comunidad creativa de Ansible.


Los valores posibles son los siguientes:

• core: mantenido por los desarrolladores creativos "core" de Ansible e incluido siempre con
Ansible.

• curated: módulos enviados y mantenidos por partners o empresas en la comunidad. Los


mantenedores de estos módulos deben observar los problemas informados o extraer solicitudes
presentadas respecto del módulo. Los desarrolladores creativos "core" revisan los cambios
propuestos a los módulos protegidos después de que los encargados del mantenimiento de
la comunidad hayan aprobado los cambios. Los responsables "core" (principales) también
garantizan que se solucionen los problemas con estos módulos debido a cambios en el motor
de Ansible. Estos módulos se incluyen actualmente con Ansible, pero pueden empaquetarse de
forma separada en algún punto en el futuro.

• community: módulos no admitidos por los desarrolladores creativos "core", partners o


empresas, pero mantenidos completamente por la comunidad de código abierto general.
Los módulos en esta categoría se pueden utilizar en su totalidad, pero la tasa de respuesta
a problemas depende exclusivamente de la comunidad. Estos módulos también se incluyen
actualmente con Ansible, pero es muy probable que se empaqueten de forma separada en
algún momento en el futuro.

La comunidad creativa de Ansible tiene un rastreador de problemas para Ansible y sus módulos
integrados en https://github.com/ansible/ansible/issues.

RH294-RHEL8.0-es-1-20200501 83
capítulo 3 | Implementación de guías

Algunas veces, un módulo no existe para algo que desea hacer. Como usuario final, puede
escribir sus propios módulos privados u obtener módulos de un tercero. Ansible busca módulos
personalizados en la ubicación especificada por la variable del entorno ANSIBLE_LIBRARY o, si
no se estableció, por la palabra clave library en el archivo de configuración de Ansible actual.
Ansible también busca módulos personalizados en el directorio ./library, relacionados con la
guía que se está ejecutando actualmente.

library = /usr/share/my_modules

La información sobre la escritura de módulos va más allá del alcance de este curso. La
documentación sobre cómo hacer esto está disponible en https://docs.ansible.com/ansible/
latest/dev_guide/developing_modules.html.

Importante
Use el comando ansible-doc para buscar módulos y aprender a usarlos para sus
tareas.

De ser posible, intente evitar los módulos command, shell y raw en las guías, por
más simple que parezca su uso. Debido a que estos adoptan comandos arbitrarios,
es muy fácil programar guías no idempotentes con estos módulos.

Por ejemplo, la siguiente tarea que usa el módulo shell no es idempotente. Cada
vez que se ejecuta la reproducción, reescribe /etc/resolv.conf aunque ya
conste de la línea nameserver 192.0.2.1.

- name: Non-idempotent approach with shell module


shell: echo "nameserver 192.0.2.1" > /etc/resolv.conf

Hay varias maneras para escribir tareas que usen el módulo shell de manera
idempotente, y algunas veces, realizar estas modificaciones y usar shell es
el mejor enfoque. Una solución más rápida puede ser usar ansible-doc para
descubrir el módulo copy y usarlo para obtener el efecto deseado.

El siguiente ejemplo no reescribe el archivo /etc/resolv.conf si ya consta del


contenido correcto:

- name: Idempotent approach with copy module


copy:
dest: /etc/resolv.conf
content: "nameserver 192.0.2.1\n"

El módulo copy comprueba si ya se alcanzó el estado y, de ser así, no realiza


cambios. El módulo shell permite mucha flexibilidad, pero también requiere de
más atención para garantizar que se ejecute de manera idempotente.

Las guías idempotentes se pueden ejecutar de manera repetida para garantizar que
los sistemas se encuentren en un estado particular sin interrumpir esos sistemas si
ya lo están.

84 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Variaciones de sintaxis de las guías


La última parte de este capítulo investiga algunas variaciones de la sintaxis de la guía de Ansible o
YAML que puede encontrar.

Comentarios en YAML
Los comentarios también se pueden utilizar para asistir a la capacidad de lectura. En YAML, todo
lo que está a la derecha del número o símbolo numeral (#) es un comentario. Si hay contenido a la
izquierda del comentario, coloque un espacio delante del símbolo numérico.

# This is a YAML comment

some data # This is also a YAML comment

Cadenas en YAML
Por lo general, no es necesario colocar entre comillas las cadenas en YAML, inclusive si hay
espacios contenidos en la cadena. Puede incluir cadenas entre comillas dobles o comillas simples.

this is a string

'this is another string'

"this is yet another a string"

Existen dos formas de escribir cadenas de líneas múltiples. Puede usar el carácter de barra vertical
(|) para denotar que deben preservarse los caracteres de nueva línea dentro de una cadena.

include_newlines: |
Example Company
123 Main Street
Atlanta, GA 30303

También puede escribir cadenas de líneas múltiples usando el carácter mayor que (>) para indicar
que los caracteres de nueva línea se deben convertir a espacios y que se deben quitar los espacios
en blanco en las líneas. A menudo, este método se usa para dividir cadenas extensas en caracteres
de espacio a fin de que puedan abarcar múltiples líneas para una mejor capacidad de lectura.

fold_newlines: >
This is an example
of a long string,
that will become
a single sentence once folded.

Diccionarios en YAML
Hemos visto recopilaciones de pares de claves-valores escritos como un bloque con sangría, de la
siguiente manera:

RH294-RHEL8.0-es-1-20200501 85
capítulo 3 | Implementación de guías

name: svcrole
svcservice: httpd
svcport: 80

Los diccionarios también pueden escribirse en un formato de bloque en línea entre llaves, de la
siguiente manera:

{name: svcrole, svcservice: httpd, svcport: 80}

En la mayoría de los casos, se debe evitar el formato de bloque en línea, ya que es difícil de leer.
Sin embargo, existe al menos una situación en la que se usa más comúnmente. Más adelante
en este curso hablaremos sobre el uso de roles. Cuando una guía incluye una lista de roles,
es más común usar esta sintaxis para facilitar la distinción de los roles que se incluyen en una
reproducción de las variables que se pasan a un rol.

Listas en YAML
También hemos visto listas escritas con la sintaxis normal de un solo guión:

hosts:
- servera
- serverb
- serverc

Las listas también tienen un formato en línea entre corchetes que se ve de la siguiente manera:

hosts: [servera, serverb, serverc]

Debe evitar esta sintaxis porque generalmente es más difícil de leer.

Abreviatura de guía de clave=valor obsoleto


Algunas guías pueden usar un método de abreviatura antiguo para definir tareas, y ponen los pares
de claves-valores para el módulo en la misma línea que el nombre del módulo. Por ejemplo, puede
ver esta sintaxis:

tasks:
- name: shorthand form
service: name=httpd enabled=true state=started

En general, escribiría la misma tarea de la siguiente manera:

tasks:
- name: normal form
service:
name: httpd
enabled: true
state: started

En general, debe evitar la forma de abreviatura y usar la forma normal.

86 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

La forma normal tiene más líneas, pero es más fácil para trabajar. Las palabras clave de la tarea
se apilan verticalmente y son más fáciles de diferenciar. Sus ojos pueden recorrer la reproducción
hacia abajo con menos movimiento de izquierda a derecha. Además, la sintaxis normal es YAML
nativa, mientras que la abreviatura no lo es. Las herramientas de resaltado de sintaxis en editores
de texto modernos pueden ayudarlo de manera más efectiva si usa el formato normal en lugar del
formato abreviado.

Puede encontrar esta sintaxis en documentación y guías anteriores de otras personas, y la sintaxis
aún funciona.

Referencias
Páginas del manual: ansible-playbook(1) y ansible-doc(1)

Introducción a guías — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html

Guías — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks.html

Desarrollo de módulos — Documentación Ansible


https://docs.ansible.com/ansible/latest/dev_guide/developing_modules.html

Soporte de módulos — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/modules_support.html

Sintaxis YAML — Documentación Ansible


https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

RH294-RHEL8.0-es-1-20200501 87
capítulo 3 | Implementación de guías

Ejercicio Guiado

Implementación de varias
reproducciones
En este ejercicio, creará una guía que contiene varias reproducciones y, luego, la usará para
realizar tareas de configuración en hosts administrados.

Resultados
Usted deberá ser capaz de construir y ejecutar una guía para gestionar la configuración y
realizar la administración de un host administrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab playbook-multi start. Esta función


garantiza que se puede acceder al host administrado, servera.lab.example.com, en
la red. También garantiza que el archivo de configuración y el archivo de inventario Ansible
correctos estén instalados en el nodo de control.

[student@workstation ~]$ lab playbook-multi start

1. Se creó un directorio de trabajo, /home/student/playbook-multi, en workstation


para el proyecto de Ansible. El directorio ya se completó con un archivo de configuración
ansible.cfg y un archivo de inventario inventory. El host administrado,
servera.lab.example.com, ya está definido en este archivo de inventario. Cree una
nueva guía, /home/student/playbook-multi/intranet.yml, y agregue las líneas
necesarias para iniciar la primera reproducción. Debería apuntar al host administrador
servera.lab.example.com y habilitar el escalamiento de privilegios.

1.1. Cambie el directorio al directorio de trabajo, /home/student/playbook-multi.

[student@workstation ~]$ cd ~/playbook-multi


[student@workstation playbook-multi]$

1.2. Cree y abra una nueva guía, /home/student/playbook-multi/intranet.yml,


y agregue una línea que conste de tres guiones al comienzo del archivo para indicar el
comienzo del archivo YAML.

---

1.3. Agregue la siguiente línea al archivo /home/student/playbook-multi/


intranet.yml para denotar el comienzo de una reproducción con un nombre de
Enable intranet services (Habilitar servicios de intranet).

- name: Enable intranet services

88 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

1.4. Agregue la siguiente línea para indicar que la reproducción se aplica al host
administrado servera.lab.example.com. Asegúrese de aplicar una sangría de
dos espacios en la línea (y alinearla con la palabra clave name sobre esta) para indicar
que es parte de la primera reproducción.

hosts: servera.lab.example.com

1.5. Agregue la siguiente línea para permitir el escalamiento de privilegios. Asegúrese


de aplicar una sangría de dos espacios en la línea (y alinearla con las palabras claves
sobre esta) para indicar que es parte de la primera reproducción.

become: yes

1.6. Agregue la siguiente línea para definir el comienzo de la lista tasks. Aplique una
sangría de dos espacios en la línea (y alinearla con las palabras claves sobre esta)
para indicar que es parte de la primera reproducción.

tasks:

2. Como primera tarea en la primera reproducción, defina una tarea que garantice que los
paquetes httpd y firewalld estén actualizados.
Asegúrese de aplicar una sangría de cuatro espacios a la primera línea de la tarea. Bajo la
palabra clave tasks en la primera reproducción, agregue las siguientes líneas.

- name: latest version of httpd and firewalld installed


yum:
name:
- httpd
- firewalld
state: latest

La primera línea aporta un nombre descriptivo para la tarea. La segunda línea tiene una
sangría de seis espacios e invoca al módulo yum. La siguiente línea tiene una sangría de
ocho espacios y es una palabra clave name. Especifica qué paquetes debe garantizar que
estén actualizados el módulo yum. La palabra clave name del módulo yum (que es diferente
del nombre de la tarea) puede tomar una lista de paquetes, que tienen una sangría de
diez espacios en las dos líneas siguientes. Después de la lista, la palabra clave state con
una sangría de ocho espacios especifica que el módulo yum debe asegurarse de que esté
instalada la versión más reciente de los paquetes.

3. Agregue una tarea a la lista de la primera reproducción que garantice que el contenido
correcto esté en /var/www/html/index.html.
Agregue las siguientes líneas para definir el contenido de /var/www/html/index.html.
Asegúrese de aplicar una sangría de cuatro espacios a la primera línea.

- name: test html page is installed


copy:
content: "Welcome to the example.com intranet!\n"
dest: /var/www/html/index.html

La primera entrada aporta un nombre descriptivo para la tarea. La segunda entrada está
marcada con seis espacios e invoca al módulo copy. Las entradas restantes tienen una

RH294-RHEL8.0-es-1-20200501 89
capítulo 3 | Implementación de guías

sangría de ocho espacios y envían los argumentos necesarios para garantizar que el
contenido correcto esté en la página web.

4. Defina dos tareas más en la reproducción para garantizar que se esté ejecutando el servicio
firewalld y que se iniciará en el arranque, y permita conexiones con el servicio httpd.

4.1. Agregue las siguientes líneas para garantizar que el servicio firewalld esté
habilitado y ejecutándose. Asegúrese de aplicar una sangría de cuatro espacios a la
primera línea.

- name: firewalld enabled and running


service:
name: firewalld
enabled: true
state: started

La primera entrada aporta un nombre descriptivo para la tarea. La segunda entrada


está marcada con ocho espacios y llama al módulo service. Las entradas restantes
tienen una sangría de diez espacios y envían los argumentos necesarios para
garantizar que el servicio firewalld esté habilitado y se haya ejecutado.

4.2. Agregue las siguientes líneas para garantizar que firewalld permita conexiones
HTTP desde los sistemas remotos. Asegúrese de aplicar una sangría de cuatro
espacios a la primera línea.

- name: firewalld permits access to httpd service


firewalld:
service: http
permanent: true
state: enabled
immediate: yes

La primera entrada aporta un nombre descriptivo para la tarea. La segunda entrada


está marcada con seis espacios e invoca al módulo firewalld. Las entradas
restantes tienen una sangría de ocho espacios y envían los argumentos necesarios
para garantizar que se permitan conexiones HTTP remotas permanentemente.

5. Agregue una tarea final a la primera reproducción que garantice que el servicio httpd se
esté ejecutando y que se iniciará en el arranque.
Agregue las siguientes líneas para garantizar que el servicio httpd esté habilitado y
ejecutándose. Asegúrese de aplicar una sangría de cuatro espacios a la primera línea.

- name: httpd enabled and running


service:
name: httpd
enabled: true
state: started

La primera entrada aporta un nombre descriptivo para la tarea. La segunda entrada está
marcada con seis espacios e invoca al módulo service. Las entradas restantes están
marcadas con ocho espacios y envían los argumentos necesarios para garantizar que el
servicio httpd esté habilitado y en funcionamiento.

90 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

6. En /home/student/playbook-multi/intranet.yml, defina una segunda


reproducción destinada a localhost que probará el servidor web de la intranet. No
necesita aumento de privilegios.

6.1. Agregue la siguiente línea para definir el comienzo de una segunda reproducción.
Tenga en cuenta que no hay sangría.

- name: Test intranet web server

6.2. Agregue la siguiente línea para indicar que la reproducción se aplica al host
administrado localhost. Asegúrese de aplicar una sangría de dos espacios a la línea
para indicar que está contenida por la segunda reproducción.

hosts: localhost

6.3. Agregue la siguiente línea para deshabilitar el aumento de privilegios. Asegúrese de


alinear la sangría con la palabra clave hosts sobre ella.

become: no

6.4. Agregue la siguiente línea al archivo /home/student/playbook-multi/


intranet.yml para definir el comienzo de la lista tasks. Asegúrese de aplicar una
sangría de dos espacios a la línea para indicar que está contenida por la segunda
reproducción.

tasks:

7. Agregue una sola tarea a la segunda reproducción y use el módulo uri para solicitar
contenido de http://servera.lab.example.com. La tarea debe verificar un código de
estado HTTP de retorno de 200. Configure la tarea para colocar el contenido devuelto en la
variable de resultados de la tarea.
Agregue las siguientes líneas para crear la tarea a fin de verificar el servicio web del nodo de
control. Asegúrese de aplicar una sangría de cuatro espacios a la primera línea.

- name: connect to intranet web server


uri:
url: http://servera.lab.example.com
return_content: yes
status_code: 200

La primera línea aporta un nombre descriptivo para la tarea. La segunda línea tiene una
sangría de seis espacios y llama al módulo uri. Las líneas restantes tienen una sangría de
ocho espacios y envían los argumentos necesarios para ejecutar una consulta de contenido
web del nodo de control al host administrado y verifican el código de estado recibido. La
palabra clave return_content garantiza que la respuesta del servidor se agregue a los
resultados de la tarea.

8. Verifique que la guía final /home/student/playbook-multi/intranet.yml refleje el


siguiente contenido estructurado; luego, guarde y cierre el archivo.

RH294-RHEL8.0-es-1-20200501 91
capítulo 3 | Implementación de guías

---
- name: Enable intranet services
hosts: servera.lab.example.com
become: yes
tasks:
- name: latest version of httpd and firewalld installed
yum:
name:
- httpd
- firewalld
state: latest

- name: test html page is installed


copy:
content: "Welcome to the example.com intranet!\n"
dest: /var/www/html/index.html

- name: firewalld enabled and running


service:
name: firewalld
enabled: true
state: started

- name: firewalld permits access to httpd service


firewalld:
service: http
permanent: true
state: enabled
immediate: yes

- name: httpd enabled and running


service:
name: httpd
enabled: true
state: started

- name: Test intranet web server


hosts: localhost
become: no
tasks:
- name: connect to intranet web server
uri:
url: http://servera.lab.example.com
return_content: yes
status_code: 200

9. Ejecute el comando ansible-playbook --syntax-check para verificar la sintaxis de la


guía /home/student/playbook-multi/intranet.yml.

[student@workstation playbook-multi]$ ansible-playbook --syntax-check intranet.yml

playbook: intranet.yml

92 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

10. Ejecute la guía con la opción -v para ver los resultados detallados para cada
tarea. Lea la salida generada para asegurarse de que todas las tareas se hayan
completado satisfactoriamente. Verifique que una solicitud HTTP GET para http://
servera.lab.example.com proporcione el contenido correcto.

[student@workstation playbook-multi]$ ansible-playbook -v intranet.yml


...output omitted...

PLAY [Enable intranet services] *************************************************

TASK [Gathering Facts] **********************************************************


ok: [servera.lab.example.com]

TASK [latest version of httpd and firewalld installed] **************************


changed: [servera.lab.example.com] => {"changed": true, ...output omitted...

TASK [test html page is installed] **********************************************


changed: [servera.lab.example.com] => {"changed": true, ...output omitted...

TASK [firewalld enabled and running] ********************************************


ok: [servera.lab.example.com] => {"changed": false, ...output omitted...

TASK [firewalld permits http service] *******************************************


changed: [servera.lab.example.com] => {"changed": true, ...output omitted...

TASK [httpd enabled and running] ************************************************


changed: [servera.lab.example.com] => {"changed": true, ...output omitted...

PLAY [Test intranet web server] *************************************************

TASK [Gathering Facts] **********************************************************


ok: [localhost]

TASK [connect to intranet web server] *******************************************


ok: [localhost] => {"accept_ranges": "bytes", "changed": false, "connection": "cl
ose", "content" : "Welcome to the example.com intranet!\n", "content_length":
"37", "content_type": "text/html; charset=UTF-8", "cookies": {}, "cookies_string
": "", "date": "...output omitted...", "etag": "\"25-5790ddbcc5a48\"",
"last_modified": "...output omitted...", "msg": "OK (37 bytes)", "redir
ected": false, "server": "Apache/2.4.6 (Red Hat Enterprise Linux)",
"status" : 200, "url": "http://servera.lab.example.com"}

PLAY RECAP **********************************************************************


localhost : ok=2 changed=0 unreachable=0 failed=0
servera.lab.example.com : ok=6 changed=4 unreachable=0 failed=0

El servidor respondió con el contenido deseado, Welcome to the example.com


intranet!\n (Bienvenidos a la intranet de example.com\n).
El servidor respondió con un código de estado HTTP de 200.

Finalizar
En workstation, ejecute el comando lab playbook-multi finish para limpiar los recursos
creados en este ejercicio.

RH294-RHEL8.0-es-1-20200501 93
capítulo 3 | Implementación de guías

[student@workstation ~]$ lab playbook-multi finish

Esto concluye el ejercicio guiado.

94 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Trabajo de laboratorio

Implementación de guías
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará y realizará tareas administrativas en hosts
administrados usando una guía.

Resultados
Debería construir y ejecutar una guía para instalar, configurar y verificar el estado de los
servicios web y de las bases de datos en un host administrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab playbook-review start. Esta función


garantiza que se puede acceder al host administrado, serverb.lab.example.com, en
la red. También garantiza que el archivo de configuración y el archivo de inventario Ansible
correctos estén instalados en el nodo de control.

[student@workstation ~]$ lab playbook-review start

Se creó un directorio de trabajo, /home/student/playbook-review, en


workstation para el proyecto de Ansible. El directorio ya se completó con un archivo
de configuración ansible.cfg y un archivo inventory. El host administrado,
serverb.lab.example.com, ya está definido en este archivo de inventario.

nota
La guía usada por este trabajo de laboratorio es muy similar a la que escribió en el
ejercicio guiado anterior en este capítulo. Si no desea crear la guía de este trabajo
de laboratorio desde cero, puede usar la guía del ejercicio como punto de partida
para este trabajo de laboratorio.

Si hace esto, tenga cuidado de apuntar a los hosts correctos y cambie las tareas
para que coincidan con las instrucciones para este ejercicio.

1. Cree una nueva guía, /home/student/playbook-review/internet.yml, y agregue las


entradas necesarias para iniciar una primera reproducción denominada Enable internet
services (Habilitar servicios de Internet) y especifique su host administrado previsto,
serverb.lab.example.com. Agregue una entrada para permitir el aumento de privilegios
y otra para iniciar una lista de tareas.
2. Agregue las entradas requeridas al archivo /home/student/playbook-review/
internet.yml para definir una tarea que instale las últimas versiones de los paquetes
firewalld, httpd, mariadb-server, php y php-mysqlnd.

RH294-RHEL8.0-es-1-20200501 95
capítulo 3 | Implementación de guías

3. Agregue las entradas necesarias al archivo /home/student/playbook-review/


internet.yml para definir las tareas de configuración del firewall. Deben asegurarse de
que el servicio firewalld esté enabled (habilitado) y running (en ejecución), y que se
permita el acceso al servicio httpd.
4. Agregue las tareas necesarias para asegurar que los servicios httpd y mariadb estén en los
estados enabled y running.
5. Agregue las entradas necesarias para definir la tarea final a fin de generar
contenido web para realizar pruebas. Use el módulo get_url para copiar http://
materials.example.com/labs/playbook-review/index.php a /var/www/html/
en el host administrado.
6. En /home/student/playbook-review/internet.yml, defina otra reproducción para
que la tarea se realice en el nodo de control. Esta reproducción probará el acceso al servidor
web que debería estar ejecutándose en el host administrado serverb. Esta reproducción no
requiere aumento de privilegios y se ejecutará en el host administrado localhost.
7. Agregue una tarea que pruebe el servicio web que se ejecuta en serverb desde el nodo de
control usando el módulo uri. Compruebe si existe un código de estado de retorno de 200.
8. Verifique la sintaxis de la guía internet.yml.
9. Use el comando ansible-playbook para ejecutar la guía. Lea la salida generada para
garantizar que todas las tareas se hayan completado satisfactoriamente.

Evaluación
Evalúe su trabajo ejecutando el comando lab playbook-review grade de su máquina
workstation. Corrija los errores informados y vuelva a ejecutar el script hasta obtener un
resultado satisfactorio.

[student@workstation ~]$ lab playbook-review grade

Finalizar
En workstation, ejecute el script lab playbook-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab playbook-review finish

Esto concluye el trabajo de laboratorio.

96 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Solución

Implementación de guías
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará y realizará tareas administrativas en hosts
administrados usando una guía.

Resultados
Debería construir y ejecutar una guía para instalar, configurar y verificar el estado de los
servicios web y de las bases de datos en un host administrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab playbook-review start. Esta función


garantiza que se puede acceder al host administrado, serverb.lab.example.com, en
la red. También garantiza que el archivo de configuración y el archivo de inventario Ansible
correctos estén instalados en el nodo de control.

[student@workstation ~]$ lab playbook-review start

Se creó un directorio de trabajo, /home/student/playbook-review, en


workstation para el proyecto de Ansible. El directorio ya se completó con un archivo
de configuración ansible.cfg y un archivo inventory. El host administrado,
serverb.lab.example.com, ya está definido en este archivo de inventario.

nota
La guía usada por este trabajo de laboratorio es muy similar a la que escribió en el
ejercicio guiado anterior en este capítulo. Si no desea crear la guía de este trabajo
de laboratorio desde cero, puede usar la guía del ejercicio como punto de partida
para este trabajo de laboratorio.

Si hace esto, tenga cuidado de apuntar a los hosts correctos y cambie las tareas
para que coincidan con las instrucciones para este ejercicio.

1. Cree una nueva guía, /home/student/playbook-review/internet.yml, y agregue las


entradas necesarias para iniciar una primera reproducción denominada Enable internet
services (Habilitar servicios de Internet) y especifique su host administrado previsto,
serverb.lab.example.com. Agregue una entrada para permitir el aumento de privilegios
y otra para iniciar una lista de tareas.

1.1. Agregue la siguiente entrada al comienzo de /home/student/playbook-review/


internet.yml para comenzar con el formato YAML.

---

RH294-RHEL8.0-es-1-20200501 97
capítulo 3 | Implementación de guías

1.2. Agregue la siguiente entrada para denotar el comienzo de una reproducción con un
nombre de Enable internet services (Habilitar servicios de internet).

- name: Enable internet services

1.3. Agregue la siguiente entrada para indicar que la reproducción se aplica al host
administrado serverb.

hosts: serverb.lab.example.com

1.4. Agregue la siguiente entrada para permitir el aumento de privilegios.

become: yes

1.5. Agregue la siguiente entrada para definir el comienzo de la lista tasks.

tasks:

2. Agregue las entradas requeridas al archivo /home/student/playbook-review/


internet.yml para definir una tarea que instale las últimas versiones de los paquetes
firewalld, httpd, mariadb-server, php y php-mysqlnd.

- name: latest version of all required packages installed


yum:
name:
- firewalld
- httpd
- mariadb-server
- php
- php-mysqlnd
state: latest

3. Agregue las entradas necesarias al archivo /home/student/playbook-review/


internet.yml para definir las tareas de configuración del firewall. Deben asegurarse de
que el servicio firewalld esté enabled (habilitado) y running (en ejecución), y que se
permita el acceso al servicio httpd.

- name: firewalld enabled and running


service:
name: firewalld
enabled: true
state: started

- name: firewalld permits http service


firewalld:
service: http
permanent: true
state: enabled
immediate: yes

4. Agregue las tareas necesarias para asegurar que los servicios httpd y mariadb estén en los
estados enabled y running.

98 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

- name: httpd enabled and running


service:
name: httpd
enabled: true
state: started

- name: mariadb enabled and running


service:
name: mariadb
enabled: true
state: started

5. Agregue las entradas necesarias para definir la tarea final a fin de generar
contenido web para realizar pruebas. Use el módulo get_url para copiar http://
materials.example.com/labs/playbook-review/index.php a /var/www/html/
en el host administrado.

- name: test php page is installed


get_url:
url: "http://materials.example.com/labs/playbook-review/index.php"
dest: /var/www/html/index.php
mode: 0644

6. En /home/student/playbook-review/internet.yml, defina otra reproducción para


que la tarea se realice en el nodo de control. Esta reproducción probará el acceso al servidor
web que debería estar ejecutándose en el host administrado serverb. Esta reproducción no
requiere aumento de privilegios y se ejecutará en el host administrado localhost.

6.1. Agregue la siguiente entrada para denotar el comienzo de una segunda reproducción
con un nombre de Test internet web server (Probar servidor web de Internet).

- name: Test internet web server

6.2. Agregue la siguiente entrada para indicar que la reproducción se aplica al host
administrado localhost.

hosts: localhost

6.3. Agregue la siguiente línea después de la palabra clave hosts para deshabilitar el
aumento de privilegios para la segunda reproducción.

become: no

6.4. Agregue una entrada al archivo /home/student/playbook-review/


internet.yml para definir el comienzo de la lista tasks.

tasks:

7. Agregue una tarea que pruebe el servicio web que se ejecuta en serverb desde el nodo de
control usando el módulo uri. Compruebe si existe un código de estado de retorno de 200.

RH294-RHEL8.0-es-1-20200501 99
capítulo 3 | Implementación de guías

- name: connect to internet web server


uri:
url: http://serverb.lab.example.com
status_code: 200

8. Verifique la sintaxis de la guía internet.yml.

[student@workstation playbook-review]$ ansible-playbook --syntax-check \


> internet.yml

playbook: internet.yml

9. Use el comando ansible-playbook para ejecutar la guía. Lea la salida generada para
garantizar que todas las tareas se hayan completado satisfactoriamente.

[student@workstation playbook-review]$ ansible-playbook internet.yml


PLAY [Enable internet services] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [serverb.lab.example.com]

TASK [latest version of all required packages installed] ***********************


changed: [serverb.lab.example.com]

TASK [firewalld enabled and running] *******************************************


ok: [serverb.lab.example.com]

TASK [firewalld permits http service] ******************************************


changed: [serverb.lab.example.com]

TASK [httpd enabled and running] ***********************************************


changed: [serverb.lab.example.com]

TASK [mariadb enabled and running] *********************************************


changed: [serverb.lab.example.com]

TASK [test php page installed] *************************************************


changed: [serverb.lab.example.com]

PLAY [Test internet web server] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [localhost]

TASK [connect to internet web server] ******************************************


ok: [localhost]

PLAY RECAP *********************************************************************


localhost : ok=2 changed=0 unreachable=0 failed=0
serverb.lab.example.com : ok=7 changed=5 unreachable=0 failed=0

100 RH294-RHEL8.0-es-1-20200501
capítulo 3 | Implementación de guías

Evaluación
Evalúe su trabajo ejecutando el comando lab playbook-review grade de su máquina
workstation. Corrija los errores informados y vuelva a ejecutar el script hasta obtener un
resultado satisfactorio.

[student@workstation ~]$ lab playbook-review grade

Finalizar
En workstation, ejecute el script lab playbook-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab playbook-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 101
capítulo 3 | Implementación de guías

Resumen
En este capítulo, aprendió lo siguiente:

• Una reproducción es una lista ordenada de tareas que se ejecutan respecto de hosts
seleccionados de su inventario.

• Una guía es un archivo de texto que contiene una lista de una o más reproducciones para
ejecutar en orden.

• Las guías Ansible se escriben en formato YAML.

• Los archivos YAML están estructurados mediante la sangría de espacio para representar la
jerarquía de datos.

• Las tareas se implementan mediante el código estandarizado incluido como módulos Ansible.

• El comando ansible-doc puede enumerar módulos instalados y brindar documentación y


fragmentos de códigos a modo de ejemplo de cómo usarlos en guías.

• El comando ansible-playbook se utiliza para verificar la sintaxis de la guía y ejecutar guías.

102 RH294-RHEL8.0-es-1-20200501
capítulo 4

Administración de variables y
hechos
Meta Escribir guías que usen variables para simplificar
la administración de la guía y datos para
hacer referencia a información sobre los hosts
administrados.

Objetivos • Crear variables que afecten a hosts particulares


o grupos de hosts, la reproducción o el entorno
global, y hacer referencia a ellas, y describir
cómo funciona la prioridad de variables.
• Cifrar las variables confidenciales utilizando
Ansible Vault y ejecutar guías que hagan
referencia a archivos de variables cifradas por
Vault.
• Hacer referencia a los datos sobre hosts
administrados que utilizan datos de Ansible
y configurar hechos personalizados en hosts
administrados.

Secciones • Gestión de variables (y ejercicio guiado)


• Gestión de secretos (y ejercicio guiado)
• Gestión de datos (y ejercicio guiado)

Trabajo de • Administración de variables y datos


laboratorio

RH294-RHEL8.0-es-1-20200501 103
capítulo 4 | Administración de variables y hechos

Gestión de variables

Objetivos
Después de completar esta sección, debe ser capaz de crear variables de las guías que afecten a
hosts particulares o grupos de hosts, la reproducción o el entorno global, y hacer referencia a ellas,
y describir cómo funciona la prioridad de variables.

Introducción a variables de Ansible


Ansible admite variables que se pueden usar para almacenar valores que, luego, se pueden
volver a usar en todos los archivos de un proyecto Ansible. Esto puede simplificar la creación y el
mantenimiento de un proyecto, así como reducir la cantidad de errores.

Las variables brindan una forma conveniente de gestionar los valores dinámicos para un entorno
dado en su proyecto Ansible. Los ejemplos de valores que pueden contener las variables incluyen:

• Usuarios para crear

• Paquetes para instalar

• Servicios para reiniciar

• Archivos para eliminar

• Colección de archivos para recuperar de Internet

Denominación de variables
Los nombres de las variables deben iniciarse con una letra y solo pueden contener letras, números
y guiones bajos.

En la siguiente tabla, se muestra la diferencia entre nombres de variable no válidos y válidos.

Ejemplos de nombres de variables Ansible no válidos y válidos

Nombres de variables no válidos Nombres de variables válidos

web server web_server

remote.file remote_file

1st file file_1

file1

remoteserver$1 remote_server_1

remote_server1

104 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Definición de variables
Las variables se pueden definir en una variedad de lugares en un proyecto Ansible. No obstante,
esto se puede simplificar en tres niveles de alcance básicos:

• Global scope: variables establecidas de la línea de comando o la configuración de Ansible

• Play scope: variables establecidas en la reproducción y las estructuras relacionadas

• Host scope: variables establecidas en grupos de hosts y hosts individuales por el inventario,
reunión de datos, o tareas registradas

Si el mismo nombre de variable se define en más de un nivel, el nivel con la mayor precedencia
gana. Un alcance más corto tiene prioridad sobre un alcance más amplio: las variables definidas
por el inventario se reemplazan por variables definidas por la guía, las cuales se reemplazan por
variables definidas en la línea de comando.

Una discusión detallada de precedencia de variables está disponible en la documentación Ansible,


cuyo enlace se brinda en las referencias al final de esta sección.

Variables en guías
Las variables desempeñan un papel importante en Ansible Playbook porque facilitan la
administración de datos variables en una guía.

Definición de variables en guías


Cuando se escriben guías, se pueden definir las propias variables y luego invocar esos valores
en una tarea. Por ejemplo, una variable llamada web_package se puede definir con un valor de
httpd. Por lo tanto, una tarea puede llamar a la variable usando el módulo yum para instalar el
paquete httpd.

Las variables de guías se pueden definir de múltiples maneras. Uno de los métodos más comunes
es colocar una variable en un bloque vars al comienzo de una guía:

- hosts: all
vars:
user: joe
home: /home/joe

También es posible definir variables de guías en archivos externos. En este caso, en lugar de usar
el bloque vars en la guía, se puede utilizar la directiva vars_files, seguida de una lista de
nombres para archivos de variables externas, relativos a la ubicación de la guía:

- hosts: all
vars_files:
- vars/users.yml

A continuación, las variables de la guía se definen en ese archivo o los archivos en formato YAML:

user: joe
home: /home/joe

RH294-RHEL8.0-es-1-20200501 105
capítulo 4 | Administración de variables y hechos

Uso de variables en guías


Una vez declaradas las variables, los administradores pueden usar las variables en tareas. Se
hace referencia a las variables colocando el nombre de la variable en llaves dobles ({{ }}). Ansible
sustituye la variable con su valor cuando se ejecuta la tarea.

vars:
user: joe

tasks:
# This line will read: Creates the user joe
- name: Creates the user {{ user }}
user:
# This line will create the user named Joe
name: "{{ user }}"

Importante
Cuando se utiliza una variable como el primer elemento para iniciar un valor, las
comillas son obligatorias. De esta manera, se evita que Ansible interprete que la
referencia de la variable inicia un diccionario YAML. Si faltan las comillas, aparece el
siguiente mensaje:

yum:
name: {{ service }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

with_items:
- {{ foo }}

Should be written as:

with_items:
- "{{ foo }}"

Variables de hosts y variables de grupos


Las variables de inventario que se aplican directamente a los hosts se dividen en dos categorías
amplias: variables de host, que se aplican a un host específico; y variables de grupo, que se aplican
a todos los hosts en un grupo de hosts o en un grupo de grupos de hosts. Las variables de hosts
preceden a las variables de grupos, pero las variables definidas por una guía preceden a ambas.

Una forma de definir las variables de hosts y las variables de grupos es hacerlo directamente en
el archivo de inventario. Este es un enfoque antiguo y no se lo recomienda, pero aún puede ser
detectado.

• Definición de la variable de host ansible_user para demo.example.com:

106 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

[servers]
demo.example.com ansible_user=joe

• Definición de la variable de grupo user para el grupo de hosts servers.

[servers]
demo1.example.com
demo2.example.com

[servers:vars]
user=joe

• Definición de la variable de grupo user para el grupo servers, que consta de dos grupos de
hosts, cada uno con dos servidores.

[servers1]
demo1.example.com
demo2.example.com

[servers2]
demo3.example.com
demo4.example.com

[servers:children]
servers1
servers2

[servers:vars]
user=joe

Algunas desventajas de este enfoque son que dificulta más el trabajo con el archivo de inventario,
mezcla la información acerca de hosts y variables en el mismo archivo, y usa una sintaxis obsoleta.

Uso de directorios para completar variables de host y de grupo


El enfoque recomendable para definir variables para host y grupos de hosts es crear dos
directorios, group_vars y host_vars, en el mismo directorio de trabajo como archivo de
inventario o directorio. Estos directorios contienen archivos que definen variables de grupo y
variables de host, respectivamente.

Importante
La práctica recomendada es definir las variables de inventario usando los directorios
host_vars y group_vars, y no definirlas directamente en los archivos de
inventario.

Para definir variables de grupo para el grupo servers, debería crear un archivo YAML
denominado group_vars/servers y, luego, el contenido de ese archivo establecería variables
para valores utilizando la misma sintaxis que en una guía:

user: joe

RH294-RHEL8.0-es-1-20200501 107
capítulo 4 | Administración de variables y hechos

De la misma forma, para definir variables de hosts para un host específico, cree un archivo con un
nombre que coincida con el host que se encuentra en el directorio host_vars para que contenga
las variables de hosts.

Los siguientes ejemplos ilustran este enfoque más detalladamente. Considere una situación en
la que hay dos centros de datos para administrar y los hosts del centro de datos se definen en el
archivo de inventario ~/project/inventory:

[admin@station project]$ cat ~/project/inventory


[datacenter1]
demo1.example.com
demo2.example.com

[datacenter2]
demo3.example.com
demo4.example.com

[datacenters:children]
datacenter1
datacenter2

• Si se debe definir un valor general para todos los servidores en los dos centros de datos, se
puede establecer una variable de grupo para el grupo de hosts datacenters:

[admin@station project]$ cat ~/project/group_vars/datacenters


package: httpd

• Si el valor a definir varía para cada centro de datos, establezca una variable de grupo para cada
grupo de hosts del centro de datos:

[admin@station project]$ cat ~/project/group_vars/datacenter1


package: httpd
[admin@station project]$ cat ~/project/group_vars/datacenter2
package: apache

• Si el valor por definir varía para cada host en cada centro de datos, se deben definir las variables
en archivos de variables de host diferentes:

[admin@station project]$ cat ~/project/host_vars/demo1.example.com


package: httpd
[admin@station project]$ cat ~/project/host_vars/demo2.example.com
package: apache
[admin@station project]$ cat ~/project/host_vars/demo3.example.com
package: mariadb-server
[admin@station project]$ cat ~/project/host_vars/demo4.example.com
package: mysql-server

La estructura de directorios para el proyecto de ejemplo, project, si contuviera todos los


archivos de ejemplo anteriores, aparecería de la siguiente manera:

project
├── ansible.cfg
├── group_vars

108 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

│ ├── datacenters
│ ├── datacenters1
│ └── datacenters2
├── host_vars
│ ├── demo1.example.com
│ ├── demo2.example.com
│ ├── demo3.example.com
│ └── demo4.example.com
├── inventory
└── playbook.yml

Reemplazo de las variables de la línea de comandos


Las variables de inventario son reemplazadas por variables establecidas en una guía, pero ambos
tipos de variables se pueden reemplazar mediante argumentos enviados a los comandos ansible
o ansible-playbook en la línea de comando. Las variables establecidas en la línea de comando
se denominan variables adicionales.

Las variables adicionales pueden ser útiles cuando debe reemplazar el valor definido para una
variable para una ejecución única de una guía. Por ejemplo:

[user@demo ~]$ ansible-playbook main.yml -e "package=apache"

Uso de matrices como variables


En lugar de asignar datos de configuración que se relacionen con el mismo elemento (una
lista de paquetes, una lista de servicios, una lista de usuarios, etc.) con múltiples variables, los
administradores pueden usar matrices. Una consecuencia de esto es que un arreglo se puede
examinar.

Por ejemplo, considere el siguiente fragmento:

user1_first_name: Bob
user1_last_name: Jones
user1_home_dir: /users/bjones
user2_first_name: Anne
user2_last_name: Cook
user2_home_dir: /users/acook

Este se puede reescribir como un arreglo denominado users:

users:
bjones:
first_name: Bob
last_name: Jones
home_dir: /users/bjones
acook:
first_name: Anne
last_name: Cook
home_dir: /users/acook

Luego puede usar las siguientes variables para acceder a los datos del usuario:

RH294-RHEL8.0-es-1-20200501 109
capítulo 4 | Administración de variables y hechos

# Returns 'Bob'
users.bjones.first_name

# Returns '/users/acook'
users.acook.home_dir

Debido a que la variable se define como un diccionario Python, hay disponible una sintaxis
alternativa.

# Returns 'Bob'
users['bjones']['first_name']

# Returns '/users/acook'
users['acook']['home_dir']

Importante
La notación de punto puede causar problemas si los nombres clave son los mismos
que los nombres de los métodos o atributos de Python, como discard, copy, add,
y así sucesivamente. Usar la notación de paréntesis puede ayudar a evitar conflictos
y errores.

Ambas sintaxis son válidas, pero para simplificar la solución de problemas, Red Hat
recomienda usar una sintaxis de manera consistente en todos los archivos en
cualquier proyecto de Ansible.

Captura de salida de comando con variables


registradas
Los administradores pueden usar la declaración register para capturar la salida de un comando.
El resultado se guarda en una variable temporal que puede utilizarse posteriormente en la guía
con motivos de depuración u otros motivos, como una configuración particular basada en el
resultado de un comando.

La siguiente guía demuestra cómo capturar el resultado de un comando con motivos de


depuración:

---
- name: Installs a package and prints the result
hosts: all
tasks:
- name: Install the package
yum:
name: httpd
state: installed
register: install_result

- debug: var=install_result

Cuando se ejecuta la guía, el módulo debug se usa para volcar el valor de la variable registrada
install_result en el terminal.

110 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

[user@demo ~]$ ansible-playbook playbook.yml


PLAY [Installs a package and prints the result] ****************************

TASK [setup] ***************************************************************


ok: [demo.example.com]

TASK [Install the package] *************************************************


ok: [demo.example.com]

TASK [debug] ***************************************************************


ok: [demo.example.com] => {
"install_result": {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-40.el7.x86_64 providing httpd is already installed"
]
}
}

PLAY RECAP *****************************************************************


demo.example.com : ok=3 changed=0 unreachable=0 failed=0

Referencias
Inventario — Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Variables — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

Precedencia de la variable: ¿Dónde debo colocar una variable?


https://docs.ansible.com/ansible/latest/user_guide/
playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

Sintaxis YAML — Documentación Ansible


https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

RH294-RHEL8.0-es-1-20200501 111
capítulo 4 | Administración de variables y hechos

Ejercicio Guiado

Gestión de variables
En este ejercicio, definirá y usará variables en una guía.

Resultados
Deberá poder realizar lo siguiente:

• Definir variables en una guía

• Crear tareas que usen variables definidas

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab data-variables start. Esta función crea el


directorio de trabajo, data-variables, y lo completa con un archivo de configuración de
Ansible y un inventario de hosts.

[student@workstation ~]$ lab data-variables start

1. En workstation, con el usuario student, cambie al directorio /home/student/data-


variables.

[student@workstation ~]$ cd ~/data-variables

2. Durante los siguientes varios pasos, usted creará una guía que instale el servidor web
Apache y abra los puertos para que se pueda acceder al servicio. La guía consulta al
servidor web para garantizar que se esté ejecutando.
Cree la guía playbook.yml y defina las siguientes variables en la sección vars:

Variables

Variable Descripción

web_pkg Paquete de servidor web para instalar.

firewall_pkg Paquete de firewall para instalar.

web_service Servicio web para administrar.

firewall_service Servicio de firewall que se administrará.

python_pkg Paquete requerido para el módulo uri.

rule El nombre del servicio para abrir.

112 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

---
- name: Deploy and start Apache HTTPD service
hosts: webserver
vars:
web_pkg: httpd
firewall_pkg: firewalld
web_service: httpd
firewall_service: firewalld
python_pkg: python3-PyMySQL
rule: http

3. Cree el bloque tasks y cree la primera tarea, que debería usar el módulo yum para
garantizar que estén instaladas las versiones más recientes de los paquetes requeridos.

tasks:
- name: Required packages are installed and up to date
yum:
name:
- "{{ web_pkg }}"
- "{{ firewall_pkg }}"
- "{{ python_pkg }}"
state: latest

nota
Puedes usar ansible-doc yum para revisar la sintaxis del módulo yum. La sintaxis
muestra que su directiva name puede tomar una lista de paquetes con los que debe
trabajar el módulo, de modo que no necesita tareas separadas para garantizar que
cada paquete esté actualizado.

4. Cree dos tareas para asegurarse de que los servicios httpd y firewalld estén iniciados y
habilitados.

- name: The {{ firewall_service }} service is started and enabled


service:
name: "{{ firewall_service }}"
enabled: true
state: started

- name: The {{ web_service }} service is started and enabled

RH294-RHEL8.0-es-1-20200501 113
capítulo 4 | Administración de variables y hechos

service:
name: "{{ web_service }}"
enabled: true
state: started

nota
El módulo service funciona de manera diferente que el módulo yum, según se
documenta en ansible-doc service. Su directiva name toma el nombre de
exactamente un servicio con el cual trabajar.

Puede escribir una sola tarea que garantice que ambos servicios se inicien y se
habiliten, usando la palabra clave loop que se verá más adelante en este curso.

5. Agregue una tarea que garantice que exista contenido específico en el archivo /var/www/
html/index.html.

- name: Web content is in place


copy:
content: "Example web content"
dest: /var/www/html/index.html

6. Agregue una tarea que utilice el módulo firewalld para garantizar que los puertos de
firewall estén abiertos para el servicio firewalld mencionado en la variable rule.

- name: The firewall port for {{ rule }} is open


firewalld:
service: "{{ rule }}"
permanent: true
immediate: true
state: enabled

7. Cree una nueva reproducción que consulte el servicio web para garantizar que todo se haya
configurado correctamente. Debe ejecutarse en localhost. Debido a esto, Ansible no
debe cambiar la identidad; por lo tanto, establezca el módulo become en false. Puede
usar el módulo uri para verificar una URL. Para esta tarea, verifique el código de estado
de 200 para confirmar que el servidor web en servera.lab.example.com se esté
ejecutando y esté configurado adecuadamente.

- name: Verify the Apache service


hosts: localhost
become: false
tasks:
- name: Ensure the webserver is reachable
uri:
url: http://servera.lab.example.com
status_code: 200

114 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

8. Cuando se complete, la guía debe verse de la siguiente forma. Revise la guía y confirme que
ambas reproducciones sean correctas.

---
- name: Deploy and start Apache HTTPD service
hosts: webserver
vars:
web_pkg: httpd
firewall_pkg: firewalld
web_service: httpd
firewall_service: firewalld
python_pkg: python3-PyMySQL
rule: http

tasks:
- name: Required packages are installed and up to date
yum:
name:
- "{{ web_pkg }}"
- "{{ firewall_pkg }}"
- "{{ python_pkg }}"
state: latest

- name: The {{ firewall_service }} service is started and enabled


service:
name: "{{ firewall_service }}"
enabled: true
state: started

- name: The {{ web_service }} service is started and enabled


service:
name: "{{ web_service }}"
enabled: true
state: started

- name: Web content is in place


copy:
content: "Example web content"
dest: /var/www/html/index.html

- name: The firewall port for {{ rule }} is open


firewalld:
service: "{{ rule }}"
permanent: true
immediate: true
state: enabled

- name: Verify the Apache service


hosts: localhost
become: false
tasks:

RH294-RHEL8.0-es-1-20200501 115
capítulo 4 | Administración de variables y hechos

- name: Ensure the webserver is reachable


uri:
url: http://servera.lab.example.com
status_code: 200

9. Antes de ejecutar la guía, use el comando ansible-playbook --syntax-check para


verificar su sintaxis. Si informa errores, corríjalos antes de pasar al siguiente paso. Debe ver
una salida similar a la siguiente:

[student@workstation data-variables]$ ansible-playbook --syntax-check playbook.yml

playbook: playbook.yml

10. Use el comando ansible-playbook para ejecutar la guía. Observe la salida a medida que
Ansible instala los paquetes, inicia y habilita los servicios, y garantiza que el servidor web
esté disponible.

[student@workstation data-variables]$ ansible-playbook playbook.yml

PLAY [Deploy and start Apache HTTPD service] ***********************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Required packages are installed and up to date] **************************


changed: [servera.lab.example.com]

TASK [The firewalld service is started and enabled] ****************************


ok: [servera.lab.example.com]

TASK [The httpd service is started and enabled] ********************************


changed: [servera.lab.example.com]

TASK [Web content is in place] *************************************************


changed: [servera.lab.example.com]

TASK [The firewall port for http is open] **************************************


changed: [servera.lab.example.com]

PLAY [Verify the Apache service] ***********************************************

TASK [Gathering Facts] *********************************************************


ok: [localhost]

TASK [Ensure the webserver is reachable] ***************************************


ok: [localhost]

PLAY RECAP *********************************************************************


localhost : ok=2 changed=0 unreachable=0 failed=0
servera.lab.example.com : ok=6 changed=4 unreachable=0 failed=0

116 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Finalizar
En workstation, ejecute el script lab data-variables finish para limpiar este ejercicio.

[student@workstation ~]$ lab data-variables finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 117
capítulo 4 | Administración de variables y hechos

Gestión de secretos

Objetivos
Después de completar esta sección, debe ser capaz de cifrar las variables confidenciales usando
Ansible Vault y ejecutar guías que hagan referencia a archivos de variables cifradas por Vault.

Presentación de Ansible Vault


Es posible que Ansible necesite acceso a datos confidenciales, como contraseñas o claves API,
para configurar hosts administrados. En general, esta información podría estar almacenada como
texto sin formato en variables de inventario u otros archivos de Ansible. Sin embargo, en ese
caso, los usuarios con acceso a los archivos de Ansible o a un sistema de control de versiones que
almacena los archivos de Ansible tendrían acceso a estos datos confidenciales. Esto representa un
riesgo de seguridad notorio.

Se puede utilizar Ansible Vault, que está incluido con Ansible, para cifrar y descifrar cualquier
archivo de datos estructurados utilizado por Ansible. Para usar Ansible Vault, se usa una
herramienta de la línea de comandos denominada ansible-vault para crear, editar, cifrar,
descifrar y ver archivos. Ansible Vault puede cifrar cualquier archivo de datos estructurado usado
por Ansible. Esto podría incluir variables de inventario, archivos de variables incluidos en una guía,
archivos de variables pasados como argumento al ejecutar la guía o variables definidas en roles de
Ansible.

Importante
Ansible Vault no implementa sus propias funciones criptográficas, sino que
utiliza un kit de herramientas Python externo. Los archivos están protegidos con
cifrado simétrico mediante el uso de AES256 con una contraseña como clave
secreta. Tenga en cuenta que la forma en la que se realiza esto no ha sido auditado
formalmente por un tercero.

Creación de un archivo cifrado


Para crear un nuevo archivo cifrado, use el comando ansible-vault create filename.
El comando le solicitará la nueva contraseña de Vault y abrirá un archivo con el editor
predeterminado, vi. Puede configurar y exportar la variable de entorno EDITOR para especificar
un editor predeterminado diferente mediante una configuración y una exportación. Por ejemplo,
para establecer el editor predeterminado en nano, export EDITOR=nano.

[student@demo ~]$ ansible-vault create secret.yml


New Vault password: redhat
Confirm New Vault password: redhat

En lugar de ingresar la contraseña de Vault mediante el ingreso estándar, se puede usar un


archivo de contraseña de Vault para almacenar la contraseña. Este archivo se deberá proteger
cuidadosamente mediante permisos de archivo y por otros medios.

118 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

[student@demo ~]$ ansible-vault create --vault-password-file=vault-pass secret.yml

El código usado para proteger archivos es AES256 en las versiones recientes de Ansible, pero los
archivos cifrados con versiones anteriores aún pueden utilizar AES de 128 bits.

Vista de un archivo cifrado


Puede usar el comando ansible-vault view filename para ver un archivo cifrado con
Ansible Vault, sin abrirlo para editarlo.

[student@demo ~]$ ansible-vault view secret1.yml


Vault password: secret
less 458 (POSIX regular expressions)
Copyright (C) 1984-2012 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.


For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
my_secret: "yJJvPqhsiusmmPPZdnjndkdnYNDjdj782meUZcw"

Edición de un archivo cifrado existente


Para editar un archivo cifrado existente, Ansible Vault proporciona el comando ansible-vault
edit filename. Este comando descifra el archivo a un archivo temporal y le permite editar el
archivo. Cuando se guarda, copia el contenido y elimina el archivo temporal.

[student@demo ~]$ ansible-vault edit secret.yml


Vault password: redhat

nota
El subcomando edit siempre reescribe el archivo, de modo que solo debería
usarse al hacer cambios. Esto puede tener implicancias cuando el archivo se guarda
en control de versiones. El subcomando view debe usarse siempre para ver el
contenido del archivo sin hacer cambios.

Cifrado de un archivo existente


Para cifrar un archivo que ya existe, use el comando ansible-vault encrypt filename. Este
comando puede tomar los nombres de varios archivos que se cifrarán como argumentos.

[student@demo ~]$ ansible-vault encrypt secret1.yml secret2.yml


New Vault password: redhat
Confirm New Vault password: redhat
Encryption successful

Use la opción --output=OUTPUT_FILE para guardar el archivo cifrado con un nombre nuevo
Solo puede usar un archivo de entrada con la opción --output.

RH294-RHEL8.0-es-1-20200501 119
capítulo 4 | Administración de variables y hechos

Descifrado de un archivo existente


Un archivo ya cifrado existente se puede descifrar de forma permanente con el comando
ansible-vault decrypt filename. La opción --output se puede usar cuando se descifra
un solo archivo para guardar el archivo descifrado con un nombre diferente.

[student@demo ~]$ ansible-vault decrypt secret1.yml --output=secret1-decrypted.yml


Vault password: redhat
Decryption successful

Cambio de contraseña de un archivo cifrado


Puede usar el comando ansible-vault rekey filename para cambiar la contraseña de un
archivo cifrado. Este comando puede regenerar la clave de varios archivos de datos de una vez.
Solicitará la contraseña original y luego, la nueva contraseña.

[student@demo ~]$ ansible-vault rekey secret.yml


Vault password: redhat
New Vault password: RedHat
Confirm New Vault password: RedHat
Rekey successful

Al utilizar un archivo de contraseña de Vault, use la opción --new-vault-password-file:

[student@demo ~]$ ansible-vault rekey \


> --new-vault-password-file=NEW_VAULT_PASSWORD_FILE secret.yml

Guías y Ansible Vault


Para ejecutar una guía que acceda a archivos cifrados con Ansible Vault, se debe proporcionar la
contraseña de cifrado al comando ansible-playbook. Si no proporciona la contraseña, la guía
devuelve un error:

[student@demo ~]$ ansible-playbook site.yml


ERROR: A vault password must be specified to decrypt vars/api_key.yml

Para proporcionar la contraseña de Vault para la guía, use la opción --vault-id. Por ejemplo,
para proporcionar la contraseña de Vault de forma interactiva, use --vault-id @prompt como
se ilustra en el siguiente ejemplo:

[student@demo ~]$ ansible-playbook --vault-id @prompt site.yml


Vault password (default): redhat

120 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Importante
Si está utilizando una versión de Ansible anterior a la versión 2.4, debe usar la
opción--ask-vault-pass para proporcionar la contraseña de Vault de forma
interactiva. Todavía puede usar esta opción si todos los archivos cifrados con Vault
utilizados por la guía se cifraron con la misma contraseña.

[student@demo ~]$ ansible-playbook --ask-vault-pass site.yml


Vault password: redhat

O bien, puede usar la opción --vault-password-file para especificar un archivo que


almacene la contraseña de cifrado en texto sin formato. La contraseña debe ser una cadena
almacenada como una sola línea en el archivo. Dado que el archivo contiene la contraseña
confidencial en texto sin formato, es importante que se proteja mediante permisos de archivo y
otras medidas de seguridad.

[student@demo ~]$ ansible-playbook --vault-password-file=vault-pw-file site.yml

También puede usar la variable de entorno ANSIBLE_VAULT_PASSWORD_FILE para especificar


la ubicación predeterminada del archivo de contraseña.

Importante
Comenzando con Ansible 2. 4, puede usar múltiples contraseñas de Ansible
Vault con ansible-playbook. Para usar múltiples contraseñas, pase múltiples
opciones --vault-id o --vault-password-file para el comando ansible-
playbook.

[student@demo ~]$ ansible-playbook \


> --vault-id one@prompt --vault-id two@prompt site.yml
Vault password (one):
Vault password (two):
...output omitted...

Las identificaciones de Vault one y two anteriores a @prompt pueden ser cualquier
cosa e incluso puede omitirlas por completo. Sin embargo, si usa la opción --
vault-id id cuando cifra un archivo con el comando ansible-vault, cuando
se ejecuta ansible-playbook, la contraseña para el ID coincidente se prueba
antes que cualquier otra. Si no coincide, las otras contraseñas que proporcionó
se intentarán a continuación. El ID de Vault @prompt sin ID es en realidad la
abreviatura para default@prompt, lo que significa solicitar la contraseña para el ID
de Vault default.

Prácticas recomendadas para la administración de archivos de


variables
Para simplificar la administración, tiene sentido configurar su proyecto de Ansible, de modo
que las variables confidenciales y todas las demás variables se guarden en archivos separados.
Los archivos que contienen las variables confidenciales se pueden proteger con el comando
ansible-vault.

RH294-RHEL8.0-es-1-20200501 121
capítulo 4 | Administración de variables y hechos

Recuerde que la manera preferida para administrar las variables del grupo y las variables del host
es crear directorios en el nivel de la guía. El directorio group_vars, generalmente, contiene
archivos de variables con nombres que coinciden con los grupos de hosts a los que se aplican. El
directorio host_vars, generalmente, contiene archivos de variables con nombres que coinciden
con los nombres de host de los hosts administrados a los que se aplican.

Sin embargo, en lugar de usar archivos en group_vars o host_vars, puede usar directories
para cada grupo de hosts o host administrado. Aquellos directorios pueden contener varios
archivos de variables, que son usados por el grupo de hosts o el host administrado. Por
ejemplo, en el siguiente directorio de proyecto para playbook.yml, los miembros del grupo
de hosts webservers usan variables en el archivo group_vars/webservers/vars,
y demo.example.com usa las variables en host_vars/demo.example.com/vars y
host_vars/demo.example.com/vault:

.
├── ansible.cfg
├── group_vars
│ └── webservers
│ └── vars
├── host_vars
│ └── demo.example.com
│ ├── vars
│ └── vault
├── inventory
└── playbook.yml

En este escenario, la ventaja es que la mayor parte de las variables para demo.example.com
pueden ubicarse en el archivo vars, pero las variables confidenciales pueden mantenerse en
secreto colocándolas por separado en el archivo vault. Luego, el administrador puede usar
ansible-vault para cifrar el archivo vault, y a la vez dejar el archivo vars como texto sin
formato.

No hay nada especial acerca de los nombres de archivos que se usan en este ejemplo dentro
del directorio host_vars/demo.example.com. Ese directorio podría contener más archivos,
algunos cifrados por Ansible Vault y otros no.

Las variables de guías (en oposición a las variables de inventario) también se pueden proteger con
Ansible Vault. Las variables de guías confidenciales se pueden colocar en un archivo separado que
se cifra con Ansible Vault y que se incluye en la guía mediante una directiva vars_files. Esto
puede ser útil, ya que las variables de la guía tienen precedencia sobre las variables de inventario.

Si está usando varias contraseñas de Vault con su guía, asegúrese de que a cada archivo cifrado se
le asigne un ID de Vault y que ingrese la contraseña correspondiente con ese ID de Vault cuando
ejecute la guía. Esto garantiza que la contraseña correcta se seleccione primero al descifrar el
archivo cifrado con Vault, que es más rápido que forzar a Ansible a probar todas las contraseñas de
Vault que proporcionó hasta que encuentre la correcta.

122 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Referencias
Páginas del manual: ansible-playbook(1) y ansible-vault(1)

Vault — Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_vault.html

Variables y Vaults — Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/
playbooks_best_practices.html#best-practices-for-variables-and-vaults

RH294-RHEL8.0-es-1-20200501 123
capítulo 4 | Administración de variables y hechos

Ejercicio Guiado

Gestión de secretos
En este ejercicio, cifrará las variables confidenciales con Ansible Vault para protegerlas y
luego ejecutará una guía que utiliza esas variables.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Ejecutar una guía usando variables definidas en un archivo cifrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab data-secret start. Este script


garantiza que Ansible está instalado en workstation y crea un directorio de trabajo
para este ejercicio. Este directorio incluye un archivo de inventario que apunta a
servera.lab.example.com como host administrado, que es parte del grupo
devservers.

[student@workstation ~]$ lab data-secret start

1. En workstation, con el usuario student, cambie al directorio de trabajo /home/


student/data-secret.

[student@workstation ~]$ cd ~/data-secret

2. Edite el contenido del archivo cifrado proporcionado, secret.yml . El archivo puede ser
descifrado usando redhat como contraseña. Elimine los comentarios de las entradas con
variables username y pwhash.

2.1. Edite el archivo cifrado /home/student/data-secret/secret.yml. Proporcione


una contraseña de redhat para Vault cuando se lo solicite. El archivo cifrado se abre
en el editor predeterminado, vim.

[student@workstation data-secret]$ ansible-vault edit secret.yml


Vault password: redhat

2.2. Quite las marcas de comentarios de las dos entradas de variables; luego, guarde el
archivo y salga del editor. Deben aparecer como se muestra a continuación:

username: ansibleuser1
pwhash: $6$jf...uxhP1

124 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

3. Cree una guía denominada /home/student/data-secret/create_users.yml


que use las variables definidas en el archivo cifrado /home/student/data-secret/
secret.yml.
Configure la guía para usar el grupo de hosts devservers. Ejecute esta guía con el
usuario devops en el host administrado remoto. Configure la guía para crear el usuario
ansibleuser1 definido por la variable username. Configure la contraseña del usuario
usando el hash de contraseña almacenado en la variable pwhash.

---
- name: create user accounts for all our servers
hosts: devservers
become: True
remote_user: devops
vars_files:
- secret.yml
tasks:
- name: Creating user from secret.yml
user:
name: "{{ username }}"
password: "{{ pwhash }}"

4. Use el comando ansible-playbook --syntax-check para verificar la sintaxis de la


guía create_users.yml. Use la opción --ask-vault-pass para solicitar la contraseña
de Vault, que descifra secret.yml. Resuelva los errores de sintaxis antes de continuar.

[student@workstation data-secret]$ ansible-playbook --syntax-check \


> --ask-vault-pass create_users.yml
Vault password (default): redhat

playbook: create_users.yml

nota
En lugar de usar --ask-vault-pass, puede usar la opción --vault-id
@prompt más nueva para hacer lo mismo.

5. Cree un archivo de contraseña denominado vault-pass para usar la ejecución de la guía


en lugar de solicitar una contraseña. El archivo debe contener el texto plano redhat como
la contraseña de Vault. Cambie los permisos del archivo a 0600.

[student@workstation data-secret]$ echo 'redhat' > vault-pass


[student@workstation data-secret]$ chmod 0600 vault-pass

6. Ejecute Ansible Playbook, con el archivo vault-pass, para crear el usuario


ansibleuser1 en un sistema remoto usando las contraseñas almacenadas como variables
en el archivo cifrado de Ansible Vault secret.yml.

[student@workstation data-secret]$ ansible-playbook \


> --vault-password-file=vault-pass create_users.yml

PLAY [create user accounts for all our servers] ********************************

RH294-RHEL8.0-es-1-20200501 125
capítulo 4 | Administración de variables y hechos

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Creating users from secret.yml] ******************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

7. Verifique que la guía se haya ejecutado correctamente. El usuario ansibleuser1


debe existir y tener la contraseña correcta en servera.lab.example.com. Pruebe
esto usando ssh para iniciar sesión con ese usuario en servera.lab.example.com.
La contraseña para ansibleuser1 es redhat. Para asegurarse de que SSH solo
intente autenticarse con una contraseña y no con una clave SSH, use la opción -o
PreferredAuthentications=password cuando inicie sesión.
Cerrar sesión en servera cuando haya iniciado sesión correctamente.

[student@workstation data-secret]$ ssh -o PreferredAuthentications=password \


> [email protected]
[email protected]'s password: redhat
Activate the web console with: systemctl enable --now cockpit.socket

[ansibleuser1@servera ~]$ exit


logout
Connection to servera.lab.example.com closed.

Finalizar
En workstation, ejecute el script lab data-secret finish para limpiar este ejercicio.

[student@workstation ~]$ lab data-secret finish

Esto concluye el ejercicio guiado.

126 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Gestión de datos

Objetivos
Después de completar esta sección, debe ser capaz de hacer referencia a los datos sobre
hosts administrados que usan datos de Ansible y configurar datos personalizados en hosts
administrados.

Descripción de Datos de Ansible


Los datos de Ansible son variables detectadas automáticamente por Ansible en un host
administrado. Los datos contienen información específica del host que puede usarse como
variables regulares en reproducciones, condicionales, bucles o cualquier otra declaración que
dependa de un valor recopilado de un host administrado.

Algunos de los datos recopilados para un host administrado pueden incluir los siguientes:

• El nombre del host

• La versión del kernel

• Las interfaces de red

• Las direcciones IP

• La versión del sistema operativo

• Diferentes variables de entorno

• La cantidad de CPU

• La memoria disponible o libre

• El espacio de disco disponible

Los datos son una forma conveniente de recuperar el estado de un host administrado y de
determinar qué acción tomar en función de ese estado. Por ejemplo:

• Un servidor puede reiniciarse mediante una tarea condicional que se ejecuta sobre la base de un
dato que contiene la versión del kernel actual del host administrado.

• El archivo de configuración MySQL puede ser personalizado, según la memoria disponible


informada por un dato.

• La dirección IPv4 usada en un archivo de configuración puede configurarse sobre la base del
valor de un dato.

En general, todas las reproducciones ejecutan el módulo setup de forma automática entes
de la primera tarea para recopilar datos. Esto se informa como la tarea Gathering Facts
en Ansible 2.3 y versiones posteriores o simplemente como setup en versiones anteriores de
Ansible. De forma predeterminada, no es necesario tener una tarea para ejecutar setup en la
reproducción. En general, se ejecuta automáticamente para usted.

Una forma de ver qué datos se recopilan para sus hosts administrados es ejecutar una guía corta
que recopile datos y use el módulo debug para imprimir el valor de la variable ansible_facts.

RH294-RHEL8.0-es-1-20200501 127
capítulo 4 | Administración de variables y hechos

- name: Fact dump


hosts: all
tasks:
- name: Print all facts
debug:
var: ansible_facts

Cuando ejecuta la guía, los datos se muestran en la salida del trabajo:

[user@demo ~]$ ansible-playbook facts.yml

PLAY [Fact dump] ***************************************************************

TASK [Gathering Facts] *********************************************************


ok: [demo1.example.com]

TASK [Print all facts] *********************************************************


ok: [demo1.example.com] => {
"ansible_facts": {
"all_ipv4_addresses": [
"172.25.250.10"
],
"all_ipv6_addresses": [
"fe80::5054:ff:fe00:fa0a"
],
"ansible_local": {},
"apparmor": {
"status": "disabled"
},
"architecture": "x86_64",
"bios_date": "01/01/2011",
"bios_version": "0.5.1",
"cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-327.el7.x86_64",
"LANG": "en_US.UTF-8",
"console": "ttyS0,115200n8",
"crashkernel": "auto",
"net.ifnames": "0",
"no_timer_check": true,
"ro": true,
"root": "UUID=2460ab6e-e869-4011-acae-31b2e8c05a3b"
},
...output omitted...

En la guía, se muestra el contenido de la variable ansible_facts en formato JSON como un


hash/diccionario de variables. Puede examinar la salida para ver los datos recopilados y para
buscar datos que pueda querer usar en sus reproducciones.

En la siguiente tabla, se muestran algunos de los datos que pueden recopilarse de un nodo
administrado y que pueden ser útiles en una guía:

128 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Ejemplos de datos de Ansible

Dato Variable

Nombre abreviado ansible_facts['hostname']


del host

Nombre de dominio ansible_facts['fqdn']


completo

Dirección IPv4 ansible_facts['default_ipv4']['address']


principal (basada en
enrutamiento)

Lista de los nombres ansible_facts['interfaces']


de todas las
interfaces de red

Tamaño de la ansible_facts['devices']['vda']['partitions']
partición de disco / ['vda1']['size']
dev/vda1

Lista de servidores ansible_facts['dns']['nameservers']


DNS

Versión del kernel ansible_facts['kernel']


actualmente en
ejecución

nota
Recuerde que cuando el valor de una variable es un diccionario/hash, hay dos
sintaxis que pueden usarse para recuperar el valor. Para tomar dos ejemplos de la
tabla anterior:

• ansible_facts['default_ipv4']['address'] también se puede escribir


ansible_facts.default_ipv4.address

• ansible_facts['dns']['nameservers'] también se puede escribir


ansible_facts.dns.nameservers

Cuando un dato se usa en una guía, Ansible sustituye de manera dinámica el nombre de la variable
para el dato con el valor correspondiente:

---
- hosts: all
tasks:
- name: Prints various Ansible facts
debug:
msg: >
The default IPv4 address of {{ ansible_facts.fqdn }}
is {{ ansible_facts.default_ipv4.address }}

RH294-RHEL8.0-es-1-20200501 129
capítulo 4 | Administración de variables y hechos

En el siguiente resultado, se muestra cómo Ansible consiguió consultar el nodo gestionado y usar
de manera dinámica la información del sistema para actualizar la variable. Los datos también se
pueden usar para crear grupos de hosts dinámicos que combinen criterios en particular.

[user@demo ~]$ ansible-playbook playbook.yml


PLAY ***********************************************************************

TASK [Gathering Facts] *****************************************************


ok: [demo1.example.com]

TASK [Prints various Ansible facts] ****************************************


ok: [demo1.example.com] => {
"msg": "The default IPv4 address of demo1.example.com is
172.25.250.10"
}

PLAY RECAP *****************************************************************


demo1.example.com : ok=2 changed=0 unreachable=0 failed=0

Datos de Ansible inyectados como variables


Antes de Ansible 2.5, los datos se inyectaban como variables individuales prefijadas con la
cadena ansible_ en lugar de ser parte de la variable ansible_facts. Por ejemplo, el dato
ansible_facts['distribution'] habría sido llamado ansible_distribution.

Muchas guías más antiguas aún utilizan datos inyectados como variables en lugar de la nueva
sintaxis que se encuentra en el espacio de nombres debajo de la variable ansible_facts. Puede
utilizar un comando ad hoc para ejecutar el módulo setup para imprimir el valor de todos los
datos en este formulario. En el siguiente ejemplo, se usa un comando ad hoc para ejecutar el
módulo setup en el host administrado demo1.example.com:

[user@demo ~]$ ansible demo1.example.com -m setup


demo1.example.com | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.25.250.10"
],
"ansible_all_ipv6_addresses": [
"fe80::5054:ff:fe00:fa0a"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "01/01/2011",
"ansible_bios_version": "0.5.1",
"ansible_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-327.el7.x86_64",
"LANG": "en_US.UTF-8",
"console": "ttyS0,115200n8",
"crashkernel": "auto",
"net.ifnames": "0",
"no_timer_check": true,
"ro": true,

130 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

"root": "UUID=2460ab6e-e869-4011-acae-31b2e8c05a3b"
}
...output omitted...

En la siguiente tabla, se comparan los nombres de datos antiguos y nuevos.

Comparación de los nombres de datos de Ansible seleccionados

Forma ansible_facts Forma de variable de dato antiguo

ansible_facts['hostname'] ansible_hostname

ansible_facts['fqdn'] ansible_fqdn

ansible_facts['default_ipv4'] ansible_default_ipv4['address']
['address']

ansible_facts['interfaces'] ansible_interfaces

ansible_facts['devices']['vda'] ansible_devices['vda']
['partitions']['vda1']['size'] ['partitions']['vda1']['size']

ansible_facts['dns'] ansible_dns['nameservers']
['nameservers']

ansible_facts['kernel'] ansible_kernel

Importante
Actualmente, Ansible reconoce tanto el nuevo sistema de denominación de datos
(usando ansible_facts) como el antiguo sistema de denominación de “datos
inyectados como variables separadas”, anterior a la versión 2.5.

Puede desactivar el antiguo sistema de nombres configurando el parámetro


inject_facts_as_vars en la sección [default] del archivo de configuración
Ansible en false. La configuración predeterminada actualmente es true.

El valor predeterminado de inject_facts_as_vars probablemente cambiará


a false en una futura versión de Ansible. Si se establece en false, solo
puede hacer referencia a datos de Ansible usando el nuevo sistema de nombres
ansible_facts.*. En ese caso, los intentos de hacer referencia a los datos a
través del espacio de nombres anterior generan el siguiente error:

...output omitted...
TASK [Show me the facts] *************************************************
fatal: [demo.example.com]: FAILED! => {"msg": "The task includes an option
with an undefined variable. The error was: 'ansible_distribution' is
undefined\n\nThe error appears to have been in
'/home/student/demo/playbook.yml': line 5, column 7, but may\nbe elsewhere in
the file depending on the exact syntax problem.\n\nThe offending line appears
to be:\n\n tasks:\n - name: Show me the facts\n ^ here\n"}
...output omitted...

RH294-RHEL8.0-es-1-20200501 131
capítulo 4 | Administración de variables y hechos

Desactivación de la recopilación de datos


Algunas veces, no deseará recopilar datos para su reproducción. Existen un par de motivos por los
cuales este sería el caso. Puede ser que no esté usando los datos y desee acelerar la reproducción
o reducir la carga provocada por la reproducción en los hosts administrados. Puede ser que los
hosts administrados no puedan ejecutar el módulo setup por algún motivo, o deba instalar algún
software de requisito previo antes de recopilar datos.

Para deshabilitar la recopilación de datos para una reproducción, establezca la palabra clave
gather_facts en no:

---
- name: This play gathers no facts automatically
hosts: large_farm
gather_facts: no

Aun si se establece gather_facts: no para una reproducción, puede recopilar datos de forma
manual en cualquier momento mediante la ejecución de una tarea que use el módulo setup:

tasks:
- name: Manually gather facts
setup:
...output omitted...

Creación de datos personalizados


Los administradores pueden crear datos personalizados que se almacenan localmente en cada
host administrado. Estos datos están integrados en la lista de datos estándares recopilados
por el módulo setup cuando se ejecuta en el host administrado. Estos permiten que el host
administrado proporcione variables arbitrarias a Ansible que pueden usarse para ajustar el
comportamiento de las reproducciones.

Los datos personalizados pueden definirse en un archivo estático y formatearse como un archivo
INI o con JSON. También pueden ser scripts ejecutables que generen una salida JSON, como un
script de inventario dinámico.

Los datos personalizados permiten a los administradores definir determinados valores para
hosts administrados, qué reproducciones pueden usar para completar archivos de configuración
o ejecutar tareas de forma condicional. Los datos personalizados dinámicos permiten que
los valores para estos datos se determinen de manera programática, o incluso qué datos se
suministran, cuando se ejecuta la reproducción.

De forma predeterminada, el módulo setup carga datos personalizados de archivos y scripts en


el directorio /etc/ansible/facts.d de cada host administrado. El nombre de cada archivo o
script debe finalizar en .fact para poder usarse. Los scripts de datos personalizados dinámicos
deben mostrar datos con formato JSON y deben ser ejecutables.

Este es un ejemplo de un archivo de datos personalizados estáticos escrito en formato INI. Un


archivo de datos personalizados con formato INI contiene un nivel superior definido por una
sección, seguido por los pares de claves-valores de los datos que se definirán:

132 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

[packages]
web_package = httpd
db_package = mariadb-server

[users]
user1 = joe
user2 = jane

Los mismos datos podrían proveerse en formato JSON. Los siguientes datos JSON son
equivalentes a los datos especificados por el formato INI en el ejemplo anterior. Los datos JSON
podrían almacenarse en un archivo de texto estático o imprimirse en una salida estándar mediante
un script ejecutable:

{
"packages": {
"web_package": "httpd",
"db_package": "mariadb-server"
},
"users": {
"user1": "joe",
"user2": "jane"
}
}

nota
Los archivos de datos personalizados no pueden tener formato YAML como una
guía. El formato JSON es el equivalente más cercano.

Los datos personalizados son almacenados por el módulo setup en la variable


ansible_facts.ansible_local. Los datos se organizan sobre la base del nombre del
archivo que los definió. Por ejemplo, supongamos que los datos personalizados anteriores son
producidos por un archivo guardado como /etc/ansible/facts.d/custom.fact en el
host administrado. En ese caso, el valor de ansible_facts.ansible_local['custom']
['users']['user1'] es joe.

Puede inspeccionar la estructura de sus datos personalizados mediante la ejecución del módulo
setup en los hosts administrados con un comando ad hoc.

[user@demo ~]$ ansible demo1.example.com -m setup


demo1.example.com | SUCCESS => {
"ansible_facts": {
...output omitted...
"ansible_local": {
"custom": {
"packages": {
"db_package": "mariadb-server",
"web_package": "httpd"
},
"users": {
"user1": "joe",
"user2": "jane"

RH294-RHEL8.0-es-1-20200501 133
capítulo 4 | Administración de variables y hechos

}
}
},
...output omitted...
},
"changed": false
}

Los datos personalizados pueden usarse de la misma manera que los datos predeterminados en
las guías:

[user@demo ~]$ cat playbook.yml


---
- hosts: all
tasks:
- name: Prints various Ansible facts
debug:
msg: >
The package to install on {{ ansible_facts['fqdn'] }}
is {{ ansible_facts['ansible_local']['custom']['packages']
['web_package'] }}

[user@demo ~]$ ansible-playbook playbook.yml


PLAY ***********************************************************************

TASK [Gathering Facts] *****************************************************


ok: [demo1.example.com]

TASK [Prints various Ansible facts] ****************************************


ok: [demo1.example.com] => {
"msg": "The package to install on demo1.example.com is httpd"
}

PLAY RECAP *****************************************************************


demo1.example.com : ok=2 changed=0 unreachable=0 failed=0

Uso de variables mágicas


Algunas variables no son datos o no están configuradas a través del módulo setup, pero también
se establecen de forma automática por Ansible. Estas variables mágicas pueden ser útiles para
obtener información específica de un host administrado particular.

A continuación, se detallan cuatro de las más útiles:

hostvars
Contiene las variables para hosts administrados y puede usarse para obtener los valores para
las variables de otro host administrado. No incluye los datos del host administrado si no se
recopilaron aún para ese host.

group_names
Enumera todos los grupos en los que se encuentra el host administrado actual.

groups
Enumera todos los grupos y hosts en el inventario.

134 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

inventory_hostname
Contiene el nombre de host para el host administrado actual, según se configuró en el
inventario. Este puede ser diferente del nombre de host informado por los datos por diversos
motivos.

También existe una serie de otras “variables mágicas”. Para obtener más información, consulte
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-
precedence-where-should-i-put-a-variable. Una manera de obtener información sobre sus
valores es usar el módulo debug para informar sobre el contenido de la variable hostvars para
un host específico:

[user@demo ~]$ ansible localhost -m debug -a 'var=hostvars["localhost"]'


localhost | SUCCESS => {
"hostvars[\"localhost\"]": {
"ansible_check_mode": false,
"ansible_connection": "local",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/home/student/demo/inventory"
],
"ansible_playbook_python": "/usr/bin/python2",
"ansible_python_interpreter": "/usr/bin/python2",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.7.0",
"major": 2,
"minor": 7,
"revision": 0,
"string": "2.7.0"
},
"group_names": [],
"groups": {
"all": [
"serverb.lab.example.com"
],
"ungrouped": [],
"webservers": [
"serverb.lab.example.com"
]
},
"inventory_hostname": "localhost",
"inventory_hostname_short": "localhost",
"omit": "__omit_place_holder__18d132963728b2cbf7143dd49dc4bf5745fe5ec3",
"playbook_dir": "/home/student/demo"
}
}

RH294-RHEL8.0-es-1-20200501 135
capítulo 4 | Administración de variables y hechos

Referencias
setup - Reúne los datos acerca de los hosts remotos — Documentación Ansible
https://docs.ansible.com/ansible/latest/modules/setup_module.html

Datos locales (Facts.d) — Variables — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/
playbooks_variables.html#local-facts-facts-d

136 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Ejercicio Guiado

Gestión de datos
En este ejercicio, recopilará datos Ansible de un host administrado y los usará en las
reproducciones.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Reunir datos de un host.

• Crear tareas que usen los datos recogidos.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab data-facts start. Este script crea el


directorio de trabajo, data-facts, y lo completa con un archivo de configuración y un
inventario de hosts de Ansible.

[student@workstation ~]$ lab data-facts start

1. En workstation, con el usuario student, cambie al directorio /home/student/data-


facts.

[student@workstation ~]$ cd ~/data-facts


[student@workstation data-facts]$

2. El módulo setup de Ansible recupera datos de sistemas. Ejecute un comando ad hoc


para recuperar los datos para todos los servidores en el grupo webserver. En la salida, se
muestran todos los datos reunidos para servera.lab.example.com en formato JSON.
Revise algunas de las variables exhibidas.

[student@workstation data-facts]$ ansible webserver -m setup


...output omitted...
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.25.250.10"
],
"ansible_all_ipv6_addresses": [
"fe80::2937:3aa3:ea8d:d3b1"
],
...output omitted...

RH294-RHEL8.0-es-1-20200501 137
capítulo 4 | Administración de variables y hechos

3. En workstation, cree un archivo de datos denominado /home/student/data-facts/


custom.fact. El archivo de datos define el paquete que se debe instalar y el servicio que
se inicia en servera. Se debería leer lo siguiente en el archivo:

[general]
package = httpd
service = httpd
state = started
enabled = true

4. Cree la guía setup_facts.yml para crear el directorio remoto /etc/ansible/facts.d


y guardar el archivo custom.fact en ese directorio.

---
- name: Install remote facts
hosts: webserver
vars:
remote_dir: /etc/ansible/facts.d
facts_file: custom.fact
tasks:
- name: Create the remote directory
file:
state: directory
recurse: yes
path: "{{ remote_dir }}"
- name: Install the new facts
copy:
src: "{{ facts_file }}"
dest: "{{ remote_dir }}"

5. Ejecute un comando ad hoc con el módulo setup. Busque la sección ansible_local en


la salida. No debe haber datos personalizados en este momento.

[student@workstation data-facts]$ ansible webserver -m setup


servera.lab.example.com | SUCCESS => {
"ansible_facts": {
...output omitted...
"ansible_local": {}
...output omitted...
},
"changed": false
}

6. Antes de ejecutar la guía, ejecute ansible-playbook --syntax-check para verificar


que su sintaxis sea correcta. Si informa errores, corríjalos antes de pasar al siguiente paso.
Debe ver una salida similar a la siguiente:

[student@workstation data-facts]$ ansible-playbook --syntax-check setup_facts.yml

playbook: setup_facts.yml

138 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

7. Ejecute la guía setup_facts.yml.

[student@workstation data-facts]$ ansible-playbook setup_facts.yml

PLAY [Install remote facts] ****************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Create the remote directory] *********************************************


changed: [servera.lab.example.com]

TASK [Install the new facts] ***************************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

8. Ahora es posible crear la guía principal que usa los datos personalizados y del usuario para
configurar servera. Durante los próximos varios pasos, los agregará al archivo de la guía.
Cree la guía playbook.yml con lo siguiente:

---
- name: Install Apache and starts the service
hosts: webserver

9. Continúe editando el archivo playbook.yml creando la primera tarea que instala el


paquete httpd. Use el dato del usuario para el nombre del paquete.

tasks:
- name: Install the required package
yum:
name: "{{ ansible_facts['ansible_local']['custom']['general']
['package'] }}"
state: latest

10. Cree otra tarea que usa el dato personalizado para iniciar el servicio httpd.

- name: Start the service


service:
name: "{{ ansible_facts['ansible_local']['custom']['general']
['service'] }}"
state: "{{ ansible_facts['ansible_local']['custom']['general']
['state'] }}"
enabled: "{{ ansible_facts['ansible_local']['custom']['general']
['enabled'] }}"

RH294-RHEL8.0-es-1-20200501 139
capítulo 4 | Administración de variables y hechos

11. Al completarse con todas las tareas, la guía completa debe verse de la siguiente forma.
Revise la guía y garantice que todas las tareas estén definidas.

---
- name: Install Apache and starts the service
hosts: webserver

tasks:
- name: Install the required package
yum:
name: "{{ ansible_facts['ansible_local']['custom']['general']
['package'] }}"
state: latest

- name: Start the service


service:
name: "{{ ansible_facts['ansible_local']['custom']['general']
['service'] }}"
state: "{{ ansible_facts['ansible_local']['custom']['general']
['state'] }}"
enabled: "{{ ansible_facts['ansible_local']['custom']['general']
['enabled'] }}"

12. Antes de ejecutar la guía, use un comando ad hoc para verificar que el servicio httpd no se
ejecute actualmente en servera.

[student@workstation data-facts]$ ansible servera.lab.example.com -m command \


> -a 'systemctl status httpd'
servera.lab.example.com | FAILED | rc=4 >>
Unit httpd.service could not be found.non-zero return code

13. Ejecute ansible-playbook --syntax-check para verificar la sintaxis de la guía. Si


informa errores, corríjalos antes de pasar al siguiente paso. Debe ver una salida similar a la
siguiente:

[student@workstation data-facts]$ ansible-playbook --syntax-check playbook.yml

playbook: playbook.yml

14. Con el comando ansible-playbook, ejecute la guía. Observe la salida a medida que
Ansible instala el paquete y, luego, habilite el servicio.

[student@workstation data-facts]$ ansible-playbook playbook.yml

PLAY [Install Apache and start the service] ************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Install the required package] ********************************************


changed: [servera.lab.example.com]

140 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

TASK [Start the service] *******************************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

15. Use un comando ad hoc para ejecutar systemctl a fin de determinar si el servicio httpd
se está ejecutando en servera.

[student@workstation data-facts]$ ansible servera.lab.example.com -m command \


> -a 'systemctl status httpd'
servera.lab.example.com | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset:
disabled)
Active: active (running) since Mon 2019-05-27 07:50:55 EDT; 50s ago
Docs: man:httpd.service(8)
Main PID: 11603 (httpd)
Status: "Running, listening on: port 80"
Tasks: 213 (limit: 4956)
Memory: 24.1M
CGroup: /system.slice/httpd.service
...output omitted...

Finalizar
En workstation, ejecute el script lab data-facts finish para limpiar este ejercicio.

[student@workstation ~]$ lab data-facts finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 141
capítulo 4 | Administración de variables y hechos

Trabajo de laboratorio

Administración de variables y datos


Lista de verificación de rendimiento
En este trabajo de laboratorio, escribirá y ejecutará una guía Ansible que utilice variables,
secretos y datos.

Resultados
Debe ser capaz de definir variables y usar datos en una guía, así como usar variables
definidas en un archivo cifrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab data-review start. El script crea


el directorio de trabajo, /home/student/data-review, y lo completa con un
archivo de configuración de Ansible y un inventario de hosts. El host administrado,
serverb.lab.example.com, está definido en este inventario como miembro del
grupo de hosts webserver. Un desarrollador le ha pedido que escriba una Ansible
Playbook para automatizar la configuración de un entorno de servidor web en
serverb.lab.example.com, que controla el acceso de los usuarios a su sitio web
mediante autenticación básica.

Este es el contenido del subdirectorio files:

• Un archivo de configuración httpd.conf para el servicio web Apache para autenticación


básica
• Un archivo .htaccess que se usa para controlar el acceso al directorio raíz de
documentos del servidor web.
• Un archivo htpasswd que contiene credenciales para los usuarios permitidos

[student@workstation ~]$ lab data-review start

1. En el directorio de trabajo, cree la guía playbook.yml y agregue el grupo de hosts


webserver como el host administrado. Defina las siguientes variables de reproducción:

142 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Variables

Variable Valores

firewall_pkg firewalld

firewall_svc firewalld

web_pkg httpd

web_svc httpd

ssl_pkg mod_ssl

httpdconf_src files/httpd.conf

httpdconf_dest /etc/httpd/conf/httpd.conf

htaccess_src files/.htaccess

secrets_dir /etc/httpd/secrets

secrets_src files/htpasswd

secrets_dest "{{ secrets_dir }}/htpasswd"

web_root /var/www/html

2. Agregue una sección tasks a la reproducción. Escriba una tarea que garantice que esté
instalada la última versión de los paquetes necesarios. Estos paquetes están definidos por las
variables firewall_pkg, web_pkg y ssl_pkg.
3. Agregue una segunda tarea a la guía que garantice que el archivo especificado por la variable
httpdconf_src ha sido copiado (con el módulo copy) en la ubicación especificada por
la variable httpdconf_dest en el host administrado. El archivo debe ser propiedad del
usuario root y el grupo root. También establece 0644 como los permisos de archivo.
4. Agregue una tercera tarea que use el módulo file para crear el directorio especificado por
la variable secrets_dir en el host administrado. Este directorio contiene los archivos de
contraseña utilizados para la autenticación básica de los servicios web. El archivo debe ser
propiedad del usuario apache y el grupo apache. Establezca 0500 como los permisos de
archivo.
5. Agregue una cuarta tarea que use el módulo copy para colocar un archivo htpasswd que
se usará para la autenticación básica de los usuarios web. El origen debe estar definido por
la variable secrets_src. El destino debe estar definido por la variable secrets_dest.
El archivo debe ser propiedad del usuario y el grupo apache. Establezca 0400 como los
permisos de archivo.
6. Agregue una quinta tarea que use el módulo copy para crear un archivo .htaccess en el
directorio raíz del documento del servidor web. Copie el archivo especificado por la variable
htaccess_src en {{web_root}}/.htaccess. El archivo debe ser propiedad del usuario
apache y el grupo apache. Establezca 0400 como los permisos de archivo.
7. Agregue una tercera tarea que use el módulo copy para crear el archivo de contenido
web index.html en el directorio especificado por la variable web_root. El archivo
debe contener el mensaje “HOSTNAME (IPADDRESS) has been customized by Ansible”

RH294-RHEL8.0-es-1-20200501 143
capítulo 4 | Administración de variables y hechos

(HOSTNAME [IPADDRESS] ha sido personalizado por Ansible), donde HOSTNAME es el


nombre de host calificado completo del host administrado e IPADDRESS es su dirección IP
IPv4. Use la opción content para el módulo copy para especificar el contenido del archivo y
los datos de Ansible para especificar el nombre de host y la dirección IP.
8. Agregue una séptima tarea que use el módulo service para habilitar e iniciar el servicio de
firewall en el host administrado.
9. Agregue una octava tarea que use el modulo firewalld para permitir el servicio https
necesario para que los usuarios accedan a servicios web en el host administrado. Este cambio
de firewall debe ser permanente y debe tener lugar inmediatamente.
10. Agregue una tarea final que use el módulo service para habilitar e iniciar el servicio web
en el host administrado para que todos los cambios de configuración se hagan efectivos. El
nombre del servicio web está definido por la variable web_svc.
11. Defina una segunda reproducción destinada a localhost que probará la autenticación
en el servidor web. No necesita aumento de privilegios. Defina una variable denominada
web_user con el valor guest.
12. Agregue una directiva a la reproducción que agregue variables adicionales de un archivo de
variables llamado vars/secret.yml. Este archivo contiene una variable que especifica la
contraseña para el usuario web. Creará este archivo más adelante en el trabajo de laboratorio.
Defina el inicio de la lista de tareas.
13. Agregue dos tareas a la segunda reproducción.
La primera usa el módulo uri para solicitar contenido de https://
serverb.lab.example.com mediante la autenticación básica. Tenga en cuenta que
el certificado presentado por serverb no será de confianza, por lo que deberá evitar la
validación de certificados. La tarea debe verificar un código de estado HTTP de retorno de
200. Configure la tarea para colocar el contenido devuelto en la variable de resultados de la
tarea. Registre el resultado de la tarea en una variable.
La segunda tarea usa el módulo debug para imprimir el contenido devuelto desde el servidor
web.
14. Cree un archivo cifrado con Ansible Vault, llamado vars/secret.yml. Debe establecer la
variable web_pass a redhat, que será la contraseña del usuario web.
15. Ejecute la guía playbook.yml. Verifique que el contenido se haya devuelto correctamente
desde el servidor web y que coincida con lo que se configuró en una tarea anterior.

Evaluación
En workstation, ejecute el comando lab data-review grade para confirmar que ha realizado
correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script hasta
obtener un resultado satisfactorio.

[student@workstation ~]$ lab data-review grade

Finalizar
En workstation, ejecute el comando lab data-review finish para limpiar este ejercicio.

[student@workstation ~]$ lab data-review finish

Esto concluye el trabajo de laboratorio.

144 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Solución

Administración de variables y datos


Lista de verificación de rendimiento
En este trabajo de laboratorio, escribirá y ejecutará una guía Ansible que utilice variables,
secretos y datos.

Resultados
Debe ser capaz de definir variables y usar datos en una guía, así como usar variables
definidas en un archivo cifrado.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab data-review start. El script crea


el directorio de trabajo, /home/student/data-review, y lo completa con un
archivo de configuración de Ansible y un inventario de hosts. El host administrado,
serverb.lab.example.com, está definido en este inventario como miembro del
grupo de hosts webserver. Un desarrollador le ha pedido que escriba una Ansible
Playbook para automatizar la configuración de un entorno de servidor web en
serverb.lab.example.com, que controla el acceso de los usuarios a su sitio web
mediante autenticación básica.

Este es el contenido del subdirectorio files:

• Un archivo de configuración httpd.conf para el servicio web Apache para autenticación


básica
• Un archivo .htaccess que se usa para controlar el acceso al directorio raíz de
documentos del servidor web.
• Un archivo htpasswd que contiene credenciales para los usuarios permitidos

[student@workstation ~]$ lab data-review start

1. En el directorio de trabajo, cree la guía playbook.yml y agregue el grupo de hosts


webserver como el host administrado. Defina las siguientes variables de reproducción:

RH294-RHEL8.0-es-1-20200501 145
capítulo 4 | Administración de variables y hechos

Variables

Variable Valores

firewall_pkg firewalld

firewall_svc firewalld

web_pkg httpd

web_svc httpd

ssl_pkg mod_ssl

httpdconf_src files/httpd.conf

httpdconf_dest /etc/httpd/conf/httpd.conf

htaccess_src files/.htaccess

secrets_dir /etc/httpd/secrets

secrets_src files/htpasswd

secrets_dest "{{ secrets_dir }}/htpasswd"

web_root /var/www/html

1.1. Cambie al directorio de trabajo /home/student/data-review.

[student@workstation ~]$ cd ~/data-review


[student@workstation data-review]$

1.2. Cree el archivo de guía playbook.yml y edítelo en un editor de texto. El inicio del
archivo debe aparecer de la siguiente manera:

---
- name: install and configure webserver with basic auth
hosts: webserver
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
web_pkg: httpd
web_svc: httpd
ssl_pkg: mod_ssl
httpdconf_src: files/httpd.conf
httpdconf_dest: /etc/httpd/conf/httpd.conf
htaccess_src: files/.htaccess
secrets_dir: /etc/httpd/secrets
secrets_src: files/htpasswd
secrets_dest: "{{ secrets_dir }}/htpasswd"
web_root: /var/www/html

146 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

2. Agregue una sección tasks a la reproducción. Escriba una tarea que garantice que esté
instalada la última versión de los paquetes necesarios. Estos paquetes están definidos por las
variables firewall_pkg, web_pkg y ssl_pkg.

2.1. Defina el comienzo de la sección tasks agregando la siguiente línea a la guía:

tasks:

2.2. Agregue las siguientes líneas a la guía para definir una tarea que utilice el módulo yum
para instalar los paquetes necesarios.

- name: latest version of necessary packages installed


yum:
name:
- "{{ firewall_pkg }}"
- "{{ web_pkg }}"
- "{{ ssl_pkg }}"
state: latest

3. Agregue una segunda tarea a la guía que garantice que el archivo especificado por la variable
httpdconf_src ha sido copiado (con el módulo copy) en la ubicación especificada por
la variable httpdconf_dest en el host administrado. El archivo debe ser propiedad del
usuario root y el grupo root. También establece 0644 como los permisos de archivo.
Agregue las siguientes líneas a la guía para definir una tarea que usa el módulo copy para
copiar el contenido del archivo definido por la variable httpdconf_src en la ubicación
especificada por la variable httpdconf_dest.

- name: configure web service


copy:
src: "{{ httpdconf_src }}"
dest: "{{ httpdconf_dest }}"
owner: root
group: root
mode: 0644

4. Agregue una tercera tarea que use el módulo file para crear el directorio especificado por
la variable secrets_dir en el host administrado. Este directorio contiene los archivos de
contraseña utilizados para la autenticación básica de los servicios web. El archivo debe ser
propiedad del usuario apache y el grupo apache. Establezca 0500 como los permisos de
archivo.
Agregue las siguientes líneas a la guía para definir una tarea que use el módulo file para
crear el directorio definido por la variable secrets_dir.

- name: secrets directory exists


file:
path: "{{ secrets_dir }}"
state: directory
owner: apache
group: apache
mode: 0500

5. Agregue una cuarta tarea que use el módulo copy para colocar un archivo htpasswd que
se usará para la autenticación básica de los usuarios web. El origen debe estar definido por

RH294-RHEL8.0-es-1-20200501 147
capítulo 4 | Administración de variables y hechos

la variable secrets_src. El destino debe estar definido por la variable secrets_dest.


El archivo debe ser propiedad del usuario y el grupo apache. Establezca 0400 como los
permisos de archivo.

- name: htpasswd file exists


copy:
src: "{{ secrets_src }}"
dest: "{{ secrets_dest }}"
owner: apache
group: apache
mode: 0400

6. Agregue una quinta tarea que use el módulo copy para crear un archivo .htaccess en el
directorio raíz del documento del servidor web. Copie el archivo especificado por la variable
htaccess_src en {{web_root}}/.htaccess. El archivo debe ser propiedad del usuario
apache y el grupo apache. Establezca 0400 como los permisos de archivo.
Agregue las siguientes líneas a la guía para definir una tarea que utilice el módulo copy para
crear el archivo .htaccess definido por la variable htaccess_src.

- name: .htaccess file installed in docroot


copy:
src: "{{ htaccess_src }}"
dest: "{{ web_root }}/.htaccess"
owner: apache
group: apache
mode: 0400

7. Agregue una tercera tarea que use el módulo copy para crear el archivo de contenido
web index.html en el directorio especificado por la variable web_root. El archivo
debe contener el mensaje “HOSTNAME (IPADDRESS) has been customized by Ansible”
(HOSTNAME [IPADDRESS] ha sido personalizado por Ansible), donde HOSTNAME es el
nombre de host calificado completo del host administrado e IPADDRESS es su dirección IP
IPv4. Use la opción content para el módulo copy para especificar el contenido del archivo y
los datos de Ansible para especificar el nombre de host y la dirección IP.
Agregue las siguientes líneas a la guía para definir una tarea que utilice el módulo
copy para crear el archivo index.html en el directorio definido por la variable
web_root. Rellene el archivo con el contenido especificado usando los datos de Ansible
ansible_facts['fqdn'] y ansible_facts['default_ipv4']['address']
recuperados del host administrado.

- name: create index.html


copy:
content: "{{ ansible_facts['fqdn'] }} ({{ ansible_facts['default_ipv4']
['address'] }}) has been customized by Ansible.\n"
dest: "{{ web_root }}/index.html"

148 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

8. Agregue una séptima tarea que use el módulo service para habilitar e iniciar el servicio de
firewall en el host administrado.
Agregue las siguientes líneas a la guía para definir una tarea que use el módulo service para
habilitar e iniciar el servicio de firewall.

- name: firewall service enabled and started


service:
name: "{{ firewall_svc }}"
state: started
enabled: true

9. Agregue una octava tarea que use el modulo firewalld para permitir el servicio https
necesario para que los usuarios accedan a servicios web en el host administrado. Este cambio
de firewall debe ser permanente y debe tener lugar inmediatamente.
Agregue las siguientes líneas a la guía para definir una tarea que use el módulo firewalld
para abrir el puerto HTTPS para el servicio web.

- name: open the port for the web server


firewalld:
service: https
state: enabled
immediate: true
permanent: true

10. Agregue una tarea final que use el módulo service para habilitar e iniciar el servicio web
en el host administrado para que todos los cambios de configuración se hagan efectivos. El
nombre del servicio web está definido por la variable web_svc.

- name: web service enabled and started


service:
name: "{{ web_svc }}"
state: started
enabled: true

11. Defina una segunda reproducción destinada a localhost que probará la autenticación
en el servidor web. No necesita aumento de privilegios. Defina una variable denominada
web_user con el valor guest.

11.1. Agregue la siguiente línea para definir el comienzo de una segunda reproducción.
Tenga en cuenta que no hay sangría.

- name: test web server with basic auth

11.2. Agregue la siguiente línea para indicar que la reproducción se aplica al host
administrado localhost.

hosts: localhost

11.3. Agregue la siguiente línea para deshabilitar el aumento de privilegios.

become: no

RH294-RHEL8.0-es-1-20200501 149
capítulo 4 | Administración de variables y hechos

11.4. Agregue las siguientes líneas para definir una lista de variables y la variable web_user.

vars:
web_user: guest

12. Agregue una directiva a la reproducción que agregue variables adicionales de un archivo de
variables llamado vars/secret.yml. Este archivo contiene una variable que especifica la
contraseña para el usuario web. Creará este archivo más adelante en el trabajo de laboratorio.
Defina el inicio de la lista de tareas.

12.1. Con la palabra clave vars_files, agregue las siguientes líneas a la guía para indicar
a Ansible que use las variables que se encuentran en el archivo de variables vars/
secret.yml.

vars_files:
- vars/secret.yml

12.2. Agregue la siguiente línea para definir el comienzo de la lista tasks.

tasks:

13. Agregue dos tareas a la segunda reproducción.


La primera usa el módulo uri para solicitar contenido de https://
serverb.lab.example.com mediante la autenticación básica. Tenga en cuenta que
el certificado presentado por serverb no será de confianza, por lo que deberá evitar la
validación de certificados. La tarea debe verificar un código de estado HTTP de retorno de
200. Configure la tarea para colocar el contenido devuelto en la variable de resultados de la
tarea. Registre el resultado de la tarea en una variable.
La segunda tarea usa el módulo debug para imprimir el contenido devuelto desde el servidor
web.

13.1. Agregue las siguientes líneas para crear la tarea a fin de verificar el servicio web del
nodo de control. Asegúrese de aplicar una sangría de cuatro espacios a la primera línea.

- name: connect to web server with basic auth


uri:
url: https://serverb.lab.example.com
validate_certs: no
force_basic_auth: yes
user: "{{ web_user }}"
password: "{{ web_pass }}"
return_content: yes
status_code: 200
register: auth_test

13.2. Cree la segunda tarea usando el módulo de depuración. El contenido devuelto desde el
servidor web se agrega a la variable registrada como la clave content.

- debug:
var: auth_test.content

13.3. La guía completa debe verse de la siguiente manera:

150 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

---
- name: install and configure webserver with basic auth
hosts: webserver
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
web_pkg: httpd
web_svc: httpd
ssl_pkg: mod_ssl
httpdconf_src: files/httpd.conf
httpdconf_dest: /etc/httpd/conf/httpd.conf
htaccess_src: files/.htaccess
secrets_dir: /etc/httpd/secrets
secrets_src: files/htpasswd
secrets_dest: "{{ secrets_dir }}/htpasswd"
web_root: /var/www/html
tasks:
- name: latest version of necessary packages installed
yum:
name:
- "{{ firewall_pkg }}"
- "{{ web_pkg }}"
- "{{ ssl_pkg }}"
state: latest

- name: configure web service


copy:
src: "{{ httpdconf_src }}"
dest: "{{ httpdconf_dest }}"
owner: root
group: root
mode: 0644

- name: secrets directory exists


file:
path: "{{ secrets_dir }}"
state: directory
owner: apache
group: apache
mode: 0500

- name: htpasswd file exists


copy:
src: "{{ secrets_src }}"
dest: "{{ secrets_dest }}"
owner: apache
group: apache
mode: 0400

- name: .htaccess file installed in docroot


copy:
src: "{{ htaccess_src }}"
dest: "{{ web_root }}/.htaccess"

RH294-RHEL8.0-es-1-20200501 151
capítulo 4 | Administración de variables y hechos

owner: apache
group: apache
mode: 0400

- name: create index.html


copy:
content: "{{ ansible_facts['fqdn'] }} ({{ ansible_facts['default_ipv4']
['address'] }}) has been customized by Ansible.\n"
dest: "{{ web_root }}/index.html"

- name: firewall service enable and started


service:
name: "{{ firewall_svc }}"
state: started
enabled: true

- name: open the port for the web server


firewalld:
service: https
state: enabled
immediate: true
permanent: true

- name: web service enabled and started


service:
name: "{{ web_svc }}"
state: started
enabled: true

- name: test web server with basic auth


hosts: localhost
become: no
vars:
- web_user: guest
vars_files:
- vars/secret.yml
tasks:
- name: connect to web server with basic auth
uri:
url: https://serverb.lab.example.com
validate_certs: no
force_basic_auth: yes
user: "{{ web_user }}"
password: "{{ web_pass }}"
return_content: yes
status_code: 200
register: auth_test

- debug:
var: auth_test.content

13.4. Guarde y cierre el archivo playbook.yml.

14. Cree un archivo cifrado con Ansible Vault, llamado vars/secret.yml. Debe establecer la
variable web_pass a redhat, que será la contraseña del usuario web.

152 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

14.1. Cree un subdirectorio llamado vars en el directorio de trabajo.

[student@workstation data-review]$ mkdir vars

14.2. Cree el archivo de variables cifrado, vars/secret.yml, usando Ansible Vault.


Establezca la contraseña para el archivo cifrado como redhat.

[student@workstation data-review]$ ansible-vault create vars/secret.yml


New Vault password: redhat
Confirm New Vault password: redhat

14.3. Agregue la siguiente definición de variables al archivo.

web_pass: redhat

14.4. Guarde y cierre el archivo.

15. Ejecute la guía playbook.yml. Verifique que el contenido se haya devuelto correctamente
desde el servidor web y que coincida con lo que se configuró en una tarea anterior.

15.1. Antes de ejecutar la guía, ejecute ansible-playbook --syntax-check para


verificar que su sintaxis sea correcta. Utilice el --ask-vault-pass para que se le
solicite la contraseña del almacén. Escriba redhat como contraseña cuando se le
solicite. Si informa errores, corríjalos antes de pasar al siguiente paso. Debe ver un
resultado similar al siguiente:

[student@workstation data-review]$ ansible-playbook --syntax-check \


> --ask-vault-pass playbook.yml
Vault password: redhat

playbook: playbook.yml

15.2. Con el comando ansible-playbook, ejecute la guía con la opción --ask-vault-


pass. Escriba redhat como contraseña cuando se le solicite.

[student@workstation data-review]$ ansible-playbook playbook.yml --ask-vault-pass


Vault password: redhat
PLAY [Install and configure webserver with basic auth] *********************

...output omitted...

TASK [connect to web server with basic auth] ***********************************


ok: [localhost]

TASK [debug] *******************************************************************


ok: [localhost] => {
"auth_test.content": "serverb.lab.example.com (172.25.250.11) has been
customized by Ansible.\n"
}

RH294-RHEL8.0-es-1-20200501 153
capítulo 4 | Administración de variables y hechos

PLAY RECAP *********************************************************************


localhost : ok=3 changed=0 unreachable=0 failed=0
serverb.lab.example.com : ok=10 changed=8 unreachable=0 failed=0

Evaluación
En workstation, ejecute el comando lab data-review grade para confirmar que ha realizado
correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script hasta
obtener un resultado satisfactorio.

[student@workstation ~]$ lab data-review grade

Finalizar
En workstation, ejecute el comando lab data-review finish para limpiar este ejercicio.

[student@workstation ~]$ lab data-review finish

Esto concluye el trabajo de laboratorio.

154 RH294-RHEL8.0-es-1-20200501
capítulo 4 | Administración de variables y hechos

Resumen
En este capítulo, aprendió lo siguiente:

• Las variables de Ansible permiten a los administradores reutilizar valores en los archivos de un
proyecto completo de Ansible.

• Las variables se pueden definir para los hosts y los grupos de hosts en el archivo de inventario.

• Las variables se pueden definir para las guías usando datos y archivos externos. También se
pueden definir en la línea de comando.

• La palabra clave register se puede usar para capturar la salida de un comando en una
variable.

• Ansible Vault es una manera de proteger los datos confidenciales, como los hash de contraseñas
y las claves privadas para la implementación, con Ansible Playbook.

• Los datos de Ansible son variables automáticamente descubiertas por Ansible desde un host
administrado.

RH294-RHEL8.0-es-1-20200501 155
156 RH294-RHEL8.0-es-1-20200501
capítulo 5

Implementación del control de


tareas
Meta Administrar el control de tareas, los manejadores y
los errores de tareas en Ansible Playbooks.

Objetivos • Implementar bucles para escribir tareas


eficientes a fin de controlar cuándo ejecutar
tareas.
• Implementar una tarea que se ejecute solo
cuando otra tarea cambie el host administrado.
• Controlar lo que sucede cuando falla una tarea
y qué condiciones hacen que falle una tarea.

Secciones • Escritura de bucles y tareas condicionales (y


ejercicio guiado)
• Implementación de manejadores (y ejercicio
guiado)
• Manejo de fallas de tareas (y ejercicio guiado)

Trabajo de • Implementación del control de tareas


laboratorio

RH294-RHEL8.0-es-1-20200501 157
capítulo 5 | Implementación del control de tareas

Escritura de bucles y tareas condicionales

Objetivos
Después de completar esta sección, debe ser capaz de usar bucles para escribir tareas eficientes y
usar condiciones para controlar cuándo ejecutar tareas.

Iteración de tareas con bucles


El uso de bucles elimina la necesidad de los administradores de escribir varias tareas que usen el
mismo módulo. Por ejemplo, en lugar de escribir cinco tareas para garantizar que existan cinco
usuarios, puede escribir una tarea que itere sobre una lista de cinco usuarios para garantizar que
existan todos.

Ansible admite la iteración de una tarea sobre un conjunto de elementos utilizando la palabra clave
loop. Puede configurar los bucles para que repitan una tarea con cada elemento en una lista, el
contenido de cada uno de los archivos en una lista, una secuencia de números generada o con
estructuras más complicadas. En esta sección, se cubren bucles simples que iteran sobre una lista
de elementos. Consulte la documentación para ver escenarios de bucle más avanzados.

Bucles simples
Un bucle simple itera una tarea sobre una lista de elementos. Se agrega la palabra clave loop a la
tarea, y esta toma como valor la lista de elementos sobre los cuales se debería iterar la tarea. La
variable de bucle item contiene el valor usado durante cada iteración.

Considere el siguiente fragmento que usa el módulo service dos veces para garantizar que se
estén ejecutando dos servicios de red:

- name: Postfix is running


service:
name: postfix
state: started

- name: Dovecot is running


service:
name: dovecot
state: started

Estas dos tareas pueden reescribirse para usar un bucle simple, de modo que se necesita solo una
tarea para garantizar que se ejecuten ambos servicios:

- name: Postfix and Dovecot are running


service:
name: "{{ item }}"
state: started
loop:
- postfix
- dovecot

158 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

La lista usada por loop puede ser provista por una variable. En el siguiente ejemplo, la variable
mail_services contiene la lista de servicios que se deben ejecutar.

vars:
mail_services:
- postfix
- dovecot

tasks:
- name: Postfix and Dovecot are running
service:
name: "{{ item }}"
state: started
loop: "{{ mail_services }}"

Bucles sobre una lista de hashes o diccionarios


La lista loop no necesita ser una lista de valores simples. En el siguiente ejemplo, cada elemento
de la lista es en realidad un hash o diccionario. Cada hash o diccionario del ejemplo tiene dos
claves, name y groups, y el valor de cada clave en la variable de bucle item actual puede
obtenerse con las variables item.name y item.groups, respectivamente.

- name: Users exist and are in the correct groups


user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- name: jane
groups: wheel
- name: joe
groups: root

El resultado de la tarea anterior es que el usuario jane está presente y es un miembro del grupo
wheel, y el usuario joe está presente y es un miembro del grupo root.

Palabras clave de bucle del estilo anterior


Antes de Ansible 2.5, la mayoría de las guías usaban una sintaxis diferente para los bucles. Se
proporcionaron varias palabras clave de bucle, que fueron prefijadas con with_, seguido del
nombre de un complemento (plug-in) de búsqueda Ansible (una característica avanzada que no
se trata en detalle en este curso). Esta sintaxis para el bucle es muy común en las guías existentes,
pero es probable que se considere obsoleta en algún momento en el futuro.

Algunos ejemplos se enumeran en la siguiente tabla:

RH294-RHEL8.0-es-1-20200501 159
capítulo 5 | Implementación del control de tareas

Bucles Ansible del estilo anterior

Palabra clave del bucle Descripción

with_items Se comporta igual que la palabra clave loop para listas simples,
como una lista de cadenas o una lista de hashes/dictionarios.
A diferencia de loop, si se proporcionan listas de listas a
with_items, se aplanan en una lista de nivel simple. La variable
de bucle item contiene el elemento de lista usado durante cada
iteración.

with_file Esta palabra clave requiere una lista de nombres de archivo de


nodo de control. La variable de bucle item incluye el contenido
de un archivo correspondiente de la lista de archivos durante cada
iteración.

with_sequence En lugar de requerir una lista, esta palabra clave requiere


parámetros para generar una lista de valores basada en una
secuencia numérica. La variable de bucle item incluye el valor de
uno de los elementos generados en la secuencia generada durante
cada iteración.

A continuación se muestra un ejemplo de with_items en una guía:

vars:
data:
- user0
- user1
- user2
tasks:
- name: "with_items"
debug:
msg: "{{ item }}"
with_items: "{{ data }}"

Importante
Desde Ansible 2.5, la forma recomendada de escribir bucles es usar la palabra clave
loop.

Sin embargo, todavía debe entender la sintaxis antigua, especialmente


with_items, porque es ampliamente utilizada en las guías existentes. Es probable
que encuentre guías y roles que continúen usando palabras clave with_* para el
bucle.

Cualquier tarea que use la sintaxis antigua se puede convertir para usar loop conjuntamente con
filtros Ansible. No necesita saber cómo usar los filtros Ansible para hacer esto. Hay una buena
referencia sobre cómo convertir los bucles antiguos a la nueva sintaxis, así como ejemplos de
cómo realizar un bucle sobre los ítems que no son listas simples, en la documentación de Ansible,
en la sección Migración de with_X a bucle [https://docs.ansible.com/ansible/latest/user_guide/
playbooks_loops.html#migrating-from-with-x-to-loop] de la Guía del usuario Ansible.

Es probable que encuentre tareas de guías más antiguas que contienen palabras clave with_*.

160 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

Las técnicas avanzadas de bucle están fuera del alcance de este curso. Todas las tareas de
iteración en este curso se pueden implementar ya sea con la palabra clave with_items o loop.

Uso de variables de registro con bucles


La palabra clave register también puede capturar la salida de una tarea que realiza un bucle. El
siguiente fragmento de código muestra la estructura de la variable de registro de una tarea que
realiza un bucle:

[student@workstation loopdemo]$ cat loop_register.yml


---
- name: Loop Register Test
gather_facts: no
hosts: localhost
tasks:
- name: Looping Echo Task
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results

- name: Show echo_results variable


debug:
var: echo_results

La variable echo_results está registrada.


El contenido de la variable echo_results se muestra en pantalla.

Al ejecutar la guía anterior, se obtiene la siguiente salida:

[student@workstation loopdemo]$ ansible-playbook loop_register.yml


PLAY [Loop Register Test] ****************************************************

TASK [Looping Echo Task] *****************************************************


...output omitted...
TASK [Show echo_results variable] ********************************************
ok: [localhost] => {
"echo_results": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
...output omitted...
"changed": true,
"cmd": "echo This is my item: one",
"delta": "0:00:00.011865",
"end": "2018-11-01 16:32:56.080433",
"failed": false,
...output omitted...
"item": "one",
"rc": 0,

RH294-RHEL8.0-es-1-20200501 161
capítulo 5 | Implementación del control de tareas

"start": "2018-11-01 16:32:56.068568",


"stderr": "",
"stderr_lines": [],
"stdout": "This is my item: one",
"stdout_lines": [
"This is my item: one"
]
},
{
"_ansible_ignore_errors": null,
...output omitted...
"changed": true,
"cmd": "echo This is my item: two",
"delta": "0:00:00.011142",
"end": "2018-11-01 16:32:56.828196",
"failed": false,
...output omitted...
"item": "two",
"rc": 0,
"start": "2018-11-01 16:32:56.817054",
"stderr": "",
"stderr_lines": [],
"stdout": "This is my item: two",
"stdout_lines": [
"This is my item: two"
]
}
]
}
}
...output omitted...

El carácter { indica que el inicio de la variable echo_results se compone de pares de


claves/valores.
La clave results contiene los resultados de la tarea anterior. El carácter [ indica el inicio de
una lista.
El inicio de los metadatos de la tarea para el primer elemento (indicado por la clave item). La
salida del comando echo se encuentra en la clave stdout.
El inicio de los metadatos del resultado de la tarea para el segundo elemento.
El carácter ] indica el final de la lista results.

En lo anterior, la clave results contiene una lista. A continuación, la guía se modifica de modo
que la segunda tarea itera en esta lista:

[student@workstation loopdemo]$ cat new_loop_register.yml


---
- name: Loop Register Test
gather_facts: no
hosts: localhost
tasks:
- name: Looping Echo Task
shell: "echo This is my item: {{ item }}"
loop:
- one

162 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

- two
register: echo_results

- name: Show stdout from the previous task.


debug:
msg: "STDOUT from previous task: {{ item.stdout }}"
loop: "{{ echo_results['results'] }}"

Después de ejecutar la guía anterior, la salida es:

PLAY [Loop Register Test] ****************************************************

TASK [Looping Echo Task] *****************************************************


...output omitted...

TASK [Show stdout from the previous task.] ***********************************


ok: [localhost] => (item={...output omitted...}) => {
"msg": "STDOUT from previous task: This is my item: one"
}
ok: [localhost] => (item={...output omitted...}) => {
"msg": "STDOUT from previous task: This is my item: two"
}
...output omitted...

Ejecución de tareas de forma condicional


Ansible puede usar condicionales para ejecutar tareas o reproducciones cuando se cumplen
ciertas condiciones. Por ejemplo, un condicional se puede usar para determinar la memoria
disponible en un host administrado antes de que Ansible instale o configure un servicio.

Los condicionales permiten que los administradores diferencien entre hosts administrados y les
asignen roles funcionales según las condiciones que cumplen. Las variables de la guía, las variables
registradas y los datos de Ansible se pueden probar con condicionales. Los operadores para
comparar cadenas, datos numéricos y valores booleanos están disponibles.

Los siguientes escenarios ilustran el uso de condicionales en Ansible:

• Un límite de hardware se puede definir en una variable (por ejemplo, min_memory) y se lo


puede comparar con la memoria disponible en un host administrado.

• La salida de un comando puede ser capturada y evaluada por Ansible para determinar si se
completó una tarea antes de tomar otras medidas. Por ejemplo, si falla un programa, se omite un
lote.

• Utilice los datos de Ansible para determinar la configuración de la red del host administrado y
decida qué archivo de plantilla enviar (por ejemplo, unificación o enlace troncal de red).

• El número de CPU se puede evaluar para determinar cómo ajustar adecuadamente un servidor
web.

• Compare una variable registrada con una variable predefinida para determinar si un servicio
cambió. Por ejemplo, pruebe la suma de comprobación MD5 de un archivo de configuración de
servicio para ver si se modifica el servicio.

RH294-RHEL8.0-es-1-20200501 163
capítulo 5 | Implementación del control de tareas

Sintaxis condicional de tareas


El enunciado when se usa para ejecutar una tarea de forma condicional. Toma como valor la
condición para realizar pruebas. Si se cumple la condición, se ejecuta la tarea. Si no se cumple la
condición, se omite la tarea.

Una de las condiciones más simples que pueden probarse es si una variable booleana es
verdadera o falsa. El enunciado when en el siguiente ejemplo hace que la tarea se ejecute solo si
run_my_task es verdadero:

---
- name: Simple Boolean Task Demo
hosts: all
vars:
run_my_task: true

tasks:
- name: httpd package is installed
yum:
name: httpd
when: run_my_task

El siguiente ejemplo es un poco más sofisticado y prueba si la variable my_service tiene un valor.
Si lo hace, el valor de my_service se usa como nombre del paquete para instalar. Si la variable
my_service no está definida, la tarea se omite sin errores.

---
- name: Test Variable is Defined Demo
hosts: all
vars:
my_service: httpd

tasks:
- name: "{{ my_service }} package is installed"
yum:
name: "{{ my_service }}"
when: my_service is defined

En la siguiente tabla, se muestran algunas de las operaciones que pueden utilizar los
administradores al trabajar con condicionales:

Ejemplos de condicionales

Operación Ejemplo

Igual (el valor es una cadena) ansible_machine == "x86_64"

Igual (el valor es numérico) max_memory == 512

Menor que min_memory < 128

Mayor que min_memory > 256

Menor que o igual a min_memory <= 256

164 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

Operación Ejemplo

Mayor que o igual a min_memory >= 512

No es igual a min_memory != 512

La variable existe min_memory is defined

La variable no existe min_memory is not defined

La variable booleana es true. memory_available


Los valores de 1, True, o yes
son true.

La variable booleana es not memory_available


false. Los valores de 0,
False, o no son false.

El valor de la primera variable ansible_distribution in supported_distros


está presente como valor en
la lista de la segunda variable

La última entrada en la tabla anterior puede ser confusa al principio. El siguiente ejemplo ilustra
cómo funciona.

En el ejemplo, la variable ansible_distribution es un dato determinado durante la tarea


Gathering Facts, e identifica la distribución del sistema operativo del host administrado. El
autor de la guía creó la variable supported_distros, y contiene una lista de las distribuciones
de sistemas operativos que admite la guía. Si el valor de ansible_distribution se encuentra
en la lista supported_distros, pasa el condicional y se ejecuta la tarea.

---
- name: Demonstrate the "in" keyword
hosts: all
gather_facts: yes
vars:
supported_distros:
- RedHat
- Fedora
tasks:
- name: Install httpd using yum, where supported
yum:
name: http
state: present
when: ansible_distribution in supported_distros

RH294-RHEL8.0-es-1-20200501 165
capítulo 5 | Implementación del control de tareas

Importante
Observe la sangría de la declaración when. Debido a que la declaración when no es
una variable de módulo, se la debe colocar fuera del módulo con sangría en el nivel
superior de la tarea.

Una tarea es un diccionario/hash YAML, y la declaración when es simplemente


una clave más en la tarea, como el nombre de la tarea y el módulo que usa. Una
convención común coloca cualquier palabra clave when que pueda estar presente
después del nombre de la tarea y del módulo (y los argumentos del módulo).

Realización de pruebas de varias condiciones


Una declaración when se puede usar para evaluar condicionales múltiples. Para ello, los
condicionales se pueden combinar con las palabras clave and u or y se pueden agrupar con
paréntesis.

En los siguientes fragmentos, se muestran algunos ejemplos de cómo expresar condiciones


múltiples.

• Si una declaración condicional se debe cumplir cuando ambas condiciones son verdaderas, debe
utilizar la declaración or. Por ejemplo, la siguiente condición se cumple si la máquina ejecuta
Red Hat Enterprise Linux o Fedora:

when: ansible_distribution == "RedHat" or ansible_distribution == "Fedora"

• Con la operación and, ambas condiciones deben ser verdaderas para que se cumpla con toda
la declaración condicional. Por ejemplo, la siguiente condición se cumple si el host remoto es un
host Red Hat Enterprise Linux 7.5, y el kernel instalado es la versión especificada:

when: ansible_distribution_version == "7.5" and ansible_kernel ==


"3.10.0-327.el7.x86_64"

La palabra clave when también admite el uso de una lista para describir una lista de condiciones.
Cuando se proporciona una lista a la palabra clave when, todos los condicionales se combinan
utilizando la operación and. En el siguiente ejemplo, se muestra otra forma de combinar varias
declaraciones condicionales usando el operador and:

when:
- ansible_distribution_version == "7.5"
- ansible_kernel == "3.10.0-327.el7.x86_64"

Este formato mejora la legibilidad, un objetivo clave de una guía Ansible bien escrita.

• Se pueden expresar declaraciones condicionales más complejas agrupando las condiciones con
paréntesis. Esto asegura que se interpreten correctamente.

Por ejemplo, la siguiente declaración condicional se cumple si la máquina ejecuta Red Hat
Enterprise Linux 7 o Fedora 28: Este ejemplo usa el carácter mayor que (>) para que el
condicional largo se pueda dividir en varias líneas en la guía, a fin de que sea más fácil de leer.

166 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

when: >
( ansible_distribution == "RedHat" and
ansible_distribution_major_version == "7" )
or
( ansible_distribution == "Fedora" and
ansible_distribution_major_version == "28" )

Combinación de bucles y tareas condicionales


Puede combinar los bucles y los condicionales.

En el siguiente ejemplo, el paquete mariadb-server se instala mediante el módulo yum si hay


un sistema de archivo instalado en / con más de 300 MB libres. El dato ansible_mounts es
una lista de diccionarios, cada uno de los cuales representa información acerca de un sistema
de archivos instalado. El bucle realiza la iteración de cada diccionario en la lista, y la declaración
condicional no se cumple, a menos que se determine que un diccionario representa un sistema de
archivos montado en donde ambas condiciones son verdaderas.

- name: install mariadb-server if enough space on root


yum:
name: mariadb-server
state: latest
loop: "{{ ansible_mounts }}"
when: item.mount == "/" and item.size_available > 300000000

Importante
Cuando usa when con loop para una tarea, se verifica la declaración when de cada
ítem.

Este es otro ejemplo que combina condicionales y variables de registro. La siguiente guía anotada
reinicia el servicio httpd únicamente si se ejecuta el servicio postfix.

---
- name: Restart HTTPD if Postfix is Running
hosts: all
tasks:
- name: Get Postfix server status
command: /usr/bin/systemctl is-active postfix
ignore_errors: yes
register: result

- name: Restart Apache HTTPD based on Postfix status


service:
name: httpd
state: restarted
when: result.rc == 0

¿Se está ejecutando Postfix o no?


Si no se está ejecutando y el comando falla, no detenga el procesamiento.
Guarda información en el resultado del módulo en una variable denominada result.

RH294-RHEL8.0-es-1-20200501 167
capítulo 5 | Implementación del control de tareas

Evalúa la salida de la tarea Postfix. Si el código de salida del comando systemctl es 0,


Postfix está activo y esta tarea reinicia el servicio httpd.

Referencias
Bucles — Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html

Evaluaciones — Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html

Condicionales — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html

Qué implica un nombre de variable válido — Variables — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/
playbooks_variables.html#what-makes-a-valid-variable-name

168 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

Ejercicio Guiado

Escritura de bucles y tareas condicionales


En este ejercicio, escribirá una guía que contiene tareas con condicionales y bucles.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Implementar condicionales Ansible usando la palabra clave when.

• Implementar la iteración de tareas usando la palabra clave loop junto con condicionales.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab control-flow start. Este script crea el


directorio de trabajo, /home/student/control-flow.

[student@workstation ~]$ lab control-flow start

1. En workstation.lab.example.com, vaya al directorio del proyecto /home/student/


control-flow.

[student@workstation ~]$ cd ~/control-flow


[student@workstation control-flow]$

2. El script del trabajo de laboratorio creó un archivo de configuración Ansible, así


como un archivo de inventario. Este archivo de inventario contiene el servidor
servera.lab.example.com en el grupo de hosts database_dev, y el servidor
serverb.lab.example.com en el grupo de hosts database_prod. Revise el archivo
antes de continuar.

[student@workstation control-flow]$ cat inventory


[database_dev]
servera.lab.example.com

[database_prod]
serverb.lab.example.com

3. Cree la guía playbook.yml, que contiene una reproducción con dos tareas. Use el grupo
de hosts database_dev. La primera tarea instala los paquetes requeridos por MariaDB, y
la segunda tarea garantiza que el servicio MariaDB se está ejecutando.

3.1. Abra la guía en un editor de texto. Defina la variable mariadb_packages con dos
valores: mariadb-server y python3-PyMySQL. La guía usa la variable para instalar
los paquetes requeridos. Se debería leer lo siguiente en el archivo:

RH294-RHEL8.0-es-1-20200501 169
capítulo 5 | Implementación del control de tareas

---
- name: MariaDB server is running
hosts: database_dev
vars:
mariadb_packages:
- mariadb-server
- python3-PyMySQL

3.2. Defina una tarea que use el módulo yum y la variable mariadb_packages. La tarea
instala los paquetes requeridos. La tarea debe decir lo siguiente:

tasks:
- name: MariaDB packages are installed
yum:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"

3.3. Defina una segunda tarea para iniciar el servicio mariadb. La tarea debe decir lo
siguiente:

- name: Start MariaDB service


service:
name: mariadb
state: started
enabled: true

4. Ejecute la guía y observe la salida de la reproducción.

[student@workstation control-flow]$ ansible-playbook playbook.yml

PLAY [MariaDB server is running] ***********************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [MariaDB packages are installed] ******************************************


changed: [servera.lab.example.com] => (item=mariadb-server)
changed: [servera.lab.example.com] => (item=python3-PyMySQL)

TASK [Start MariaDB service] ***************************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

5. Actualice la primera tarea para que se ejecute solo si el host administrado usa Red Hat
Enterprise Linux como su sistema operativo. Actualice la reproducción para que use el
grupo de hosts database_prod. La tarea debe decir lo siguiente:

170 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

- name: MariaDB server is running


hosts: database_prod
vars:
...output omitted...
tasks:
- name: MariaDB packages are installed
yum:
name: "{{ item }}"
state: present
loop: "{{ mariadb_packages }}"
when: ansible_distribution == "RedHat"

6. Verifique que los hosts administrados en el grupo de hosts database_prod usen Red Hat
Enterprise Linux como su sistema operativo.

[student@workstation control-flow]$ ansible database_prod -m command \


> -a 'cat /etc/redhat-release' -u devops --become
serverb.lab.example.com | CHANGED | rc=0 >>
Red Hat Enterprise Linux release 8.0 (Ootpa)

7. Ejecute la guía nuevamente y observe la salida de la reproducción.

[student@workstation control-flow]$ ansible-playbook playbook.yml

PLAY [MariaDB server is running] ***********************************************

TASK [Gathering Facts] *********************************************************


ok: [serverb.lab.example.com]

TASK [MariaDB packages are installed] ******************************************


changed: [serverb.lab.example.com] => (item=mariadb-server)
changed: [serverb.lab.example.com] => (item=python3-PyMySQL)

TASK [Start MariaDB service] ***************************************************


changed: [serverb.lab.example.com]

PLAY RECAP *********************************************************************


serverb.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

Ansible ejecuta la tarea porque serverb.lab.example.com usa Red Hat Enterprise


Linux.

Finalizar
En workstation, ejecute el script lab control-flow finish para limpiar los recursos creados
en este ejercicio.

[student@workstation ~]$ lab control-flow finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 171
capítulo 5 | Implementación del control de tareas

Implementación de manejadores

Objetivos
Después de completar esta sección, debe ser capaz de implementar una tarea que se ejecute solo
cuando otra tarea cambie el host administrado.

Manejadores de Ansible
Los módulos Ansible están diseñados para ser idempotentes. Esto implica que en una guía
programada adecuadamente, la guía y sus tareas se pueden ejecutar múltiples veces sin cambiar
el host administrado, a menos que necesiten realizar un cambio para llevar al host administrado a
su estado deseado.

No obstante, algunas veces, cuando una tarea realiza un cambio en el sistema, se puede tener
que ejecutar otra tarea. Por ejemplo, un cambio en un archivo de configuración del servicio puede
luego requerir que el servicio se vuelva a cargar para que se aplique la configuración modificada.

Los manejadores son tareas que responden a una notificación desencadenada por otras tareas.
Las tareas solo notifican a sus manejadores cuando la tarea cambia algo en un host administrado.
Cada controlador tiene un nombre único a nivel global, y se desencadena al final de un bloque
de tareas en una guía. Si ninguna tarea notifica al manejador por nombre, no se ejecutará el
manejador. Si una o más tareas notifican al manejador, el manejador se ejecutará exactamente
una vez después de que todas las demás tareas en la reproducción se hayan completado. Debido
a que los manejadores son tareas, los administradores pueden usar los mismos módulos en
manejadores que utilizarían para cualquier otra tarea. Generalmente, los manejadores se utilizan
para reiniciar los hosts y los servicios.

Los manejadores se pueden considerar como tareas inactive que solo se desencadenan cuando
se las invoca explícitamente mediante una declaración notify. El siguiente fragmento muestra
cómo el servidor Apache solo se reinicia mediante el manejador restart_apache cuando un
archivo de configuración se actualiza y lo notifica:

tasks:
- name: copy demo.example.conf configuration template
template:
src: /var/lib/templates/demo.example.conf.template
dest: /etc/httpd/conf.d/demo.example.conf
notify:
- restart apache

handlers:
- name: restart apache
service:
name: httpd
state: restarted

La tarea que notifica al manejador.


La declaración notify indica que la tarea debe activar un manejador.
El nombre del manejador que debe ejecutarse.

172 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

La palabra clave handlers indica el inicio de la lista de tareas del manejador.


El nombre del manejador invocado por las tareas.
El módulo que usará el manejador.

En el ejemplo anterior, el manejador restart_apache se desencadena al ser notificado por


la tarea template de que se ha producido un cambio. Una tarea puede invocar a más de un
manejador en su sección notify. Ansible trata la declaración notify como un arreglo y realiza
iteración de los nombres del manejador:

tasks:
- name: copy demo.example.conf configuration template
template:
src: /var/lib/templates/demo.example.conf.template
dest: /etc/httpd/conf.d/demo.example.conf
notify:
- restart mysql
- restart apache

handlers:
- name: restart mysql
service:
name: mariadb
state: restarted

- name: restart apache


service:
name: httpd
state: restarted

Descripción de los beneficios del uso de manejadores


Como analizamos en la documentación Ansible, debemos recordar algunos aspectos importantes
acerca del uso de manejadores:

• Los manejadores se ejecutan siempre en el orden especificado por la sección handlers de la


reproducción. No se ejecutan en el orden en que aparecen en la lista por la declaración notify
en una tarea ni en el orden en que las tareas los notifican.

• Los manejadores se ejecutan después de que se hayan completado todas las demás tareas
en la reproducción. Un manejador invocado por una tarea en la parte tasks de la guía no se
ejecutará hasta que se hayan procesado todas las tareas en tasks. (Hay algunas excepciones
menores a esto).

• Los nombres de los manejadores se encuentran en un espacio de nombres por reproducción. Si


erróneamente se asigna a dos manejadores el mismo nombre, se ejecutará uno solo.

• Inclusive si más de una tarea notifica a un manejador, este se ejecuta una sola vez. Si ninguna
tarea lo notifica, no se ejecutará el manejador.

• Si una tarea que incluye una declaración notify no informa un resultado changed (por
ejemplo, un paquete ya se encuentra instalado y la tarea muestra ok), no se notificará al
manejador. Se omitirá el manejador, a menos que otra tarea lo notifique. Ansible notifica a los
manejadores solo si la tarea muestra el estado CHANGED.

RH294-RHEL8.0-es-1-20200501 173
capítulo 5 | Implementación del control de tareas

Importante
Los manejadores están diseñados para realizar una acción adicional cuando una
tarea realiza un cambio en un host administrado. No deben usarse como sustituto
de las tareas normales.

Referencias
Introducción a guías — Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html

174 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

Ejercicio Guiado

Implementación de manejadores
En este ejercicio, implementará manejadores en guías.

Resultados
Debe ser capaz de definir manejadores en guías y notificarlos para un cambio de
configuración.

Andes De Comenzar
Desde workstation, ejecute lab control-handlers start para configurar el
entorno para el ejercicio. Este script crea el directorio del proyecto /home/student/
control-handlers y descarga el archivo de configuración Ansible y el archivo de
inventario del host necesarios para el ejercicio. El directorio del proyecto también contiene
una guía parcialmente completa, configure_db.yml.

[student@workstation ~]$ lab control-handlers start

1. En workstation.lab.example.com, abra un nuevo terminal y vaya al directorio del


proyecto /home/student/control-handlers.

[student@workstation ~]$ cd ~/control-handlers


[student@workstation control-handlers]$

2. En ese directorio, use un editor de texto para editar el archivo de la guía


configure_db.yml. Esta guía instala y configura un servidor de base de datos. Cuando la
configuración del servidor de la base de datos cambia, la guía desencadena un reinicio del
servicio de la base de datos y configura la contraseña administrativa de la base de datos.

2.1. Usando un editor de texto, revise la guía configure_db.yml. Comienza con la


inicialización de algunas variables:

---
- name: MariaDB server is installed
hosts: databases
vars:
db_packages:
- mariadb-server
- python3-PyMySQL
db_service: mariadb
resources_url: http://materials.example.com/labs/control-handlers
config_file_url: "{{ resources_url }}/my.cnf.standard"
config_file_dst: /etc/my.cnf
tasks:

RH294-RHEL8.0-es-1-20200501 175
capítulo 5 | Implementación del control de tareas

db_packages define el nombre de los paquetes que se instalarán para el


servicio de base de datos.
db_service define el nombre del servicio de base de datos.
resources_url representa la URL del directorio de recursos donde se
encuentran los archivos de configuración remota.
config_file_url representa la URL del archivo de configuración de la base
de datos para instalar.
config_file_dst representa la ubicación del archivo de configuración
instalado en los hosts administrados.

2.2. En el archivo configure_db.yml, defina una tarea que usa el módulo yum para
instalar los paquetes de base de datos, según lo define la variable db_packages.
Si la tarea cambia el sistema, la base de datos no se instaló, y debe notificar al
manejador set db password para establecer su usuario de base de datos inicial y
contraseña. Recuerde que la tarea del manejador, si se notifica, no se ejecutará hasta
que todas las tareas en la sección tasks se hayan ejecutado.
La tarea debe decir lo siguiente:

tasks:
- name: "{{ db_packages }} packages are installed"
yum:
name: "{{ db_packages }}"
state: present
notify:
- set db password

2.3. Agregue una tarea para iniciar y habilitar el servicio de base de datos. La tarea debe
decir lo siguiente:

- name: Make sure the database service is running


service:
name: "{{ db_service }}"
state: started
enabled: true

2.4. Agregue una tarea para descargar my.cnf.standard en /etc/my.cnf en el host


administrado, mediante el módulo get_url. Agregue una condición que notifique
al manejador restart db service para reiniciar el servicio de base de datos
después de un cambio de archivo de configuración. La tarea debe decir lo siguiente:

- name: The {{ config_file_dst }} file has been installed


get_url:
url: "{{ config_file_url }}"
dest: "{{ config_file_dst }}"
owner: mysql
group: mysql
force: yes
notify:
- restart db service

176 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

2.5. Agregue la palabra clave handlers para definir el inicio de las tareas del manejador.
Defina el primer manejador, restart db service, que reinicia el servicio
mariadb. Debe decir lo siguiente:

handlers:
- name: restart db service
service:
name: "{{ db_service }}"
state: restarted

2.6. Defina el segundo manejador, set db password, que establece la contraseña


administrativa para el servicio de base de datos. El manejador utiliza el módulo
mysql_user para realizar el comando. En el manejador, se debe leer lo siguiente:

- name: set db password


mysql_user:
name: root
password: redhat

Cuando se complete, la guía debe verse de la siguiente forma:

---
- name: MariaDB server is installed
hosts: databases
vars:
db_packages:
- mariadb-server
- python3-PyMySQL
db_service: mariadb
resources_url: http://materials.example.com/labs/control-handlers
config_file_url: "{{ resources_url }}/my.cnf.standard"
config_file_dst: /etc/my.cnf
tasks:
- name: "{{ db_packages }} packages are installed"
yum:
name: "{{ db_packages }}"
state: present
notify:
- set db password

- name: Make sure the database service is running


service:
name: "{{ db_service }}"
state: started
enabled: true

- name: The {{ config_file_dst }} file has been installed


get_url:
url: "{{ config_file_url }}"
dest: "{{ config_file_dst }}"
owner: mysql
group: mysql
force: yes

RH294-RHEL8.0-es-1-20200501 177
capítulo 5 | Implementación del control de tareas

notify:
- restart db service

handlers:
- name: restart db service
service:
name: "{{ db_service }}"
state: restarted

- name: set db password


mysql_user:
name: root
password: redhat

3. Antes de ejecutar la guía, ejecute ansible-playbook con la opción --syntax-check


para verificar que su sintaxis sea correcta. Si informa errores, corríjalos antes de pasar al
siguiente paso. Debe ver una salida similar a la siguiente:

[student@workstation control-handlers]$ ansible-playbook configure_db.yml \


> --syntax-check

playbook: configure_db.yml

4. Ejecute la guía configure_db.yml. En la salida, se muestra que los manejadores se están


ejecutando.

[student@workstation control-handlers]$ ansible-playbook configure_db.yml

PLAY [Installing MariaDB server] *********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [['mariadb-server', 'python3-PyMySQL'] packages are installed] **********


changed: [servera.lab.example.com]

TASK [Make sure the database service is running] *****************************


changed: [servera.lab.example.com]

TASK [The /etc/my.cnf file has been installed] *******************************


changed: [servera.lab.example.com]

RUNNING HANDLER [restart db service] *****************************************


changed: [servera.lab.example.com]

RUNNING HANDLER [set db password] ********************************************


changed: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=5 unreachable=0 failed=0

178 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

5. Ejecute la guía nuevamente.

[student@workstation control-handlers]$ ansible-playbook configure_db.yml

PLAY [Installing MariaDB server] *********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [['mariadb-server', 'python3-PyMySQL'] packages are installed] **********


ok: [servera.lab.example.com]

TASK [Make sure the database service is running] *****************************


ok: [servera.lab.example.com]

TASK [The /etc/my.cnf file has been installed] *******************************


ok: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=4 changed=0 unreachable=0 failed=0

En esta oportunidad, se omiten los manejadores. En el caso de que el archivo de


configuración remota se cambie en el futuro, ejecutar la guía desencadenará el manejador
restart db service, pero no el manejador set db password.

Finalizar
En workstation, ejecute el script lab control-handlers finish para limpiar los recursos
creados en este ejercicio.

[student@workstation ~]$ lab control-handlers finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 179
capítulo 5 | Implementación del control de tareas

Manejo de fallas de tareas

Objetivos
Después de completar esta sección, debe ser capaz de controlar lo que sucede cuando falla una
tarea y qué condiciones hacen que esta falle.

Gestión de errores de tareas en reproducciones


Ansible evalúa los códigos de retorno de cada tarea para determinar si una tarea se realizó
satisfactoriamente o con errores. Generalmente, cuando una tarea falla, Ansible cancela
inmediatamente el resto de la reproducción en ese host y omite todas las tareas posteriores.

No obstante, algunas veces puede desear continuar la ejecución de la reproducción, aunque una
tarea falle. Por ejemplo, puede esperar que una tarea específica falle y tal vez desee recuperarla
ejecutando otra tarea de forma condicional. Existen varias funciones de Ansible que se pueden
usar para administrar los errores de tareas.

Fallas de tareas ignoradas


De forma predeterminada, si una tarea falla, se cancela la reproducción. Sin embargo, el
comportamiento puede anularse si se ignoran las tareas fallidas. Puede usar la palabra clave
ignore_errors en una tarea para lograr esto.

En el siguiente fragmento, se muestra cómo usar ignore_errors en una tarea para continuar
la ejecución de una guía en el host, aun si la tarea falla. Por ejemplo, si el paquete notapkg no
existe, el módulo yum falla, pero si se tiene ignore_errors establecido como yes, la ejecución
continuará.

- name: Latest version of notapkg is installed


yum:
name: notapkg
state: latest
ignore_errors: yes

Forzado de la ejecución de manejadores después de la falla de


una tarea
En general, cuando falla una tarea y se cancela la reproducción en ese host, no se ejecutarán los
manejadores informados por las tareas anteriores en la reproducción. Si establece la palabra clave
force_handlers: yes en la reproducción, se llama a los manejadores notificados incluso si se
canceló la reproducción porque falló una tarea posterior.

El siguiente fragmento muestra cómo usar la palabra clave force_handlers en una


reproducción para forzar la ejecución del manejador, incluso si falla una tarea:

---
- hosts: all
force_handlers: yes
tasks:

180 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

- name: a task which always notifies its handler


command: /bin/true
notify: restart the database

- name: a task which fails because the package doesn't exist


yum:
name: notapkg
state: latest

handlers:
- name: restart the database
service:
name: mariadb
state: restarted

nota
Recuerde que se notifica a los manejadores cuando una tarea informa un resultado
changed (modificado), pero no se notifican cuando informa un resultado ok
(correcto) o failed (con errores).

Especificación de las condiciones de falla de tareas


Puede usar la palabra clave failed_when en una tarea para especificar las condiciones que
indican que la tarea falló. A menudo, esto se usa con los módulos de comando que pueden
ejecutar un comando correctamente, pero la salida del comando indica una falla.

Por ejemplo, puede ejecutar un script que presenta un mensaje de error y usar ese mensaje
para definir el estado fallido para la tarea. El siguiente fragmento muestra cómo la palabra clave
failed_when se puede utilizar en una tarea:

tasks:
- name: Run user creation script
shell: /usr/local/bin/create_users.sh
register: command_result
failed_when: "'Password missing' in command_result.stdout"

El módulo fail también se puede utilizar para forzar una falla de tarea. El escenario anterior se
puede escribir alternativamente como dos tareas:

tasks:
- name: Run user creation script
shell: /usr/local/bin/create_users.sh
register: command_result
ignore_errors: yes

- name: Report script failure


fail:
msg: "The password is missing in the output"
when: "'Password missing' in command_result.stdout"

RH294-RHEL8.0-es-1-20200501 181
capítulo 5 | Implementación del control de tareas

Puedes usar el módulo fail para proporcionar un mensaje de error claro para la tarea. Este
enfoque también permite la falla retrasada, lo que le permite ejecutar tareas intermedias para
completar o revertir otros cambios.

Especificación cuando una tarea informa resultados


“Changed”
Cuando una tarea realiza un cambio a un host administrado, informa el estado changed y notifica
a los manejadores. Cuando una tarea no necesita realizar un cambio, informa ok y no notifica a los
manejadores.

La palabra clave changed_when puede usarse para controlar cuando una tarea informa que se
ha modificado. Por ejemplo, el módulo shell en el siguiente ejemplo se usa para obtener una
credencial de Kerberos que usarán las tareas posteriores. En general, informaría siempre changed
(modificado) cuando se ejecuta. Para eliminar esa modificación, changed_when: false se
establece de modo que solo informa ok (correcto) o failed (con errores).

- name: get Kerberos credentials as "admin"


shell: echo "{{ krb_admin_pass }}" | kinit -f admin
changed_when: false

El siguiente ejemplo usa el módulo shell que informa changed (modificado) según la salida del
módulo recopilada por una variable registrada:

tasks:
- shell:
cmd: /usr/local/bin/upgrade-database
register: command_result
changed_when: "'Success' in command_result.stdout"
notify:
- restart_database

handlers:
- name: restart_database
service:
name: mariadb
state: restarted

Bloques Ansible y manejo de errores


En las guías, los blocks (bloques) son cláusulas que agrupan tareas de forma lógica, y se pueden
usar para controlar cómo se ejecutan las tareas. Por ejemplo, un bloque de tareas puede tener una
palabra clave when para aplicar una condición a varias tareas:

- name: block example


hosts: all
tasks:
- name: installing and configuring Yum versionlock plugin
block:
- name: package needed by yum
yum:
name: yum-plugin-versionlock
state: present

182 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

- name: lock version of tzdata


lineinfile:
dest: /etc/yum/pluginconf.d/versionlock.list
line: tzdata-2016j-1
state: present
when: ansible_distribution == "RedHat"

Los bloques también permiten el manejo de errores junto con los enunciados rescue y always.
Si una tarea en un bloque falla, las tareas en su bloque rescue se ejecutan para recuperarla.
Después de que se ejecuten las tareas en la cláusula block, así como las tareas en la cláusula
rescue si hubo una falla, se ejecutan las tareas en la cláusula always. Para resumir:

• block: define las tareas principales para ejecutar.

• rescue: define las tareas que se ejecutarán si fallan las tareas definidas en la cláusula block.

• always: define las tareas que se ejecutarán siempre, independientemente del éxito o de la falla
de las tareas definidas en las cláusulas block y rescue.

En el siguiente ejemplo, se muestra cómo implementar un bloque en una guía. Inclusive si las
tareas definidas en la cláusula block fallan, se ejecutan las tareas definidas en las cláusulas
rescue y always.

tasks:
- name: Upgrade DB
block:
- name: upgrade the database
shell:
cmd: /usr/local/lib/upgrade-database
rescue:
- name: revert the database upgrade
shell:
cmd: /usr/local/lib/revert-database
always:
- name: always restart the database
service:
name: mariadb
state: restarted

La condición when en una cláusula block también se aplica a sus cláusulas rescue y always si
están presentes.

Referencias
Manejo de errores en guías — Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html

Manejo de errores — Bloques — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html#error-
handling

RH294-RHEL8.0-es-1-20200501 183
capítulo 5 | Implementación del control de tareas

Ejercicio Guiado

Manejo de fallas de tareas


En este ejercicio, explorará diferentes formas de manejar la falla de una tarea en un Ansible
Playbook.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Ignorar los comandos fallidos durante la ejecución de guías.

• Forzar la ejecución de los manejadores.

• Reemplazar lo que constituye una falla en las tareas.

• Reemplazar el estado changed para las tareas.

• Implementar block, rescue y always en las guías.

Andes De Comenzar
En workstation, ejecute el script de inicio del trabajo de laboratorio a fin de confirmar
que el entorno esté listo para que comience el trabajo de laboratorio. Este script crea el
directorio de trabajo, /home/student/control-errors.

[student@workstation ~]$ lab control-errors start

1. En workstation.lab.example.com, vaya al directorio del proyecto /home/student/


control-errors.

[student@workstation ~]$ cd ~/control-errors


[student@workstation control-errors]$

2. El script del trabajo de laboratorio creó un archivo de configuración Ansible, así como un
archivo de inventario que contiene el servidor servera.lab.example.com en el grupo
databases. Revise el archivo antes de continuar.

3. Cree la guía playbook.yml, que contiene una reproducción con dos tareas. Escriba la
primera tarea con un error deliberado para que falle.

3.1. Abra la guía en un editor de texto. Defina tres variables: web_package con un valor
de http, db_package con un valor de mariadb-server y db_service con un
valor de mariadb. Estas variables se usarán para instalar los paquetes requeridos e
iniciar el servidor.
El valor http es un error intencional en el nombre del paquete. Se debería leer lo
siguiente en el archivo:

184 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

---
- name: Task Failure Exercise
hosts: databases
vars:
web_package: http
db_package: mariadb-server
db_service: mariadb

3.2. Defina dos tareas que usen el módulo yum y las dos variables, web_package y
db_package. Las tareas instalarán los paquetes requeridos. En las tareas, se debe
leer lo siguiente:

tasks:
- name: Install {{ web_package }} package
yum:
name: "{{ web_package }}"
state: present

- name: Install {{ db_package }} package


yum:
name: "{{ db_package }}"
state: present

4. Ejecute la guía y observe la salida de la reproducción.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Install http package] ****************************************************


fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "failures":
["No package http available."], "msg": "Failed to install some of the specified
packages", "rc": 1, "results": []}

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=1 changed=0 unreachable=0 failed=1

La tarea falló porque no hay un paquete existente denominado http. Debido a que falló la
primera tarea, no se ejecutó la segunda tarea.

5. Actualice la primera tarea para ignorar cualquier error añadiendo la palabra clave
ignore_errors. En las tareas, se debe leer lo siguiente:

tasks:
- name: Install {{ web_package }} package
yum:
name: "{{ web_package }}"
state: present
ignore_errors: yes

RH294-RHEL8.0-es-1-20200501 185
capítulo 5 | Implementación del control de tareas

- name: Install {{ db_package }} package


yum:
name: "{{ db_package }}"
state: present

6. Ejecute la guía nuevamente y observe la salida de la reproducción.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Install http package] ****************************************************


fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "failures":
["No package http available."], "msg": "Failed to install some of the specified
packages", "rc": 1, "results": []}
...ignoring

TASK [Install mariadb-server package] ******************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=1 unreachable=0 failed=0

A pesar del hecho de que falló la primera tarea, Ansible ejecutó la segunda.

7. En este paso, configurará una palabra clave block para que pueda experimentar con su
funcionamiento.

7.1. Actualice la guía anidando la primera tarea en una cláusula block. Elimine la línea que
establece ignore_errors: yes. El bloque debe decir lo siguiente:

- name: Attempt to set up a webserver


block:
- name: Install {{ web_package }} package
yum:
name: "{{ web_package }}"
state: present

7.2. Anide la tarea que instala el paquete mariadb-server en una cláusula rescue. La
tarea se ejecutará si falla la tarea que se detalla en la cláusula block. La cláusula
block debe decir lo siguiente:

rescue:
- name: Install {{ db_package }} package
yum:
name: "{{ db_package }}"
state: present

186 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

7.3. Por último, agregue una cláusula always que iniciará el servidor de base de datos
una vez realizada la instalación usando el módulo service. La cláusula debe decir lo
siguiente:

always:
- name: Start {{ db_service }} service
service:
name: "{{ db_service }}"
state: started

7.4. La sección de la tarea completa debe decir lo siguiente:

tasks:
- name: Attempt to set up a webserver
block:
- name: Install {{ web_package }} package
yum:
name: "{{ web_package }}"
state: present
rescue:
- name: Install {{ db_package }} package
yum:
name: "{{ db_package }}"
state: present
always:
- name: Start {{ db_service }} service
service:
name: "{{ db_service }}"
state: started

8. Ahora ejecute la guía otra vez y observe la salida.

8.1. Ejecute la guía. Fallará la tarea en el bloque que garantiza que esté instalado
web_package, lo que causará la ejecución de la tarea del bloque rescue. A
continuación, se ejecuta la tarea en el bloque always.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Install http package] ****************************************************


fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "failures":
["No package http available."], "msg": "Failed to install some of the specified
packages", "rc": 1, "results": []}

TASK [Install mariadb-server package] ******************************************


ok: [servera.lab.example.com]

TASK [Start mariadb service] ***************************************************


changed: [servera.lab.example.com]

RH294-RHEL8.0-es-1-20200501 187
capítulo 5 | Implementación del control de tareas

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=1 unreachable=0 failed=1

8.2. Edite la guía y corrija el valor de la variable web_package para que diga httpd.
Esto hará que la tarea en el bloque se ejecute de manera correcta la próxima vez que
ejecute la guía.

vars:
web_package: httpd
db_package: mariadb-server
db_service: mariadb

8.3. Ejecute la guía nuevamente. Esta vez, la tarea en el bloque no fallará. Esto hace que
se ignore la tarea en la sección rescue. Se ejecutará la tarea en always.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Install httpd package] ***************************************************


changed: [servera.lab.example.com]

TASK [Start mariadb service] ***************************************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=3 changed=1 unreachable=0 failed=0

9. Este paso explora el modo en que se controla la condición que hace que la tarea se informe
como “changed” (modificado) al host administrado.

9.1. Edite la guía para agregar dos tareas al inicio de la reproducción, antes del block. La
primera tarea usa el módulo command para ejecutar el comando date y registra el
resultado en la variable command_result. La segunda tarea usa el módulo debug
para imprimir la salida estándar del comando de la primera tarea.

tasks:
- name: Check local time
command: date
register: command_result

- name: Print local time


debug:
var: command_result.stdout

9.2. Ejecute la guía. Debería ver que la primera tarea, que ejecuta el módulo command,
informe changed (modificado), aun si no modificó el sistema remoto; solo recopiló
información acerca de la hora. Esto se debe a que el módulo command no puede

188 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

diferenciar entre un comando que recopila datos y un comando que modifica el


estado.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Check local time] ********************************************************


changed: [servera.lab.example.com]

TASK [Print local time] ********************************************************


ok: [servera.lab.example.com] => {
"command_result.stdout": "mié mar 27 08:07:08 EDT 2019"
}

TASK [Install httpd package] ***************************************************


ok: [servera.lab.example.com]

TASK [Start mariadb service] ***************************************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=5 changed=1 unreachable=0 failed=0

Si ejecuta la guía nuevamente, la tarea Check local time (Verificar hora local)
informará changed (modificado) nuevamente.

9.3. Esa tarea command no debería informar changed (modificado) cada vez que se
ejecuta, ya que no modifica el host administrado. Dado que sabe que la tarea nunca
modificará un host administrado, agregue la línea changed_when: false a la tarea
para eliminar la modificación.

tasks:
- name: Check local time
command: date
register: command_result
changed_when: false

- name: Print local time


debug:
var: command_result.stdout

9.4. Ejecute la guía nuevamente para observar que la tarea ahora informe ok (correcto),
pero la tarea aún se está ejecutando y está guardando la hora en la variable.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

RH294-RHEL8.0-es-1-20200501 189
capítulo 5 | Implementación del control de tareas

TASK [Check local time] ********************************************************


ok: [servera.lab.example.com]

TASK [Print local time] ********************************************************


ok: [servera.lab.example.com] => {
"command_result.stdout": "mié mar 27 08:08:36 EDT 2019"
}

TASK [Install httpd package] ***************************************************


ok: [servera.lab.example.com]

TASK [Start mariadb service] ***************************************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=5 changed=0 unreachable=0 failed=0

10. Como ejercicio final, edite la guía para explorar el modo en que la palabra clave
failed_when interactúa con las tareas.

10.1. Edite la tarea Install {{ web_package }} package (Instalar el paquete


{{ web_package }}) de modo que informe que falló cuando web_package tenga el
valor httpd. Dado que este es el caso, la tarea informará una falla cuando ejecute la
reproducción.
Preste atención a su sangría para asegurarse de que la palabra clave se establezca
correctamente en la tarea.

- block:
- name: Install {{ web_package }} package
yum:
name: "{{ web_package }}"
state: present
failed_when: web_package == "httpd"

10.2. Ejecute la guía.

[student@workstation control-errors]$ ansible-playbook playbook.yml

PLAY [Task Failure Exercise] ***************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [Check local time] ********************************************************


ok: [servera.lab.example.com]

TASK [Print local time] ********************************************************


ok: [servera.lab.example.com] => {
"command_result.stdout": "mié mar 27 08:09:35 EDT 2019"
}

TASK [Install httpd package] ***************************************************

190 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

fatal: [servera.lab.example.com]: FAILED! => {"changed": false,


"failed_when_result": true, "msg": "Nothing to do", "rc": 0, "results":
["Installed: httpd"]}

TASK [Install mariadb-server package] ******************************************


ok: [servera.lab.example.com]

TASK [Start mariadb service] ***************************************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=5 changed=0 unreachable=0 failed=1

Observe la salida con atención. La tarea Install httpd package (Instalar


paquete httpd) informa que falló, pero en realidad se ejecutó y se aseguró de que el
paquete se instalara primero. La palabra clave failed_when modifica el estado que
informa la tarea después de su ejecución; no modifica el comportamiento de la tarea
en sí.
Sin embargo, la falla informada puede modificar el comportamiento del resto de la
reproducción. Dado que esta tarea se encontraba en un bloque e informó una falla, se
ejecutó la tarea Install mariadb-server package (Instalar paquete mariadb-
server) en la sección rescue del bloque.

Finalizar
En workstation, ejecute el script lab control-errors finish para limpiar los recursos
creados en este ejercicio.

[student@workstation ~]$ lab control-errors finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 191
capítulo 5 | Implementación del control de tareas

Trabajo de laboratorio

Implementación del control de tareas


Lista de verificación de rendimiento
En este trabajo de laboratorio, instalará el servidor web Apache y lo asegurará usando
mod_ssl. Utilizará las condiciones, los manejadores y el manejo de fallas de tareas en su
guía para implementar el entorno.

Resultados
Debe ser capaz de definir condicionales en Ansible Playbooks, configurar bucles que iteran
en elementos, definir manejadores en guías y manejar errores de tareas.

Andes De Comenzar
Inicie sesión como el usuario student en workstation y ejecute lab control-review
start. Este script garantiza que se pueda acceder al host administrado, serverb, en la red.
También garantiza que el archivo de configuración y el inventario Ansible correctos estén
instalados en el nodo de control.

[student@workstation ~]$ lab control-review start

1. En workstation, cambie al directorio de proyectos /home/student/control-review.


2. El directorio de proyectos contiene una guía parcialmente completada, playbook.yml.
Usando un editor de texto, agregue una tarea que use el módulo fail bajo el comentario
#Fail Fast Message. Asegúrese de proporcionar un nombre adecuado para la tarea. Esta
tarea solo debe ejecutarse cuando el sistema remoto no cumple con los requisitos mínimos.
Los requisitos mínimos para el host remoto se enumeran a continuación:

• Tiene al menos la cantidad de RAM especificada por la variable min_ram_mb. La variable


min_ram_mb se define en el archivo vars.yml y tiene un valor de 256.

• Ejecuta Red Hat Enterprise Linux.


3. Agregue una sola tarea a la guía bajo el comentario #Install all Packages para instalar
la última versión de cualquier paquete faltante. Los paquetes requeridos son especificados
por la variable packages, que se define en el archivo vars.yml.
El nombre de la tarea debe ser Ensure required packages are present.
4. Agregue una sola tarea a la guía bajo el comentario #Enable and start services para
iniciar todos los servicios. Deben iniciarse y habilitarse todos los servicios especificados por
la variable services, que se define en el archivo vars.yml. Asegúrese de proporcionar un
nombre adecuado para la tarea.
5. Agregue un bloque de tareas a la guía bajo el comentario #Block of config tasks. Este
bloque contiene dos tareas:

• Una tarea para asegurar que el directorio especificado por la variable ssl_cert_dir
existe en el host remoto. Este directorio almacena los certificados del servidor web.

192 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

• Una tarea para copiar todos los archivos especificados por la variable
web_config_files al host remoto. Examine la estructura de la variable
web_config_files en el archivo vars.yml. Configure la tarea para copiar cada archivo
al destino correcto en el host remoto.

Esta tarea debe desencadenar el manejador restart web service si alguno de estos
archivos se modifica en el servidor remoto.

Además, se ejecuta una tarea de depuración si falla alguna de las dos tareas anteriores. En
este caso, la tarea imprime el mensaje: One or more of the configuration changes
failed, but the web service is still active..
Asegúrese de proporcionar un nombre adecuado para todas las tareas.
6. La guía configura el host remoto para escuchar las solicitudes de HTTPS estándares.
Agregue una sola tarea a la guía bajo el comentario #Configure the firewall para
configurar firewalld.
Esta tarea debe garantizar que el host remoto permita conexiones HTTP y HTTPS
estándares. Estos cambios de configuración deben ser efectivos de inmediato y persistir
después de reiniciar el sistema. Asegúrese de proporcionar un nombre adecuado para la
tarea.
7. Defina el manejador restart web service.
Cuando se desencadena, esta tarea debe reiniciar el servicio web determinado por la variable
web_service, definida en el archivo vars.yml.
8. Desde el directorio, ~/control-review, ejecute la guía playbook.yml. La guía debe
ejecutarse sin errores y desencadenar la ejecución de la tarea del manejador.
9. Verifique que el servidor web ahora responde a las solicitudes HTTPS, usando el certificado
autofirmado personalizado para cifrar la conexión. La respuesta del servidor web debe
coincidir con la cadena Configured for both HTTP and HTTPS.

Evaluación
En workstation, ejecute el comando lab control-review grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab control-review grade

Finalizar
Ejecute el comando lab control-review finish para la limpieza después del trabajo de
laboratorio.

[student@workstation ~]$ lab control-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 193
capítulo 5 | Implementación del control de tareas

Solución

Implementación del control de tareas


Lista de verificación de rendimiento
En este trabajo de laboratorio, instalará el servidor web Apache y lo asegurará usando
mod_ssl. Utilizará las condiciones, los manejadores y el manejo de fallas de tareas en su
guía para implementar el entorno.

Resultados
Debe ser capaz de definir condicionales en Ansible Playbooks, configurar bucles que iteran
en elementos, definir manejadores en guías y manejar errores de tareas.

Andes De Comenzar
Inicie sesión como el usuario student en workstation y ejecute lab control-review
start. Este script garantiza que se pueda acceder al host administrado, serverb, en la red.
También garantiza que el archivo de configuración y el inventario Ansible correctos estén
instalados en el nodo de control.

[student@workstation ~]$ lab control-review start

1. En workstation, cambie al directorio de proyectos /home/student/control-review.

[student@workstation ~]$ cd ~/control-review


[student@workstation control-review]$

2. El directorio de proyectos contiene una guía parcialmente completada, playbook.yml.


Usando un editor de texto, agregue una tarea que use el módulo fail bajo el comentario
#Fail Fast Message. Asegúrese de proporcionar un nombre adecuado para la tarea. Esta
tarea solo debe ejecutarse cuando el sistema remoto no cumple con los requisitos mínimos.
Los requisitos mínimos para el host remoto se enumeran a continuación:

• Tiene al menos la cantidad de RAM especificada por la variable min_ram_mb. La variable


min_ram_mb se define en el archivo vars.yml y tiene un valor de 256.

• Ejecuta Red Hat Enterprise Linux.

La tarea completada coincide:

tasks:
#Fail Fast Message
- name: Show Failed System Requirements Message
fail:
msg: "The {{ inventory_hostname }} did not meet minimum reqs."
when: >
ansible_memtotal_mb < min_ram_mb or
ansible_distribution != "RedHat"

194 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

3. Agregue una sola tarea a la guía bajo el comentario #Install all Packages para instalar
la última versión de cualquier paquete faltante. Los paquetes requeridos son especificados
por la variable packages, que se define en el archivo vars.yml.
El nombre de la tarea debe ser Ensure required packages are present.
La tarea completada coincide:

#Install all Packages


- name: Ensure required packages are present
yum:
name: "{{ packages }}"
state: latest

4. Agregue una sola tarea a la guía bajo el comentario #Enable and start services para
iniciar todos los servicios. Deben iniciarse y habilitarse todos los servicios especificados por
la variable services, que se define en el archivo vars.yml. Asegúrese de proporcionar un
nombre adecuado para la tarea.
La tarea completada coincide:

#Enable and start services


- name: Ensure services are started and enabled
service:
name: "{{ item }}"
state: started
enabled: yes
loop: "{{ services }}"

5. Agregue un bloque de tareas a la guía bajo el comentario #Block of config tasks. Este
bloque contiene dos tareas:

• Una tarea para asegurar que el directorio especificado por la variable ssl_cert_dir
existe en el host remoto. Este directorio almacena los certificados del servidor web.

• Una tarea para copiar todos los archivos especificados por la variable
web_config_files al host remoto. Examine la estructura de la variable
web_config_files en el archivo vars.yml. Configure la tarea para copiar cada archivo
al destino correcto en el host remoto.

Esta tarea debe desencadenar el manejador restart web service si alguno de estos
archivos se modifica en el servidor remoto.

Además, se ejecuta una tarea de depuración si falla alguna de las dos tareas anteriores. En
este caso, la tarea imprime el mensaje: One or more of the configuration changes
failed, but the web service is still active..
Asegúrese de proporcionar un nombre adecuado para todas las tareas.
El bloque de tareas completadas coincide con lo siguiente:

#Block of config tasks


- name: Setting up the SSL cert directory and config files
block:
- name: Create SSL cert directory
file:
path: "{{ ssl_cert_dir }}"

RH294-RHEL8.0-es-1-20200501 195
capítulo 5 | Implementación del control de tareas

state: directory

- name: Copy Config Files


copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
loop: "{{ web_config_files }}"
notify: restart web service

rescue:
- name: Configuration Error Message
debug:
msg: >
One or more of the configuration
changes failed, but the web service
is still active.

6. La guía configura el host remoto para escuchar las solicitudes de HTTPS estándares.
Agregue una sola tarea a la guía bajo el comentario #Configure the firewall para
configurar firewalld.
Esta tarea debe garantizar que el host remoto permita conexiones HTTP y HTTPS
estándares. Estos cambios de configuración deben ser efectivos de inmediato y persistir
después de reiniciar el sistema. Asegúrese de proporcionar un nombre adecuado para la
tarea.
La tarea completada coincide:

#Configure the firewall


- name: ensure web server ports are open
firewalld:
service: "{{ item }}"
immediate: true
permanent: true
state: enabled
loop:
- http
- https

196 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

7. Defina el manejador restart web service.


Cuando se desencadena, esta tarea debe reiniciar el servicio web determinado por la variable
web_service, definida en el archivo vars.yml.
La sección handlers se agregará al final de la guía:

handlers:
- name: restart web service
service:
name: "{{ web_service }}"
state: restarted

La guía completa contiene lo siguiente:

---
- name: Playbook Control Lab
hosts: webservers
vars_files: vars.yml
tasks:
#Fail Fast Message
- name: Show Failed System Requirements Message
fail:
msg: "The {{ inventory_hostname }} did not meet minimum reqs."
when: >
ansible_memtotal_mb < min_ram_mb or
ansible_distribution != "RedHat"

#Install all Packages


- name: Ensure required packages are present
yum:
name: "{{ packages }}"
state: latest

#Enable and start services


- name: Ensure services are started and enabled
service:
name: "{{ item }}"
state: started
enabled: yes
loop: "{{ services }}"

#Block of config tasks


- name: Setting up the SSL cert directory and config files
block:
- name: Create SSL cert directory
file:
path: "{{ ssl_cert_dir }}"
state: directory

- name: Copy Config Files


copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
loop: "{{ web_config_files }}"
notify: restart web service

RH294-RHEL8.0-es-1-20200501 197
capítulo 5 | Implementación del control de tareas

rescue:
- name: Configuration Error Message
debug:
msg: >
One or more of the configuration
changes failed, but the web service
is still active.

#Configure the firewall


- name: ensure web server ports are open
firewalld:
service: "{{ item }}"
immediate: true
permanent: true
state: enabled
loop:
- http
- https

#Add handlers
handlers:
- name: restart web service
service:
name: "{{ web_service }}"
state: restarted

8. Desde el directorio, ~/control-review, ejecute la guía playbook.yml. La guía debe


ejecutarse sin errores y desencadenar la ejecución de la tarea del manejador.

[student@workstation control-review]$ ansible-playbook playbook.yml

PLAY [Playbook Control Lab] **************************************************

TASK [Gathering Facts] *******************************************************


ok: [serverb.lab.example.com]

TASK [Show Failed System Requirements Message] *******************************


skipping: [serverb.lab.example.com]

TASK [Ensure required packages are present] **********************************


changed: [serverb.lab.example.com]

TASK [Ensure services are started and enabled] *******************************


changed: [serverb.lab.example.com] => (item=httpd)
ok: [serverb.lab.example.com] => (item=firewalld)

TASK [Create SSL cert directory] *********************************************


changed: [serverb.lab.example.com]

TASK [Copy Config Files] *****************************************************


changed: [serverb.lab.example.com] => (item={'src': 'server.key', 'dest': '/etc/
httpd/conf.d/ssl'})

198 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

changed: [serverb.lab.example.com] => (item={'src': 'server.crt', 'dest': '/etc/


httpd/conf.d/ssl'})
changed: [serverb.lab.example.com] => (item={'src': 'ssl.conf', 'dest': '/etc/
httpd/conf.d'})
changed: [serverb.lab.example.com] => (item={'src': 'index.html', 'dest': '/var/
www/html'})

TASK [ensure web server ports are open] **************************************


changed: [serverb.lab.example.com] => (item=http)
changed: [serverb.lab.example.com] => (item=https)

RUNNING HANDLER [restart web service] ****************************************


changed: [serverb.lab.example.com]

PLAY RECAP *******************************************************************


serverb.lab.example.com : ok=7 changed=6 unreachable=0 failed=0

9. Verifique que el servidor web ahora responde a las solicitudes HTTPS, usando el certificado
autofirmado personalizado para cifrar la conexión. La respuesta del servidor web debe
coincidir con la cadena Configured for both HTTP and HTTPS.

[student@workstation control-review]$ curl -k -vvv https://serverb.lab.example.com


* About to connect() to serverb.lab.example.com port 443 (#0)
* Trying 172.25.250.11...
* Connected to serverb.lab.example.com (172.25.250.11) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
...output omitted...
* start date: Nov 13 15:52:18 2018 GMT
* expire date: Aug 09 15:52:18 2021 GMT
* common name: serverb.lab.example.com
...output omitted...
< Accept-Ranges: bytes
< Content-Length: 36
< Content-Type: text/html; charset=UTF-8
<
Configured for both HTTP and HTTPS.
* Connection #0 to host serverb.lab.example.com left intact

Evaluación
En workstation, ejecute el comando lab control-review grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab control-review grade

Finalizar
Ejecute el comando lab control-review finish para la limpieza después del trabajo de
laboratorio.

RH294-RHEL8.0-es-1-20200501 199
capítulo 5 | Implementación del control de tareas

[student@workstation ~]$ lab control-review finish

Esto concluye el trabajo de laboratorio.

200 RH294-RHEL8.0-es-1-20200501
capítulo 5 | Implementación del control de tareas

Resumen
En este capítulo, aprendió lo siguiente:

• Los bucles se usan para iterar un conjunto de valores, por ejemplo, una simple lista de cadenas o
una lista de hashes o diccionarios.

• Los condicionales se pueden usar para ejecutar tareas o reproducciones únicamente cuando se
hayan cumplido ciertas condiciones.

• Los manejadores son tareas especiales que se ejecutan al final de una reproducción si otras
tareas los notifican.

• Los manejadores solo son notificados cuando una tarea informa que se cambió algo en un host
administrado.

• Las tareas se configuran para manejar condiciones de error ignorando una falla en las tareas,
forzando a los manejadores a ser invocados aun cuando la tarea haya fallado, marcar una tarea
como con errores cuando fue satisfactoria o reemplazar el comportamiento que hace que la
tarea se marque como modificada.

• Los bloques se usan para agrupar tareas como una unidad y ejecutar otras tareas dependiendo
de si todas las tareas en el bloque se realizaron satisfactoriamente.

RH294-RHEL8.0-es-1-20200501 201
202 RH294-RHEL8.0-es-1-20200501
capítulo 6

Implementación de archivos en
hosts administrados
Meta Implementar, administrar y ajustar archivos en
hosts administrados por Ansible.

Objetivos • Crear, instalar, editar y eliminar archivos en


hosts administrados, y gestionar permisos,
propiedad, contexto de SELinux y otras
características de esos archivos.
• Personalizar archivos mediante el uso de
plantillas Jinja2 e implementarlas en hosts
administrados.

Secciones • Modificación y copia de archivos a hosts (y


ejercicio guiado)
• Implementación de archivos personalizados con
plantillas Jinja2 (y ejercicio guiado)

Trabajo de • Implementación de archivos en hosts


administrados
laboratorio

RH294-RHEL8.0-es-1-20200501 203
capítulo 6 | Implementación de archivos en hosts administrados

Modificación y copia de archivos a hosts

Objetivos
Tras completar esta sección, deberá ser capaz de crear, instalar, editar y eliminar archivos en hosts
administrados, y administrar permisos, propiedad, contexto de SELinux y otras características de
esos archivos.

Descripción de los módulos de archivos


Red Hat Ansible Engine se envía con una gran colección de módulos (la “librería de módulos”)
que se desarrollan como parte del innovador proyecto de Ansible. Para facilitar su organización,
documentación y administración, se organizan en grupos según la función que tienen en la
documentación y el momento en que se instalan en un sistema.

La librería de módulos Files incluye módulos que permiten realizar la mayoría de las tareas
relacionadas con la administración de archivos de Linux, como crear, copiar, editar y modificar
permisos y otros atributos de archivos. En la siguiente tabla, se proporciona una lista de los
módulos de administración de archivos de uso frecuente:

Módulos de archivos de uso común

Nombre del módulo Descripción del módulo

blockinfile Inserte, actualice o elimine un bloque de texto multilínea rodeado


por líneas de marcador personalizables.

copy Copie un archivo de la máquina local o remota a una ubicación en un


host administrado. Similar al módulo file, el módulo copy también
puede establecer atributos de archivo, incluido el contexto SELinux.

fetch Este módulo funciona como el módulo copy, pero a la inversa. Este
módulo se utiliza para recuperar archivos de máquinas remotas
al nodo de control y para almacenarlos en un árbol de archivos,
organizado por nombre de host.

file Establezca atributos tales como permisos, propiedad, contextos


SELinux y marcas de tiempo de archivos regulares, enlaces
simbólicos, enlaces físicos y directorios. Este módulo también puede
crear o eliminar archivos regulares, enlaces simbólicos, enlaces
físicos y directorios. Una serie de otros módulos relacionados con
archivos admiten las mismas opciones para establecer atributos
como el módulo file, incluido el módulo copy.

lineinfile Asegúrese de que una línea particular esté en un archivo o


reemplace una línea existente usando una expresión regular de
referencia inversa. Este módulo es principalmente útil cuando desea
cambiar una sola línea en un archivo.

204 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

Nombre del módulo Descripción del módulo

stat Recupere información de estado de un archivo, similar al comando


stat de Linux.

synchronize Un contenedor alrededor del comando rsync para hacer que las
tareas comunes sean rápidas y fáciles. El módulo synchronize
no está destinado a proporcionar acceso a toda la potencia del
comando rsync, pero hace que las invocaciones más comunes sean
más fáciles de implementar. Es posible que aún necesite generar el
comando rsync directamente a través del módulo run command
según su caso de uso.

Ejemplos de automatización con módulos de archivos


Crear, copiar, editar y eliminar archivos en hosts administrados son tareas comunes que puede
implementar usando módulos de la biblioteca de módulos Files. Los siguientes ejemplos
muestran formas en que puede usar estos módulos para automatizar las tareas comunes de
administración de archivos.

Garantía de que exista un archivo en los hosts administrados


Use el módulo file para tocar un archivo en los hosts administrados. Esto funciona como el
comando touch, creando un archivo vacío si no existe y actualizando su hora de modificación
si existe. En este ejemplo, además de tocar el archivo, Ansible se asegura de que el usuario
propietario, el grupo y los permisos del archivo estén configurados con valores específicos.

- name: Touch a file and set permissions


file:
path: /path/to/file
owner: user1
group: group1
mode: 0640
state: touch

Resultado de ejemplo:

$ ls -l file
-rw-r----- user1 group1 0 Nov 25 08:00 file

Modificación de los atributos del archivo


Puede usar el módulo file para garantizar que un archivo nuevo o existente tenga los permisos
correctos o el tipo SELinux también.

Por ejemplo, el siguiente archivo ha conservado el contexto predeterminado de SELinux en


relación con el directorio de inicio de un usuario, que no es el contexto deseado.

$ ls -Z samba_file
-rw-r--r-- owner group unconfined_u:object_r:user_home_t:s0 samba_file

La siguiente tarea garantiza que el atributo de tipo de contexto SELinux del archivo samba_file
es el tipo samba_share_t deseado. Este comportamiento es similar al comando chcon de Linux.

RH294-RHEL8.0-es-1-20200501 205
capítulo 6 | Implementación de archivos en hosts administrados

- name: SELinux type is set to samba_share_t


file:
path: /path/to/samba_file
setype: samba_share_t

Resultado de ejemplo:

$ ls -Z samba_file
-rw-r--r-- owner group unconfined_u:object_r:samba_share_t:s0 samba_file

nota
Los parámetros de atributos de archivo están disponibles en varios módulos
de administración de archivos. Ejecute los comandos ansible-doc file y
ansible-doc copy para obtener más información.

Realización de los cambios de contexto del archivo SELinux


como persistentes
El módulo file actúa como chcon al configurar contextos de archivo. Los cambios realizados con
ese módulo podrían anularse de manera inesperada al ejecutar restorecon . Después de usar
file para establecer el contexto, puede usar sefcontext de la colección de módulos System
para actualizar la política de SELinux como semanage fcontext.

- name: SELinux type is persistently set to samba_share_t


sefcontext:
target: /path/to/samba_file
setype: samba_share_t
state: present

Resultado de ejemplo:

$ ls -Z samba_file
-rw-r--r-- owner group unconfined_u:object_r:samba_share_t:s0 samba_file

Importante
El módulo sefcontext actualiza el contexto predeterminado para el destino en la
política de SELinux, pero no cambia el contexto en los archivos existentes.

Copia y edición de archivos en hosts administrados


En este ejemplo, el módulo copy se usa para copiar un archivo ubicado en el directorio de trabajo
de Ansible en el nodo de control a los hosts administrados seleccionados.

De forma predeterminada, este módulo supone que force: yes está configurado. Eso obliga
al módulo a sobrescribir el archivo remoto si existe, pero tiene un contenido diferente del archivo
que se está copiando. Si se configura force: no, solo copia el archivo al host administrado si no
existe.

206 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

- name: Copy a file to managed hosts


copy:
src: file
dest: /path/to/file

Para recuperar archivos de hosts administrados, use el módulo fetch. Esto puede usarse para
recuperar un archivo como una clave pública SSH de un sistema de referencia antes de distribuirlo
a otros hosts administrados.

- name: Retrieve SSH key from reference host


fetch:
src: "/home/{{ user }}/.ssh/id_rsa.pub
dest: "files/keys/{{ user }}.pub"

Para asegurarse de que existe una línea de texto específica en un archivo existente, use el módulo
lineinfile:

- name: Add a line of text to a file


lineinfile:
path: /path/to/file
line: 'Add this line to the file'
state: present

Para agregar un bloque de texto a un archivo existente, use el módulo blockinfile:

- name: Add additional lines to a file


blockinfile:
path: /path/to/file
block: |
First line in the additional block of text
Second line in the additional block of text
state: present

nota
Al usar el módulo blockinfile, los marcadores de bloque comentados se insertan
al principio y al final del bloque para garantizar la idempotencia.

# BEGIN ANSIBLE MANAGED BLOCK


First line in the additional block of text
Second line in the additional block of text
# END ANSIBLE MANAGED BLOCK

Puede usar el parámetro marker en el módulo para garantizar que se esté


utilizando el texto o carácter de comentario correcto para el archivo en cuestión.

Eliminación de un archivo de los hosts administrados


Un ejemplo básico para eliminar un archivo de los hosts administrados es usar el módulo file con
el parámetro state: absent. El parámetro state es opcional para muchos módulos. Siempre
debe aclarar si desea state: present o state: absent por varias razones. Algunos módulos

RH294-RHEL8.0-es-1-20200501 207
capítulo 6 | Implementación de archivos en hosts administrados

admiten otras opciones también. Es posible que el valor predeterminado pueda cambiar en algún
momento, pero quizás lo más importante es que facilita la comprensión del estado en el que debe
estar el sistema según su tarea.

- name: Make sure a file does not exist on managed hosts


file:
dest: /path/to/file
state: absent

Recuperación del estado de un archivo en hosts administrados


El módulo stat recupera datos para un archivo, de manera similar al comando stat de Linux. Los
parámetros proporcionan la funcionalidad para recuperar atributos de archivo, determinar la suma
de comprobación de un archivo y más.

El módulo stat devuelve un diccionario de hash de los valores que contienen datos de estado
del archivo, lo que le permite referirse a partes individuales de información mediante variables
separadas.

En el siguiente ejemplo, se registran los resultados de un módulo stat y, luego, se imprime


la checksum MD5 del archivo que verificó. (El algoritmo SHA256 más moderno también está
disponible; aquí se usa MD5 para mejorar la legibilidad).

- name: Verify the checksum of a file


stat:
path: /path/to/file
checksum_algorithm: md5
register: result

- debug
msg: "The checksum of the file is {{ result.stat.checksum }}"

El resultado debe ser similar a lo siguiente:

TASK [Get md5 checksum of a file] *****************************************


ok: [hostname]

TASK [debug] **************************************************************


ok: [hostname] => {
"msg": "The checksum of the file is 5f76590425303022e933c43a7f2092a3"
}

La información sobre los valores devueltos por el módulo stat son registrados por ansible-
doc, o puede registrar una variable y visualizar su contenido para ver qué hay disponible:

- name: Examine all stat output of /etc/passwd


hosts: localhost

tasks:
- name: stat /etc/passwd
stat:
path: /etc/passwd
register: results

208 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

- name: Display stat results


debug:
var: results

Sincronización de archivos entre el nodo de control y los hosts


administrados
El módulo synchronize es un contenedor alrededor de la herramienta rsync, que simplifica las
tareas comunes de administración de archivos en sus guías. La herramienta rsync debe instalarse
en el host local y remoto. De forma predeterminada, cuando usa el módulo synchronize, el “host
local” es el host en el que se origina la tarea de sincronización (por lo general, el nodo de control),
y el “host de destino” es el host al que se conecta synchronize.

En el siguiente ejemplo, se sincroniza un archivo ubicado en el directorio de trabajo de Ansible con


los hosts administrados:

- name: synchronize local file to remote files


synchronize:
src: file
dest: /path/to/file

Hay muchas maneras de usar el módulo synchronize y sus diversos parámetros, incluida la
sincronización de directorios. Ejecute el comando ansible-doc synchronize para obtener
ejemplos de parámetros y de guía adicionales.

Referencias
Páginas del manual ansible-doc(1), chmod(1), chown(1), rsync(1), stat(1) and
touch(1)

Módulos de archivos
https://docs.ansible.com/ansible/latest/modules/list_of_files_modules.html

RH294-RHEL8.0-es-1-20200501 209
capítulo 6 | Implementación de archivos en hosts administrados

Ejercicio Guiado

Modificación y copia de archivos a hosts


En este ejercicio, usará los módulos estándares de Ansible para crear, instalar, editar y
eliminar archivos en hosts administrados y administrar permisos, propiedad y contextos de
SELinux de esos archivos.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Recuperar archivos de hosts administrados por nombre de host y almacenarlos


localmente.

• Crear guías que usen módulos comunes de administración de archivos como copy, file,
lineinfile y blockinfile.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab file-manage start. El script crea el


directorio del proyecto file-manage y descarga el archivo de configuración Ansible y el
archivo del inventario del host necesarios para el ejercicio.

[student@workstation ~]$ lab file-manage start

1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/file-manage. Cree una guía denominada secure_log_backups.yml
en el directorio de trabajo actual. Configure la guía para usar el módulo fetch con el
fin de recuperar el archivo de registro /var/log/secure de cada uno de los hosts
administrados y almacenarlos en el nodo de control. La guía debe crear el directorio
secure-backups con subdirectorios con el nombre del host de cada host administrado.
Almacene los archivos de copia de seguridad en sus respectivos subdirectorios.

1.1. Diríjase al directorio de trabajo /home/student/file-manage.

[student@workstation ~]$ cd ~/file-manage


[student@workstation file-manage]$

1.2. Cree la guía secure_log_backups.yml con el contenido inicial:

---
- name: Use the fetch module to retrieve secure log files
hosts: all
remote_user: root

1.3. Agregue una tarea a la guía secure_log_backups.yml que recupere el archivo de


registro /var/log/secure de los hosts administrados y lo almacene en el directorio

210 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

~/file-manage/secure-backups. El módulo fetch crea el directorio ~/file-


manage/secure-backups si aún no existe. Use el parámetro flat: no para
garantizar el comportamiento predeterminado de agregar el nombre de host, la ruta y
el nombre de archivo al destino:

tasks:
- name: Fetch the /var/log/secure log file from managed hosts
fetch:
src: /var/log/secure
dest: secure-backups
flat: no

1.4. Antes de ejecutar la guía, ejecute el comando ansible-playbook --syntax-


check secure_log_backups.yml para verificar su sintaxis. Corrija los errores
antes de pasar al siguiente paso.

[student@workstation file-manage]$ ansible-playbook --syntax-check \


> secure_log_backups.yml

playbook: secure_log_backups.yml

1.5. Ejecute ansible-playbook secure_log_backups.yml para ejecutar la guía:

[student@workstation file-manage]$ ansible-playbook secure_log_backups.yml


PLAY [Use the fetch module to retrieve secure log files] ******************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]

TASK [Fetch the /var/log/secure file from managed hosts] ******************


changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

1.6. Verifique los resultados de la guía:

[student@workstation file-manage]$ tree -F secure-backups


secure-backups
├── servera.lab.example.com/
│ └── var/
│ └── log/
│ └── secure
└── serverb.lab.example.com/
└── var/
└── log/
└── secure

RH294-RHEL8.0-es-1-20200501 211
capítulo 6 | Implementación de archivos en hosts administrados

2. Cree la guía copy_file.yml en el directorio de trabajo actual. Configure la guía para


copiar el archivo /home/student/file-manage/files/users.txt en todos los hosts
administrados como usuario root.

2.1. Agregue el siguiente contenido inicial a la guía copy_file.yml:

---
- name: Using the copy module
hosts: all
remote_user: root

2.2. Agregue una tarea para usar el módulo copy para copiar el archivo /home/
student/file-manage/files/users.txt en todos los hosts administrados. Use
el módulo copy para definir los siguientes parámetros para el archivo users.txt:

Parámetro Valores

src files/users.txt

dest /home/devops/users.txt

owner devops

group devops

mode u+rw,g-wx,o-rwx

setype samba_share_t

tasks:
- name: Copy a file to managed hosts and set attributes
copy:
src: files/users.txt
dest: /home/devops/users.txt
owner: devops
group: devops
mode: u+rw,g-wx,o-rwx
setype: samba_share_t

2.3. Use el comando ansible-playbook --syntax-check copy_file.yml para


verificar la sintaxis de la guía copy_file.yml.

[student@workstation file-manage]$ ansible-playbook --syntax-check copy_file.yml

playbook: copy_file.yml

2.4. Ejecute la guía:

[student@workstation file-manage]$ ansible-playbook copy_file.yml


PLAY [Using the copy module] *******************************************

TASK [Gathering Facts] *************************************************

212 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [Copy a file to managed hosts and set attributes] *****************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]

PLAY RECAP *************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

2.5. Use un comando ad hoc para ejecutar el comando ls -Z como el usuario devops
para verificar los atributos del archivo users.txt en los hosts administrados.

[student@workstation file-manage]$ ansible all -m command -a 'ls -Z' -u devops


servera.lab.example.com | CHANGED | rc=0 >>
unconfined_u:object_r:samba_share_t:s0 users.txt

serverb.lab.example.com | CHANGED | rc=0 >>


unconfined_u:object_r:samba_share_t:s0 users.txt

3. En un paso anterior, se estableció el campo de tipo SELinux samba_share_t para el


archivo users.txt. Sin embargo, ahora se determina que los valores predeterminados
deben establecerse para el contexto del archivo SELinux.
Cree una guía denominada selinux_defaults.yml en el directorio de trabajo actual.
Configure la guía para usar el módulo file para garantizar el contexto predeterminado de
SELinux para los campos user, role, type y level.

nota
En un caso real, también debería editar copy_file.yml y eliminar la palabra clave
setype.

3.1. Cree la guía selinux_defaults.yml:

---
- name: Using the file module to ensure SELinux file context
hosts: all
remote_user: root
tasks:
- name: SELinux file context is set to defaults
file:
path: /home/devops/users.txt
seuser: _default
serole: _default
setype: _default
selevel: _default

3.2. Use el comando ansible-playbook --syntax-check


selinux_defaults.yml para verificar la sintaxis de la guía
selinux_defaults.yml.

RH294-RHEL8.0-es-1-20200501 213
capítulo 6 | Implementación de archivos en hosts administrados

[student@workstation file-manage]$ ansible-playbook --syntax-check \


> selinux_defaults.yml

playbook: selinux_defaults.yml

3.3. Ejecute la guía:

[student@workstation file-manage]$ ansible-playbook selinux_defaults.yml


PLAY [Using the file module to ensure SELinux file context] ************

TASK [Gathering Facts] *************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [SELinux file context is set to defaults] *************************


changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]

PLAY RECAP *************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

3.4. Use un comando ad hoc para ejecutar el comando ls -Z como el usuario


devops para verificar los atributos de archivo predeterminados de
unconfined_u:object_r:user_home_t:s0.

[student@workstation file-manage]$ ansible all -m command -a 'ls -Z' -u devops


servera.lab.example.com | CHANGED | rc=0 >>
unconfined_u:object_r:user_home_t:s0 users.txt

serverb.lab.example.com | CHANGED | rc=0 >>


unconfined_u:object_r:user_home_t:s0 users.txt

4. Cree una guía denominada add_line.yml en el directorio de trabajo actual. Configure la


guía para usar el módulo lineinfile para añadir la línea This line was added by
the lineinfile module. (Esta línea fue agregada por el módulo lineinfile.) al archivo /
home/devops/users.txt en todos los hosts administrados.

4.1. Cree la guía add_line.yml:

---
- name: Add text to an existing file
hosts: all
remote_user: devops
tasks:
- name: Add a single line of text to a file
lineinfile:
path: /home/devops/users.txt
line: This line was added by the lineinfile module.
state: present

214 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

4.2. Use el comando ansible-playbook --syntax-check add_line.yml para


verificar la sintaxis de la guía add_line.yml.

[student@workstation file-manage]$ ansible-playbook --syntax-check add_line.yml

playbook: add_line.yml

4.3. Ejecute la guía:

[student@workstation file-manage]$ ansible-playbook add_line.yml


PLAY [Add text to an existing file] ************************************

TASK [Gathering Facts] *************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [Add a single line of text to a file] *****************************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]

PLAY RECAP *************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

4.4. Use el módulo command con la opción cat, como el usuario devops, para verificar el
contenido del archivo users.txt en los hosts administrados.

[student@workstation file-manage]$ ansible all -m command \


> -a 'cat users.txt' -u devops
serverb.lab.example.com | CHANGED | rc=0 >>
This line was added by the lineinfile module.

servera.lab.example.com | CHANGED | rc=0 >>


This line was added by the lineinfile module.

5. Cree una guía denominada add_block.yml en el directorio de trabajo actual. Configure la


guía para usar el módulo blockinfile para añadir el siguiente bloque de texto al archivo
/home/devops/users.txt en todos los hosts administrados.

This block of text consists of two lines.


They have been added by the blockinfile module.

5.1. Cree la guía add_block.yml:

---
- name: Add block of text to a file
hosts: all
remote_user: devops
tasks:
- name: Add a block of text to an existing file
blockinfile:
path: /home/devops/users.txt

RH294-RHEL8.0-es-1-20200501 215
capítulo 6 | Implementación de archivos en hosts administrados

block: |
This block of text consists of two lines.
They have been added by the blockinfile module.
state: present

5.2. Use el comando ansible-playbook --syntax-check add_block.yml para


verificar la sintaxis de la guía add_block.yml.

[student@workstation file-manage]$ ansible-playbook --syntax-check add_block.yml

playbook: add_block.yml

5.3. Ejecute la guía:

[student@workstation file-manage]$ ansible-playbook add_block.yml

PLAY [Add block of text to a file] ****************************************

TASK [Gathering Facts] ****************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [Add a block of text to an existing file] ****************************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

5.4. Use el módulo command con el comando cat para verificar el contenido del archivo /
home/devops/users.txt en el host administrado.

[student@workstation file-manage]$ ansible all -m command \


> -a 'cat users.txt' -u devops
serverb.lab.example.com | CHANGED | rc=0 >>
This line was added by the lineinfile module.
# BEGIN ANSIBLE MANAGED BLOCK
This block of text consists of two lines.
They have been added by the blockinfile module.
# END ANSIBLE MANAGED BLOCK

servera.lab.example.com | CHANGED | rc=0 >>


This line was added by the lineinfile module.
# BEGIN ANSIBLE MANAGED BLOCK
This block of text consists of two lines.
They have been added by the blockinfile module.
# END ANSIBLE MANAGED BLOCK

6. Cree una guía denominada remove_file.yml en el directorio de trabajo actual.


Configure la guía para usar el módulo file para eliminar el archivo /home/devops/
users.txt de todos los hosts administrados.

216 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

6.1. Cree la guía remove_file.yml:

---
- name: Use the file module to remove a file
hosts: all
remote_user: devops
tasks:
- name: Remove a file from managed hosts
file:
path: /home/devops/users.txt
state: absent

6.2. Use el comando ansible-playbook --syntax-check remove_file.yml para


verificar la sintaxis de la guía remove_file.yml.

[student@workstation file-manage]$ ansible-playbook --syntax-check remove_file.yml

playbook: remove_file.yml

6.3. Ejecute la guía:

[student@workstation file-manage]$ ansible-playbook remove_file.yml


PLAY [Use the file module to remove a file] *******************************

TASK [Gathering Facts] ****************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [Remove a file from managed hosts] ***********************************


changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

6.4. Use un comando ad hoc para ejecutar el comando ls -l para confirmar que el
archivo users.txt ya no existe en los hosts administrados.

[student@workstation file-manage]$ ansible all -m command -a 'ls -l'


serverb.lab.example.com | CHANGED | rc=0 >>
total 0

servera.lab.example.com | CHANGED | rc=0 >>


total 0

Finalizar
En workstation, ejecute el script lab file-manage finish para limpiar este ejercicio.

[student@workstation ~]$ lab file-manage finish

RH294-RHEL8.0-es-1-20200501 217
capítulo 6 | Implementación de archivos en hosts administrados

Esto concluye el ejercicio guiado.

218 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

Implementación de archivos
personalizados con plantillas Jinja2

Objetivos
Tras completar esta sección, deberá ser capaz de usar plantillas de Jinja2 para implementar
archivos personalizados en hosts administrados.

Plantillas para archivos


Red Hat Ansible Engine tiene una serie de módulos que se pueden usar para modificar archivos
existentes. Estos incluyen lineinfile y blockinfile, entre otros. Sin embargo, no siempre
son fáciles de usar de manera efectiva y correcta.

Una forma mucho más poderosa de administrar archivos es utilizar una plantilla. Con este método,
puede escribir un archivo de configuración de plantilla que se personaliza automáticamente para
el host administrado cuando se implementa el archivo, usando datos y variables de Ansible. Esto
puede ser más fácil de controlar y menos propenso a errores.

Introducción a Jinja2
Ansible usa el sistema de plantillas Jinja2 para los archivos de plantilla. Ansible también usa la
sintaxis de Jinja2 para hacer referencia a las variables de las guías, por lo que ya sabe un poco
cómo usarlo.

Uso de delimitadores
Las variables y expresiones lógicas se colocan entre etiquetas, o delimitadores. Por ejemplo, las
plantillas Jinja2 usan {% EXPR %} para expresiones o lógica (por ejemplo, bucles), mientras que
{{ EXPR }} se usan para proporcionar los resultados de una expresión o una variable al usuario
final. La última etiqueta, cuando se representa, se reemplaza con un valor o con valores y son
visibles para el usuario final. Use la sintaxis {# COMMENT #} para encerrar los comentarios que no
deberían aparecer en el archivo final.

En el siguiente ejemplo, la primera línea incluye un comentario que no se incluirá en el archivo final.
Las referencias a variables en la segunda línea se reemplazan con los valores de datos del sistema
a los que hacen referencia.

{# /etc/hosts line #}
{{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}

Desarrollo de una plantilla Jinja2


Una plantilla Jinja2 está compuesta por múltiples elementos: datos, variables y expresiones. Estas
variables y expresiones se reemplazan con sus valores cuando se entrega la plantilla Jinja2. Las
variables utilizadas en la plantilla se pueden especificar en la sección vars de la guía. Es posible
usar la información de los hosts administrados como variables en una plantilla.

RH294-RHEL8.0-es-1-20200501 219
capítulo 6 | Implementación de archivos en hosts administrados

nota
Recuerde que la información asociada con un host administrado se puede obtener
usando el comando ansible system_hostname -i inventory_file -m
setup.

En el siguiente ejemplo, se muestra cómo crear una plantilla para /etc/ssh/sshd_config con
variables y datos recuperados por Ansible de los hosts administrados. Cuando la guía asociada se
ejecuta, los datos se reemplazan por sus valores en el host administrado que se está configurando.

nota
Un archivo que contiene una plantilla Jinja2 no necesita tener ninguna extensión de
archivo específica (por ejemplo, .j2). Sin embargo, proporcionar dicha extensión
de archivo puede hacer que sea más fácil recordar que es un archivo de plantilla.

# {{ ansible_managed }}
# DO NOT MAKE LOCAL MODIFICATIONS TO THIS FILE AS THEY WILL BE LOST

Port {{ ssh_port }}
ListenAddress {{ ansible_facts['default_ipv4']['address'] }}

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

SyslogFacility AUTHPRIV

PermitRootLogin {{ root_allowed }}
AllowGroups {{ groups_allowed }}

AuthorizedKeysFile /etc/.rht_authorized_keys .ssh/authorized_keys

PasswordAuthentication {{ passwords_allowed }}

ChallengeResponseAuthentication no

GSSAPIAuthentication yes
GSSAPICleanupCredentials no

UsePAM yes

X11Forwarding yes
UsePrivilegeSeparation sandbox

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 LANGUAGE
AcceptEnv XMODIFIERS

Subsystem sftp /usr/libexec/openssh/sftp-server

220 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

Implementación de plantillas Jinja2


Las plantillas Jinja2 son una herramienta valiosa para personalizar archivos de configuración para
ser implementados en los hosts administrados. Cuando se ha creado la plantilla Jinja2 para un
archivo de configuración, se puede implementar a los hosts administrados usando el módulo
template, el cual soporta la transferencia de un archivo local en el nodo de control a los hosts
administrados.

Para utilizar el módulo template, use la siguiente sintaxis. El valor asociado con la clave src
especifica la plantilla Jinja2 de origen, y el valor asociado a la clave dest especifica el archivo que
debe crearse en los hosts de destino.

tasks:
- name: template render
template:
src: /tmp/j2-template.j2
dest: /tmp/dest-config-file.txt

nota
El módulo template también le permite especificar el propietario (el usuario
que posee el archivo), el grupo, los permisos y el contexto SELinux del archivo
implementado, al igual que el módulo file. También puede tomar una opción
validate para ejecutar un comando arbitrario (como visudo -c) con el fin de
verificar que la sintaxis de un archivo sea correcta antes de copiarlo en su lugar.

Para obtener más detalles, consulte ansible-doc template.

Administración de archivos con plantillas


Para evitar que los administradores del sistema modifiquen los archivos implementados por
Ansible, se aconseja incluir un comentario en la parte superior de la plantilla para indicar que el
archivo no debe editarse manualmente.

Una forma de hacer esto es usar la cadena “Administrado por Ansible” en la directiva
ansible_managed. Esta no es una variable normal, pero se puede usar como una en una plantilla.
La directiva ansible_managed se establece en el archivo ansible.cfg:

ansible_managed = Ansible managed

Para incluir la cadena ansible_managed dentro de una plantilla Jinja2, use la siguiente sintaxis:

{{ ansible_managed }}

Estructuras de control
Puede usar las estructuras de control Jinja2 en los archivos de plantilla para reducir la escritura
repetitiva, ingresar entradas para cada host en una reproducción de forma dinámica o insertar
texto condicionalmente en un archivo.

RH294-RHEL8.0-es-1-20200501 221
capítulo 6 | Implementación de archivos en hosts administrados

Uso de bucles
Jinja2 usa la instrucción for para proporcionar la funcionalidad de bucles. En el siguiente ejemplo,
la variable user se reemplaza con todos los valores incluidos en la variable users, un valor por
línea.

{% for user in users %}


{{ user }}
{% endfor %}

La siguiente plantilla de ejemplo usa una sentencia for para ejecutar a través de todos los valores
en la variable users, y reemplaza myuser con cada valor, salvo cuando el valor es root.

{# for statement #}
{% for myuser in users if not myuser == "root" %}
User number {{ loop.index }} - {{ myuser }}
{% endfor %}

La variable loop.index se expande al número de índice en el que se encuentra actualmente el


bucle. Tiene un valor de 1 la primera vez que se ejecuta el bucle, y se va incrementando de a 1 en
cada iteración.

Como otro ejemplo, esta plantilla también usa la sentencia for y supone que se ha definido
una variable myhosts en el archivo de inventario que se utiliza. Esta variable contiene una lista
de hosts que deben gestionarse. Con la siguiente sentencia for, todos los hosts en el grupo
myhosts del inventario se enumeran en el archivo.

{% for myhost in groups['myhosts'] %}


{{ myhost }}
{% endfor %}

Para un ejemplo más práctico, puede usar esto para generar un archivo /etc/hosts de datos de
host de forma dinámica. Supongamos que tiene la siguiente guía:

- name: /etc/hosts is up to date


hosts: all
gather_facts: yes
tasks:
- name: Deploy /etc/hosts
template:
src: templates/hosts.j2
dest: /etc/hosts

La siguiente plantilla templates/hosts.j2 de tres líneas crea el archivo de todos los hosts del
grupo all. (La línea media es extremadamente larga en la plantilla debido a la longitud de los
nombres de las variables.) Se repite en cada host del grupo para obtener tres datos para el archivo
/etc/hosts.

222 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

{% for host in groups['all'] %}


{{ hostvars['host']['ansible_facts']['default_ipv4']['address'] }}
{{ hostvars['host']['ansible_facts']['fqdn'] }} {{ hostvars['host']
['ansible_facts']['hostname'] }}
{% endfor %}

Uso de condicionales
Jinja2 usa la instrucción if para proporcionar control condicional. Esto le permite colocar una línea
en un archivo implementado si se cumplen ciertas condiciones.

En el siguiente ejemplo, el valor de la variable result se coloca en el archivo implementado solo


si el valor de la variable finished es True.

{% if finished %}
{{ result }}
{% endif %}

Importante
Puede usar bucles y condicionales de Jinja2 en las plantillas de Ansible, pero no en
las guías de Ansible.

Filtros de variables
Jinja2 proporciona filtros que cambian el formato de salida de las expresiones de plantillas
(por ejemplo, a JSON). Existen filtros disponibles para lenguajes, como YAML y JSON. El filtro
to_json formatea el resultado de la expresión con JSON, y el filtro to_yaml formatea el
resultado de la expresión con YAML.

{{ output | to_json }}
{{ output | to_yaml }}

Hay filtros adicionales disponibles, como to_nice_json y to_nice_yaml que formatean el


resultado de la expresión en lenguaje natural JSON o YAML.

{{ output | to_nice_json }}
{{ output | to_nice_yaml }}

Los filtros from_json y from_yaml esperan cadenas en formato JSON o YAML,


respectivamente, para analizarlas.

{{ output | from_json }}
{{ output | from_yaml }}

Pruebas de variables
Las expresiones usadas con cláusulas when en las guías Ansible son expresiones Jinja2. Las
pruebas incorporadas de Ansible que se usan para probar los valores recibidos incluyen failed,

RH294-RHEL8.0-es-1-20200501 223
capítulo 6 | Implementación de archivos en hosts administrados

changed, succeeded y skipped. La siguiente tarea muestra cómo se pueden usar las pruebas
dentro de las expresiones condicionales.

tasks:
...output omitted...
- debug: msg="the execution was aborted"
when: returnvalue is failed

Referencias
plantilla - envía un archivo como plantilla a un servidor remoto —
Documentación Ansible
https://docs.ansible.com/ansible/latest/modules/template_module.html

Variables — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

Filtros — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html

224 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

Ejercicio Guiado

Implementación de archivos
personalizados con plantillas Jinja2
En este ejercicio, creará un archivo de plantilla simple que su guía usará para instalar un
archivo de Mensaje del Día personalizado en cada host administrado.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Generar un archivo de plantilla.

• Utilizar el archivo de plantilla en una guía.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab file-template start. Este script garantiza


que Ansible está instalado en workstation, crea el directorio /home/student/file-
template y descarga el archivo ansible.cfg en ese directorio.

[student@workstation ~]$ lab file-template start

nota
Todos los archivos usados durante este ejercicio están disponibles para
su referencia en workstation en el directorio /home/student/file-
template/files.

1. En workstation, diríjase al directorio de trabajo /home/student/file-template.


Cree el archivo inventory en el directorio de trabajo actual. Este archivo configura dos
grupos: webservers y workstations. Incluya el sistema servera.lab.example.com
en el grupo webservers, y el sistema workstation.lab.example.com en el grupo
workstations.

[webservers]
servera.lab.example.com

[workstations]
workstation.lab.example.com

2. Cree una plantilla para el Mensaje del día e inclúyalo en el archivo motd.j2 en el directorio
de trabajo actual. Incluya las siguientes variables y datos en la plantilla:

• ansible_facts['fqdn'], para insertar el FQDN del host administrado.

RH294-RHEL8.0-es-1-20200501 225
capítulo 6 | Implementación de archivos en hosts administrados

• ansible_facts['distribution'] y
ansible_facts['distribution_version'], para proporcionar información de
distribución.

• system_owner, para el correo electrónico del propietario del sistema. Esta variable
debe ser definida con un valor adecuado, en la sección vars de la plantilla de la guía.

This is the system {{ ansible_facts['fqdn'] }}.


This is a {{ ansible_facts['distribution'] }} version
{{ ansible_facts['distribution_version'] }} system.
Only use this system with permission.
You can request access from {{ system_owner }}.

3. Cree un archivo de guía denominado motd.yml en el directorio de trabajo actual. Defina la


variable system_owner en la sección vars e incluya una tarea para el módulo template,
el cual asigna la plantilla Jinja2 motd.j2 al archivo remoto /etc/motd en los hosts
administrados. Establezca el propietario y el grupo en root, y el modo en 0644.

---
- name: configure SOE
hosts: all
remote_user: devops
become: true
vars:
- system_owner: [email protected]
tasks:
- name: configure /etc/motd
template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644

4. Antes de ejecutar la guía, use el comando ansible-playbook --syntax-check para


verificar la sintaxis. Si informa errores, corríjalos antes de pasar al siguiente paso. Debe ver
una salida similar a la siguiente:

[student@workstation file-template]$ ansible-playbook --syntax-check motd.yml

playbook: motd.yml

5. Ejecute la guía motd.yml.

[student@workstation file-template]$ ansible-playbook motd.yml


PLAY [all] ******************************************************************

TASK [Gathering Facts] ******************************************************


ok: [servera.lab.example.com]
ok: [workstation.lab.example.com]

226 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

TASK [template] *************************************************************


changed: [servera.lab.example.com]
changed: [workstation.lab.example.com]

PLAY RECAP ******************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0
workstation.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

6. Inicie sesión en servera.lab.example.com con el usuario devops y verifique


que aparezca el MOTD correctamente al iniciar sesión. Finalice la sesión cuando haya
terminado.

[student@workstation file-template]$ ssh [email protected]


This is the system servera.lab.example.com.
This is a RedHat version 8.0 system.
Only use this system with permission.
You can request access from [email protected].
...output omitted...
[devops@servera ~]# exit
Connection to servera.lab.example.com closed.

Finalizar
Ejecute el comando lab file-template finish para limpiar después del ejercicio.

[student@workstation ~]$ lab file-template finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 227
capítulo 6 | Implementación de archivos en hosts administrados

Trabajo de laboratorio

Implementación de archivos en hosts


administrados
Lista de verificación de rendimiento
En este trabajo de laboratorio, ejecutará una guía que crea un archivo personalizado en sus
hosts administrados mediante el uso de una plantilla Jinja2.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Generar un archivo de plantilla.

• Utilizar el archivo de plantilla en una guía.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab file-review start. Esto garantiza que


Ansible está instalado en workstation, crea el directorio /home/student/file-review
y descarga el archivo ansible.cfg en ese directorio. También descarga los archivos
motd.yml, motd.j2, issue y inventory en el directorio /home/student/file-
review/files.

[student@workstation ~]$ lab file-review start

nota
Todos los archivos usados en este ejercicio están disponibles en
workstation en el directorio /home/student/file-review/files.

1. Cree un archivo de inventario denominado inventory en el directorio /home/student/


file-review. Este archivo de inventario define el grupo servers, el cual tiene asociado el
host administrado serverb.lab.example.com.
2. Identifique los datos en serverb.lab.example.com, que muestran la cantidad total de
memoria del sistema y la cantidad de procesadores.
3. Cree una plantilla para el Mensaje del día, denominada motd.j2, en el actual directorio.
Cuando el usuario devops inicia sesión en serverb.lab.example.com, debe aparecer
un mensaje que muestra la memoria total del sistema y la cantidad de procesadores. Use los
datos ansible_facts['memtotal_mb'] y ansible_facts['processor_count']
para proporcionar la información de memoria para el mensaje.
4. Cree un nuevo archivo de guía en el directorio actual, denominado motd.yml. Mediante el
módulo template, configure el archivo de la plantilla Jinja2 motd.j2 creado anteriormente,
para ser asignado al archivo /etc/motd en los hosts administrados. Este archivo tiene al

228 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

usuario root como propietario y grupo, y sus permisos son 0644. Con los módulos stat
y debug, cree tareas para verificar que /etc/motd exista en los hosts administrados y
muestre la información del archivo para /etc/motd. Use el módulo copy para colocar
files/issue en el directorio /etc/ del host administrado; use la misma propiedad y los
mismos permisos que /etc/motd. Use el módulo file para asegurarse de que /etc/
issue.net sea un enlace simbólico a /etc/issue en el host administrado. Configure la
guía para que use el usuario devops, y configure el parámetro become en true.
5. Ejecute la guía incluida en el archivo motd.yml.
6. Verifique que la guía incluida en el archivo motd.yml se haya ejecutado correctamente.

Evaluación
En workstation, ejecute el script lab file-review grade para confirmar que ha realizado
correctamente este ejercicio.

[student@workstation ~]$ lab file-review grade

Finalizar
En workstation, ejecute el script lab file-review finish para limpiar después del trabajo
de laboratorio.

[student@workstation ~]$ lab file-review finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 229
capítulo 6 | Implementación de archivos en hosts administrados

Solución

Implementación de archivos en hosts


administrados
Lista de verificación de rendimiento
En este trabajo de laboratorio, ejecutará una guía que crea un archivo personalizado en sus
hosts administrados mediante el uso de una plantilla Jinja2.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Generar un archivo de plantilla.

• Utilizar el archivo de plantilla en una guía.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab file-review start. Esto garantiza que


Ansible está instalado en workstation, crea el directorio /home/student/file-review
y descarga el archivo ansible.cfg en ese directorio. También descarga los archivos
motd.yml, motd.j2, issue y inventory en el directorio /home/student/file-
review/files.

[student@workstation ~]$ lab file-review start

nota
Todos los archivos usados en este ejercicio están disponibles en
workstation en el directorio /home/student/file-review/files.

1. Cree un archivo de inventario denominado inventory en el directorio /home/student/


file-review. Este archivo de inventario define el grupo servers, el cual tiene asociado el
host administrado serverb.lab.example.com.

1.1. En workstation, cambie al directorio /home/student/file-review.

[student@workstation ~]$ cd ~/file-review/

1.2. Cree el archivo inventory en el directorio actual. Este archivo configura un grupo
denominado servers. Incluya el sistema serverb.lab.example.com en el grupo
servers.

230 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

[servers]
serverb.lab.example.com

2. Identifique los datos en serverb.lab.example.com, que muestran la cantidad total de


memoria del sistema y la cantidad de procesadores.
Use el módulo setup para obtener una lista de todos los datos para el host administrado
serverb.lab.example.com. Los datos ansible_processor_count y
ansible_memtotal_mb proporcionan información sobre los límites de recursos del host
administrado.

[student@workstation file-review]$ ansible serverb.lab.example.com -m setup


serverb.lab.example.com | SUCCESS => {
"ansible_facts": {
...output omitted...
"ansible_processor_count": 1,
...output omitted...
"ansible_memtotal_mb": 821,
...output omitted...
},
"changed": false
}

3. Cree una plantilla para el Mensaje del día, denominada motd.j2, en el actual directorio.
Cuando el usuario devops inicia sesión en serverb.lab.example.com, debe aparecer
un mensaje que muestra la memoria total del sistema y la cantidad de procesadores. Use los
datos ansible_facts['memtotal_mb'] y ansible_facts['processor_count']
para proporcionar la información de memoria para el mensaje.

System total memory: {{ ansible_facts['memtotal_mb'] }} MiB.


System processor count: {{ ansible_facts['processor_count'] }}

4. Cree un nuevo archivo de guía en el directorio actual, denominado motd.yml. Mediante el


módulo template, configure el archivo de la plantilla Jinja2 motd.j2 creado anteriormente,
para ser asignado al archivo /etc/motd en los hosts administrados. Este archivo tiene al
usuario root como propietario y grupo, y sus permisos son 0644. Con los módulos stat
y debug, cree tareas para verificar que /etc/motd exista en los hosts administrados y
muestre la información del archivo para /etc/motd. Use el módulo copy para colocar
files/issue en el directorio /etc/ del host administrado; use la misma propiedad y los
mismos permisos que /etc/motd. Use el módulo file para asegurarse de que /etc/
issue.net sea un enlace simbólico a /etc/issue en el host administrado. Configure la
guía para que use el usuario devops, y configure el parámetro become en true.

---
- name: Configure system
hosts: all
remote_user: devops
become: true
tasks:
- name: Configure a custom /etc/motd
template:
src: motd.j2
dest: /etc/motd

RH294-RHEL8.0-es-1-20200501 231
capítulo 6 | Implementación de archivos en hosts administrados

owner: root
group: root
mode: 0644

- name: Check file exists


stat:
path: /etc/motd
register: motd

- name: Display stat results


debug:
var: motd

- name: Copy custom /etc/issue file


copy:
src: files/issue
dest: /etc/issue
owner: root
group: root
mode: 0644

- name: Ensure /etc/issue.net is a symlink to /etc/issue


file:
src: /etc/issue
dest: /etc/issue.net
state: link
owner: root
group: root
force: yes

5. Ejecute la guía incluida en el archivo motd.yml.

5.1. Antes de ejecutar la guía, ejecute el comando ansible-playbook --syntax-


check para verificar su sintaxis. Si informa errores, corríjalos antes de pasar al siguiente
paso. Debe ver una salida similar a la siguiente:

[student@workstation file-review]$ ansible-playbook --syntax-check motd.yml

playbook: motd.yml

5.2. Ejecute la guía incluida en el archivo motd.yml.

[student@workstation file-review]$ ansible-playbook motd.yml

PLAY [Configure system] ****************************************************

TASK [Gathering Facts] *****************************************************


ok: [serverb.lab.example.com]

TASK [Configure a custom /etc/motd] ****************************************


changed: [serverb.lab.example.com]

TASK [Check file exists] ***************************************************


ok: [serverb.lab.example.com]

232 RH294-RHEL8.0-es-1-20200501
capítulo 6 | Implementación de archivos en hosts administrados

TASK [Display stat results] ************************************************


ok: [serverb.lab.example.com] => {
"motd": {
"changed": false,
"failed": false,
...output omitted...

TASK [Copy custom /etc/issue file] *****************************************


changed: [serverb.lab.example.com]

TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ********************


changed: [serverb.lab.example.com]

PLAY RECAP *****************************************************************


serverb.lab.example.com : ok=6 changed=3 unreachable=0 failed=0

6. Verifique que la guía incluida en el archivo motd.yml se haya ejecutado correctamente.


Inicie sesión en serverb.lab.example.com con el usuario devops y verifique que el
contenido de /etc/motd y /etc/issue aparezca al iniciar sesión. Finalice la sesión cuando
haya terminado.

[student@workstation file-review]$ ssh [email protected]


*------------------------------- PRIVATE SYSTEM -----------------------------*
* Access to this computer system is restricted to authorised users only. *
* *
* Customer information is confidential and must not be disclosed. *
*----------------------------------------------------------------------------*
System total memory: 821 MiB.
System processor count: 1
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Thu Apr 25 22:09:33 2019 from 172.25.250.9


[devops@serverb ~]$ logout

Evaluación
En workstation, ejecute el script lab file-review grade para confirmar que ha realizado
correctamente este ejercicio.

[student@workstation ~]$ lab file-review grade

Finalizar
En workstation, ejecute el script lab file-review finish para limpiar después del trabajo
de laboratorio.

[student@workstation ~]$ lab file-review finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 233
capítulo 6 | Implementación de archivos en hosts administrados

Resumen
En este capítulo, aprendió lo siguiente:

• La biblioteca de módulos Files incluye módulos que le permiten realizar la mayoría de las
tareas relacionadas con la administración de archivos, como crear, copiar, editar y modificar
permisos y otros atributos de archivos.

• Puede usar plantillas Jinja2 para crear archivos dinámicamente para la implementación.

• Por lo general, una plantilla Jinja2 se compone de dos elementos: variables y expresiones. Estas
variables y expresiones se reemplazan con valores cuando se entrega la plantilla Jinja2.

• Los filtros en Jinja2 transforman las expresiones de las plantillas de un tipo o formato de datos a
otro.

234 RH294-RHEL8.0-es-1-20200501
capítulo 7

Administración de proyectos
grandes
Meta Escribir guías que estén optimizadas para
proyectos más grandes y complejos.

Objetivos • Escribir patrones de host sofisticados para


seleccionar hosts de manera eficiente para un
comando de reproducción o ad hoc.
• Describir las características y el propósito de los
inventarios dinámicos, e instalar y usar un script
existente como fuente de inventario dinámico
de Ansible.
• Ajustar la cantidad de conexiones simultáneas
que Ansible abre a los hosts administrados,
y cómo Ansible procesa grupos de hosts
administrados a través de las tareas de la
reproducción.
• Administrar guías grandes importando o
incluyendo otras guías o tareas desde archivos
externos, ya sea sin condiciones o sobre la base
de una prueba condicional.

Secciones • Selección de hosts con patrones de hosts (y


ejercicio guiado)
• Administración de inventarios dinámicos (y
ejercicio guiado)
• Configuración del paralelismo (y ejercicio
guiado)
• Inclusión e importación de archivos (y ejercicio
guiado)

Trabajo de • Administración de proyectos grandes


laboratorio

RH294-RHEL8.0-es-1-20200501 235
capítulo 7 | Administración de proyectos grandes

Selección de hosts con patrones de hosts

Objetivos
Después de completar esta sección, deberá ser capaz de escribir patrones de host sofisticados a
fin de seleccionar hosts de manera eficiente para una reproducción o un comando ad hoc.

Referencias a hosts de inventario


Los patrones de host se usan para especificar los hosts a los que debe apuntar una reproducción
o un comando ad hoc. En su forma más simple, el nombre de un host administrado o un grupo de
hosts en el inventario es un patrón de hosts que especifica ese host o grupo de hosts.

Ya ha utilizado patrones de hosts en este curso. En una reproducción, la directiva hosts especifica
los hosts administrados respecto de los cuales se ejecutará la reproducción. Para un comando ad
hoc, debe proporcionar el patrón de host como un argumento de la línea de comandos al comando
ansible.

En general, es más fácil controlar a qué hosts apunta una reproducción usando cuidadosamente
patrones de hosts y teniendo grupos de inventario correctos en lugar de establecer condicionales
complejos en las tareas de la reproducción. Por lo tanto, es importante tener una comprensión
sólida de los patrones de host.

El siguiente ejemplo de inventario se usa en esta sección para ilustrar patrones de hosts.

[student@controlnode ~]$ cat myinventory


web.example.com
data.example.com

[lab]
labhost1.example.com
labhost2.example.com

[test]
test1.example.com
test2.example.com

[datacenter1]
labhost1.example.com
test1.example.com

[datacenter2]
labhost2.example.com
test2.example.com

[datacenter:children]
datacenter1
datacenter2

236 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

[new]
192.168.2.1
192.168.2.2

Para demostrar cómo se resuelven los patrones de host, ejecutará una guía Ansible,
playbook.yml, utilizando diferentes patrones de host para identificar diferentes subconjuntos
de hosts administrados de este inventario de ejemplo.

Hosts administrados
El patrón más básico es el nombre para un solo host administrado detallado en el inventario.
Especifica que el host será el único en el inventario en el que se actuará mediante el comando
ansible.

Cuando se ejecuta la guía, la primera tarea Recopilación de datos debe ejecutarse en todos
los hosts administrados que coincidan con el patrón de host. Un error durante esta tarea puede
hacer que el host administrado se elimine de la reproducción.

Si una dirección IP aparece explícitamente en el inventario, en lugar de un nombre de host,


entonces puede usarse como patrón de host. Si la dirección IP no está en el inventario, no podrá
usarla para especificar el host aun si la dirección IP se resuelve a ese nombre de host en el DNS.

En el siguiente ejemplo, se muestra cómo se puede usar el patrón de host para hacer referencia a
una dirección IP contenida en un inventario.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: 192.168.2.1
...output omitted...

[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [192.168.2.1]
...output omitted...

nota
Un problema al hacer referencia a hosts administrados por medio de una
dirección IP en el inventario es que puede resultar difícil recordar qué dirección IP
corresponde a qué host para sus reproducciones y comandos ad hoc. Sin embargo,
es posible que deba especificar el host por dirección IP para fines de conexión si el
host no tiene un nombre de host que se pueda resolver.

Es posible apuntar a un alias en una dirección IP específica en su inventario si


establece la variable de host ansible_host. Por ejemplo, podría tener un host en
su inventario con el nombre dummy.example y, luego, conexiones directas con ese
nombre a la dirección IP 192.168.2.1 mediante la creación de un archivo host_vars/
dummy.example que contenga la siguiente variable de host:

ansible_host: 192.168.2.1

RH294-RHEL8.0-es-1-20200501 237
capítulo 7 | Administración de proyectos grandes

Especificar hosts usando un grupo


Ya ha usado grupos de hosts de inventario como patrones de hosts. Cuando el nombre de un
grupo se usa como patrón de host, especifica que Ansible actuará en los hosts que son miembros
del grupo.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: lab
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [labhost2.example.com]
...output omitted...

Recuerde que hay un grupo especial llamado all que coincide con todos los hosts administrados
en el inventario.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: all
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost2.example.com]
ok: [test2.example.com]
ok: [web.example.com]
ok: [data.example.com]
ok: [labhost1.example.com]
ok: [192.168.2.1]
ok: [test1.example.com]
ok: [192.168.2.2]

También hay un grupo especial llamado ungrouped que incluye todos los hosts administrados en
el inventario que no son miembros de ningún otro grupo:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: ungrouped
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

238 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

TASK [Gathering Facts] *****************************************************


ok: [web.example.com]
ok: [data.example.com]

Coincidencia con varios hosts con comodines


Otro método de lograr lo mismo que con el patrón del host all es usar el carácter comodín
asterisco (*), que coincide con cualquier cadena. Si el patrón de host es solo un asterisco entre
comillas, entonces todos los hosts en el inventario coincidirán.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: '*'
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost2.example.com]
ok: [test2.example.com]
ok: [web.example.com]
ok: [data.example.com]
ok: [labhost1.example.com]
ok: [192.168.2.1]
ok: [test1.example.com]
ok: [192.168.2.2]

Importante
Algunos caracteres que se usan en los patrones de host también tienen significado
para la shell. Esto puede ser un problema al usar patrones de hosts para ejecutar
comandos ad hoc desde la línea de comandos con ansible. Es una práctica
recomendada colocar entre comillas simples los patrones de host usados en la línea
de comandos para protegerlos de una expansión de shell no deseada.

Del mismo modo, si usa caracteres comodín o de lista especiales en una Ansible
Playbook, debe colocar su patrón de host entre comillas simples para asegurarse de
que se analice correctamente.

---
hosts: '!test1.example.com,development'

El carácter de asterisco también se puede usar para que coincida con cualquier host administrado
o grupo que contenga una subcadena específica.

Por ejemplo, el siguiente patrón de host comodín coincide con todos los nombres de inventario
que finalizan en .example.com:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: '*.example.com'

RH294-RHEL8.0-es-1-20200501 239
capítulo 7 | Administración de proyectos grandes

...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [test1.example.com]
ok: [labhost2.example.com]
ok: [test2.example.com]
ok: [web.example.com]
ok: [data.example.com]

El siguiente ejemplo usa un patrón de host comodín para coincidir con los nombres de hosts o
grupos de hosts que comienzan con 192.168.2.:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: '192.168.2.*'
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [192.168.2.1]
ok: [192.168.2.2]

El siguiente ejemplo usa un patrón de host comodín para coincidir con los nombres de hosts o
grupos de hosts que comienzan con datacenter.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: 'datacenter*'
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [test1.example.com]
ok: [labhost2.example.com]
ok: [test2.example.com]

240 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Importante
Los patrones de host comodín coinciden con todos los nombres de inventario,
hosts y grupos de hosts. No distinguen entre nombres que son nombres de DNS,
direcciones IP o grupos, lo que puede generar ciertas coincidencias inesperadas.

Por ejemplo, compare los resultados de especificar el patrón de host datacenter*


del ejemplo anterior con los resultados del patrón de host data* basado en el
inventario de ejemplo:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: 'data*'
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [test1.example.com]
ok: [labhost2.example.com]
ok: [test2.example.com]
ok: [data.example.com]

Listas
Se puede hacer referencia a varias entradas en un inventario con listas lógicas. Una lista de
patrones de hosts separados por comas coincide con todos los hosts que coinciden con cualquiera
de esos patrones de hosts.

Si usted proporciona una lista de hosts administrados separados por comas, se apuntará a todos
estos hosts administrados:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: labhost1.example.com,test2.example.com,192.168.2.2
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [test2.example.com]
ok: [192.168.2.2]

Si usted proporciona una lista de grupos separados por comas, se apuntará a todos estos hosts en
cualquiera de esos grupos:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: lab,datacenter1

RH294-RHEL8.0-es-1-20200501 241
capítulo 7 | Administración de proyectos grandes

...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [labhost2.example.com]
ok: [test1.example.com]

También puede combinar hosts administrados, grupos de hosts y comodines, como se muestra
más abajo:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: lab,data*,192.168.2.2
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [labhost2.example.com]
ok: [test1.example.com]
ok: [test2.example.com]
ok: [data.example.com]
ok: [192.168.2.2]

nota
El carácter de dos puntos (:) puede usarse en lugar de una coma. Sin embargo, la
coma es el separador preferido, en especial, cuando se trabaja con direcciones IPv6
como nombres de hosts administrados. Puede ver la sintaxis de los dos puntos en
ejemplos anteriores.

Si un elemento en una lista comienza con un carácter &, los hosts deben coincidir con ese
elemento para coincidir con el patrón de host. Funciona de manera similar que un AND lógico.

Por ejemplo, en nuestro ejemplo de inventario, el siguiente patrón de host coincidirá con las
máquinas en el grupo lab solo si también se encuentran en el grupo datacenter1:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: lab,&datacenter1
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]

242 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

También podría especificar que las máquinas en el grupo datacenter1 coincidan


solo si se encuentran en el grupo lab con los patrones de host &lab,datacenter1 o
datacenter1,&lab.

Puede excluir hosts que coincidan con un patrón de una lista si usa el signo de exclamación o
carácter "bang" (!) delante del patrón de host. Esto funciona como un NOT lógico.

Este ejemplo coincide con todos los hosts definidos en el grupo datacenter, con la excepción de
test2.example.com, dado el inventario de ejemplo:

[student@controlnode ~]$ cat playbook.yml


---
- hosts: datacenter,!test2.example.com
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [labhost1.example.com]
ok: [test1.example.com]
ok: [labhost2.example.com]

El patrón '!test2.example.com,datacenter' se podría haber usado en el ejemplo anterior


para obtener el mismo resultado.

El último ejemplo muestra el uso de un patrón de host que coincide con todos los hosts del
inventario de prueba, con la excepción de los hosts administrados en el grupo datacenter1.

[student@controlnode ~]$ cat playbook.yml


---
- hosts: all,!datacenter1
...output omitted...
[student@controlnode ~]$ ansible-playbook playbook.yml

PLAY [Test Host Patterns] **************************************************

TASK [Gathering Facts] *****************************************************


ok: [web.example.com]
ok: [data.example.com]
ok: [labhost2.example.com]
ok: [test2.example.com]
ok: [192.168.2.1]
ok: [192.168.2.2]

Referencias
Trabajo con patrones — Documentación de Ansible
https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html

Trabajo con inventarios — Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

RH294-RHEL8.0-es-1-20200501 243
capítulo 7 | Administración de proyectos grandes

Ejercicio Guiado

Selección de hosts con patrones de hosts


En este ejercicio, explorará el modo en que pueden usarse los patrones de hosts
para especificar hosts de inventario para reproducciones o comandos ad hoc. Se le
proporcionarán varios ejemplos de inventario para explorar patrones de host.

Resultados
Podrá usar diferentes patrones de hosts para acceder a diversos hosts en un inventario.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-host start. El script crea el


directorio del proyecto projects-host y descarga el archivo de configuración de Ansible y
el archivo del inventario del host necesarios para este ejercicio.

[student@workstation ~]$ lab projects-host start

1. En workstation, cambie al directorio de trabajo del ejercicio, /home/student/


projects-host, y revise el contenido del directorio.

[student@workstation ~]$ cd ~/projects-host


[student@workstation projects-host]$

1.1. Enumere el contenido del directorio.

[student@workstation projects-host]$ ls
ansible.cfg inventory1 inventory2 playbook.yml

1.2. Inspeccione el archivo de inventario de ejemplo, inventory1. Observe cómo


está organizado el inventario. Explore los hosts y grupos que se encuentran en el
inventario, y los dominios que se usan.

srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com

[web]
jupiter.lab.example.com
saturn.example.com

[db]
db1.example.com
db2.example.com

244 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

db3.example.com

[lb]
lb1.lab.example.com
lb2.lab.example.com

[boston]
db1.example.com
jupiter.lab.example.com
lb2.lab.example.com

[london]
db2.example.com
db3.example.com
file1.lab.example.com
lb1.lab.example.com

[dev]
web1.lab.example.com
db3.example.com

[stage]
file2.example.com
db2.example.com

[prod]
lb2.lab.example.com
db1.example.com
jupiter.lab.example.com

[function:children]
web
db
lb
city

[city:children]
boston
london
environments

[environments:children]
dev
stage
prod
new

[new]
172.25.252.23
172.25.252.44
172.25.252.32

RH294-RHEL8.0-es-1-20200501 245
capítulo 7 | Administración de proyectos grandes

1.3. Inspeccione el archivo de inventario de ejemplo, inventory2. Observe cómo


está organizado el inventario. Explore los hosts y grupos que se encuentran en el
inventario, y los dominios que se usan.

workstation.lab.example.com

[london]
servera.lab.example.com

[berlin]
serverb.lab.example.com

[tokyo]
serverc.lab.example.com

[atlanta]
serverd.lab.example.com

[europe:children]
london
berlin

1.4. Por último, inspeccione el contenido de la guía, playbook.yml. Observe cómo la


guía usa el módulo debug para mostrar el nombre de cada host administrado.

---
- name: Resolve host patterns
hosts:
tasks:
- name: Display managed host name
debug:
msg: "{{ inventory_hostname }}"

2. Utilizando un comando ad hoc, determine si el servidor db1.example.com está presente


en el archivo de inventario inventory1.

[student@workstation projects-host]$ ansible db1.example.com -i inventory1 \


> --list-hosts
hosts (1):
db1.example.com

3. Utilizando un comando ad hoc, haga referencia a una dirección IP contenida en el inventario


inventory1 con un patrón de host.

[student@workstation projects-host]$ ansible 172.25.252.44 -i inventory1 \


> --list-hosts
hosts (1):
172.25.252.44

4. Con un comando ad hoc, use el grupo all para mostrar todos los hosts administrados en el
archivo de inventario inventory1.

246 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

[student@workstation projects-host]$ ansible all -i inventory1 --list-hosts


hosts (17):
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
jupiter.lab.example.com
saturn.example.com
db1.example.com
db2.example.com
db3.example.com
lb1.lab.example.com
lb2.lab.example.com
file1.lab.example.com
web1.lab.example.com
file2.example.com
172.25.252.23
172.25.252.44
172.25.252.32

5. Con un comando ad hoc, use el carácter asterisco (*) para enumerar todos los hosts que
terminan en .example.com en el archivo de inventario inventory1.

[student@workstation projects-host]$ ansible '*.example.com' -i inventory1 \


> --list-hosts
hosts (14):
jupiter.lab.example.com
saturn.example.com
db1.example.com
db2.example.com
db3.example.com
lb1.lab.example.com
lb2.lab.example.com
file1.lab.example.com
web1.lab.example.com
file2.example.com
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com

6. Como puede ver en la salida del comando anterior, hay 14 hosts en el dominio
*.example.com. Modifique el patrón de host en el comando ad hoc anterior para que se
ignoren los hosts del dominio *.lab.example.com.

[student@workstation projects-host]$ ansible '*.example.com, !*.lab.example.com' \


> -i inventory1 --list-hosts
hosts (7):
saturn.example.com
db1.example.com
db2.example.com

RH294-RHEL8.0-es-1-20200501 247
capítulo 7 | Administración de proyectos grandes

db3.example.com
file2.example.com
srv1.example.com
srv2.example.com

7. Sin acceder a los grupos del archivo de inventario inventory1, use un comando ad hoc
para hacer una lista de estos tres hosts: lb1.lab.example.com, s1.lab.example.com
y db1.example.com.

[student@workstation projects-host]$ ansible \


> lb1.lab.example.com,s1.lab.example.com,db1.example.com -i inventory1 \
> --list-hosts
hosts (3):
lb1.lab.example.com
s1.lab.example.com
db1.example.com

8. Use un patrón de host comodín en un comando ad hoc para hacer una lista de hosts
que comiencen con una dirección IP 172.25. Dirección IP en el archivo de inventario
inventory1.

[student@workstation projects-host]$ ansible '172.25.*' -i inventory1 --list-hosts


hosts (3):
172.25.252.23
172.25.252.44
172.25.252.32

9. Use un patrón de host en un comando ad hoc para enumerar todos los hosts del archivo de
inventario inventory1 que comienzan con la letra "s".

[student@workstation projects-host]$ ansible 's*' -i inventory1 --list-hosts


hosts (7):
saturn.example.com
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
file2.example.com
db2.example.com

Observe los hosts file2.example.com y db2.example.com en la salida del comando


anterior. Aparecen en la lista, ya que ambos son miembros de un grupo denominado stage,
que también comienza con la letra "s".

10. Con una lista y un patrón de host comodín en un comando ad hoc, muestre todos los hosts
en el inventario inventory1 del grupo prod, todos los hosts cuya dirección IP comienza
con 172 y todos los hosts que contienen lab en su nombre.

[student@workstation projects-host]$ ansible 'prod,172*,*lab*' -i inventory1 \


> --list-hosts
hosts (11):
lb2.lab.example.com

248 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

db1.example.com
jupiter.lab.example.com
172.25.252.23
172.25.252.44
172.25.252.32
lb1.lab.example.com
file1.lab.example.com
web1.lab.example.com
s1.lab.example.com
s2.lab.example.com

11. Use un comando ad hoc para listar todos los hosts que pertenecen a los grupos db y
london.

[student@workstation projects-host]$ ansible 'db,&london' -i inventory1 \


> --list-hosts
hosts (2):
db2.example.com
db3.example.com

12. Modifique el valor de hosts en el archivo playbook.yml para que todos los servidores
en el grupo london sean el objetivo. Ejecute la guía usando el archivo de inventario
inventory2.

...output omitted...
hosts: london
...output omitted...

[student@workstation projects-host]$ ansible-playbook -i inventory2 playbook.yml


...output omitted...
TASK [Gathering Facts] ************************************************
ok: [servera.lab.example.com]
...output omitted...

13. Modifique el valor de hosts en el archivo playbook.yml para que todos los servidores en
el grupo anidado europe sean el objetivo. Ejecute la guía usando el archivo de inventario
inventory2.

...output omitted...
hosts: europe
...output omitted...

[student@workstation projects-host]$ ansible-playbook -i inventory2 playbook.yml


...output omitted...
TASK [Gathering Facts] ************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
...output omitted...

RH294-RHEL8.0-es-1-20200501 249
capítulo 7 | Administración de proyectos grandes

14. Modifique el valor de hosts en el archivo playbook.yml para que todos los servidores
que no pertenecen a ningún grupo sean el objetivo. Ejecute la guía usando el archivo de
inventario inventory2.

...output omitted...
hosts: ungrouped
...output omitted...

[student@workstation projects-hosts]$ ansible-playbook -i inventory2 playbook.yml


...output omitted...
TASK [Gathering Facts] ************************************************
ok: [workstation.lab.example.com]
...output omitted...

Finalizar
En workstation, ejecute el script lab projects-host finish para limpiar este ejercicio.

[student@workstation ~]$ lab projects-host finish

Esto concluye el ejercicio guiado.

250 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Administración de inventarios dinámicos

Objetivos
Después de finalizar esta sección, será capaz de describir qué son los inventarios dinámicos, e
instalar y usar un script existente como fuente de inventario dinámico de Ansible.

Generación dinámica de inventarios


Los archivos de inventario estático con los que trabajó hasta ahora son fáciles de escribir y son
convenientes para administrar pequeñas infraestructuras. Sin embargo, cuando trabaja con
muchas máquinas, o en un entorno donde las máquinas van y vienen rápidamente, puede ser difícil
mantener los archivos de inventario estático actualizados.

La mayoría de los entornos de TI tienen sistemas que hacen un seguimiento de los hosts que
están disponibles y del modo en que están organizados. Por ejemplo, puede haber un servicio de
directorio externo mantenido por un sistema de monitoreo, como Zabbix, o en servidores FreeIPA
o Active Directory. Los servidores de instalación, como Cobbler, o los servicios de administración,
como Red Hat Satellite, pueden hacer un seguimiento de los sistemas sin sistema operativo (bare-
metal) implementados. De manera similar, los servicios de nube, como Amazon Web Services EC2,
o una implementación de OpenStack, o las infraestructuras de máquinas virtuales basadas en
VMware o Red Hat Virtualization pueden ser fuentes de información acerca de las instancias y las
máquinas virtuales que van y vienen.

Ansible admite scripts dynamic inventory que recuperan información actual de estos tipos de
fuentes siempre que se ejecuta Ansible, lo que permite que el inventario se actualice en tiempo
real. Estos scripts son programas ejecutables que recopilan información de algunas fuentes
externas y proporcionan el inventario en formato JSON.

Los scripts de inventario dinámico se usan igual que los archivos de texto de inventario estático.
La ubicación del inventario se especifica directamente en el archivo ansible.cfg actual, o con
la opción -i. Si el archivo de inventario es ejecutable, se trata como un programa de inventario
dinámico, y Ansible intenta ejecutarlo para generar el inventario. Si el archivo no es ejecutable, se
trata como un inventario estático.

nota
La ubicación del inventario se puede configurar en el archivo de configuración
ansible.cfg con el parámetro inventory. De forma predeterminada, se
configura en /etc/ansible/hosts.

Scripts aportados
La comunidad de código abierto aportó varios scripts de inventario dinámico existentes al
proyecto de Ansible. No están incluidos en el paquete ansible ni son admitidos oficialmente por
Red Hat. Estos scripts están disponibles en el sitio de Ansible GitHub en https://github.com/
ansible/ansible/tree/devel/contrib/inventory.

Algunas de las fuentes de datos o plataformas a las que apuntan los scripts de inventario dinámico
aportados incluyen las siguientes:

RH294-RHEL8.0-es-1-20200501 251
capítulo 7 | Administración de proyectos grandes

• Plataformas de nube privada, como Red Hat OpenStack Platform.

• Plataformas de nube pública, como Rackspace Cloud, Amazon Web Services EC2 o Google
Compute Engine.

• Plataformas de virtualización, como Red Hat Virtualization (oVirt) y VMware vSphere.

• Soluciones de plataforma como servicio, como OpenShift Container Platform.

• Herramientas de administración del ciclo de vida, como Foreman (con Red Hat Satellite 6 o
autónomo) y Spacewalk (innovación de Red Hat Satellite 5).

• Proveedores de hosting, como Digital Ocean o Linode.

Cada script puede tener sus propias dependencias y sus propios requisitos para funcionar. Los
scripts aportados están escritos mayormente en Python, pero esto no es un requisito para los
scripts de inventario dinámico.

Escritura de programas de inventario dinámico


Si no existe un script de inventario dinámico para el sistema de directorio o la infraestructura
en uso, puede escribir un programa de inventario dinámico personalizado. El programa
predeterminado se puede escribir en cualquier lenguaje de programación, pero debe devolver
información de inventario en formato JSON cuando se pasen las opciones correspondientes.

El comando ansible-inventory puede ser una herramienta útil para aprender a crear
inventarios de Ansible en formato JSON. Puede usar el comando ansible-inventory,
disponible desde Ansible 2.4, para ver un archivo de inventario en formato JSON.

Para mostrar el contenido del archivo de inventario en formato JSON, ejecute el comando
ansible-inventory --list. Puedes usar la opción -i para especificar la ubicación del
archivo de inventario para procesar, o simplemente usar el inventario predeterminado establecido
por la configuración actual de Ansible.

En el siguiente ejemplo, se demuestra el uso del comando ansible-inventory para procesar


un archivo de inventario de estilo INI y mostrar un archivo en formato JSON.

[student@workstation projects-host]$ cat inventory


workstation1.lab.example.com

[webservers]
web1.lab.example.com
web2.lab.example.com

[databases]
db1.lab.example.com
db2.lab.example.com

[student@workstation projects-host]$ ansible-inventory -i inventory --list


{
"_meta": {
"hostvars": {
"db1.lab.example.com": {},
"db2.lab.example.com": {},
"web1.lab.example.com": {},
"web2.lab.example.com": {},
"workstation1.lab.example.com": {}

252 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

}
},
"all": {
"children": [
"databases",
"ungrouped",
"webservers"
]
},
"databases": {
"hosts": [
"db1.lab.example.com",
"db2.lab.example.com"
]
},
"ungrouped": {
"hosts": [
"workstation1.lab.example.com"
]
},
"webservers": {
"hosts": [
"web1.lab.example.com",
"web2.lab.example.com"
]
}
}

Si desea escribir su propio script de inventario dinámico, puede encontrar más información
detallada en Desarrollo de fuentes de inventario dinámico [http://docs.ansible.com/ansible/
dev_guide/developing_inventory.html] dentro de la Guía para desarrolladores Ansible. A
continuación, se incluye una breve descripción general.

Inicie el script con una línea de intérprete adecuada (por ejemplo, #!/usr/bin/python) y
debería ser ejecutable para que lo pueda ejecutar Ansible.

Cuando se pase la opción --list, el script debe mostrar un diccionario/hash con codificación
JSON de todos los hosts y grupos en el inventario.

En su forma más simple, un grupo puede ser una lista de hosts administrados. En este ejemplo de
una salida con codificación JSON de un script de inventario, webservers es un grupo de hosts
que tiene web1.lab.example.com y web2.lab.example.com como hosts administrados
en el grupo. El grupo de hosts databases incluye los hosts db1.lab.example.com y
db2.lab.example.com como miembros.

[student@workstation ~]$ ./inventoryscript --list


{
"webservers" : [ "web1.lab.example.com", "web2.lab.example.com" ],
"databases" : [ "db1.lab.example.com", "db2.lab.example.com" ]
}

De forma alternativa, el valor de cada grupo puede ser un diccionario/hash JSON que contenga
una lista de cada host administrado, los grupos secundarios y todas las variables de grupo que
se puedan establecer. El siguiente ejemplo muestra la salida con codificación JSON para un

RH294-RHEL8.0-es-1-20200501 253
capítulo 7 | Administración de proyectos grandes

inventario dinámico más complejo. El grupo boston tiene dos grupos secundarios (backup e
ipa), tres hosts administrados propios y una variable de grupo establecida (example_host:
false).

{
"webservers" : [
"web1.demo.example.com",
"web2.demo.example.com"
],
"boston" : {
"children" : [
"backup",
"ipa"
],
"vars" : {
"example_host" : false
},
"hosts" : [
"server1.demo.example.com",
"server2.demo.example.com",
"server3.demo.example.com"
]
},
"backup" : [
"server4.demo.example.com"
],
"ipa" : [
"server5.demo.example.com"
],
"_meta" : {
"hostvars" : {
"server5.demo.example.com": {
"ntpserver": "ntp.demo.example.com",
"dnsserver": "dns.demo.example.com"
}
}
}
}

El script también debe respaldar la opción --host managed-host. Dicha opción debe imprimir
un diccionario/hash JSON que consta de variables asociadas con ese host, o un diccionario/hash
JSON vacío.

[student@workstation ~]$ ./inventoryscript --host server5.demo.example.com


{
"ntpserver" : "ntp.demo.example.com",
"dnsserver" : "dns.demo.example.com"
}

254 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

nota
Cuando se lo llama con la opción --host hostname, el script debe imprimir un
diccionario/hash JSON de las variables para el host especificado. Se puede imprimir
un hash o diccionario JSON vacío si no se proporcionan variables.

Opcionalmente, si la opción --list devuelve un elemento de nivel superior


denominado _meta, es posible devolver todas las variables de host en una llamada
de script, que mejora el rendimiento del script. En ese caso, no se realizan llamadas
--host.

Consulte Desarrollo de fuentes de inventario dinámico [http://docs.ansible.com/


ansible/developing_inventory.html] para obtener más información.

Administración de múltiples inventarios


Ansible admite el uso de varios inventarios en la misma ejecución. Si la ubicación del inventario
es un directorio (ya sea establecido por la opción -i, el valor del parámetro inventory o de
alguna otra forma), todos los archivos de inventario incluidos en el directorio, ya sean estáticos o
dinámicos, se combinan para determinar el inventario. Los archivos ejecutables en ese directorio
se usan para recuperar inventarios dinámicos, y los otros archivos se usan como inventarios
estáticos.

Los archivos de inventario no dependen de otros archivos o scripts de inventario para resolverse.
Por ejemplo, si un archivo de inventario estático especifica que un grupo en particular debe ser
un elemento secundario de otro grupo, también debe tener una entrada de marcador de posición
para dicho grupo, aunque todos los miembros de ese grupo provengan del inventario dinámico.
Considere el grupo cloud-east en el siguiente ejemplo:

[cloud-east]

[servers]
test.demo.example.com

[servers:children]
cloud-east

Esto garantiza que sin importar el orden en que se analizan los archivos de inventario, todos ellos
son internamente consistentes.

nota
En la documentación no se especifica el orden en que se analizan los archivos de
inventario. Actualmente, cuando existen múltiples archivos de inventario, se los
analiza en orden alfabético. Si una fuente de inventario depende de la información
de otra fuente de inventario, entonces el orden en que se cargan puede determinar
si el archivo de inventario funciona como se espera o arroja un error. Por lo tanto,
es importante asegurarse de que todos los archivos sean coherentes para evitar
errores inesperados.

Ansible ignora archivos en un directorio de inventario si finalizan con determinados sufijos.


Esto puede controlarse con la directiva inventory_ignore_extensions en el archivo de
configuración de Ansible. Existe más información disponible en la documentación de Ansible.

RH294-RHEL8.0-es-1-20200501 255
capítulo 7 | Administración de proyectos grandes

Referencias
Trabajo con inventario dinámico: Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html

Desarrollo de inventario dinámico: Documentación Ansible


https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html

256 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Ejercicio Guiado

Administración de inventarios dinámicos


En este ejercicio, instalará scripts personalizados que generan dinámicamente una lista de
hosts de inventario.

Resultados
Usted podrá instalar y usar scripts de inventario dinámico existentes.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-inventory start. Verifica que


Ansible esté instalado en workstation y, además, crea el directorio de trabajo /home/
student/projects-inventory para este ejercicio.

[student@workstation ~]$ lab projects-inventory start

1. En workstation, cambie al directorio de trabajo para este ejercicio, /home/student/


projects-inventory. Vea el contenido del archivo de configuración Ansible
ansible.cfg. El archivo de configuración establece la ubicación del inventario en
inventory.

[defaults]
inventory = inventory

2. Cree el directorio /home/student/projects-inventory/inventory.

[student@workstation projects-inventory]$ mkdir inventory

3. De http://materials.example.com/labs/projects-inventory/, descargue los


archivos inventorya.py, inventoryw.py y hosts en su directorio /home/student/
projects-inventory/inventory. Los dos archivos que terminan en .py son scripts
que generan inventarios dinámicos; el tercer archivo es un inventario estático.

• El script inventorya.py proporciona el grupo webservers, que incluye el host


servera.lab.example.com.

• El script inventoryw.py proporciona el host workstation.lab.example.com.

• El archivo de inventario estático hosts define el grupo servers, que es un grupo


principal del grupo webservers.

[student@workstation projects-inventory]$ wget \


> http://materials.example.com/labs/projects-inventory/inventorya.py \
> -O inventory/inventorya.py

RH294-RHEL8.0-es-1-20200501 257
capítulo 7 | Administración de proyectos grandes

[student@workstation projects-inventory]$ wget \


> http://materials.example.com/labs/projects-inventory/inventoryw.py \
> -O inventory/inventoryw.py
[student@workstation projects-inventory]$ wget \
> http://materials.example.com/labs/projects-inventory/hosts \
> -O inventory/hosts

4. Mediante el comando ansible con el script inventorya.py como inventario, enumere


los hosts administrados que se asocian con el grupo webservers. Se produce un error en
relación con los permisos de inventorya.py.

[student@workstation projects-inventory]$ ansible -i inventory/inventorya.py \


> webservers --list-hosts
[WARNING]: * Failed to parse /home/student/projects-inventory/inventory/
inventorya.py with script plugin: problem running /home/student/projects-
inventory/inventory/inventorya.py --list ([Errno 13] Permission denied)

[WARNING]: * Failed to parse /home/student/projects-inventory/inventory/


inventorya.py with ini plugin: /home/student/projects-inventory/inventory/
inventorya.py:3: Expected key=value host variable assignment, got: subprocess

[WARNING]: Unable to parse /home/student/projects-inventory/inventory/


inventorya.py as an inventory source

[WARNING]: No inventory was parsed, only implicit localhost is available

[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

[WARNING]: Could not match supplied host pattern, ignoring: webservers

hosts (0):

5. Verifique los permisos actuales para el script inventorya.py y cámbielos a 755.

[student@workstation projects-inventory]$ ls -la inventory/inventorya.py


-rw-rw-r--. 1 student student 639 Apr 29 14:20 inventory/inventorya.py
[student@workstation projects-inventory]$ chmod 755 inventory/inventorya.py

6. Cambie los permisos para el script inventoryw.py a 755.

[student@workstation projects-inventory]$ chmod 755 inventory/inventoryw.py

7. Verifique la salida actual para el script inventorya.py utilizando el parámetro --list.


Se muestran los hosts asociados con el grupo webservers.

[student@workstation projects-inventory]$ inventory/inventorya.py --list


{"webservers": {"hosts": ["servera.lab.example.com"], "vars": { }}}

258 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

8. Verifique la salida actual para el script inventoryw.py utilizando el parámetro --list.


Se muestra el host workstation.lab.example.com.

[student@workstation projects-inventory]$ inventory/inventoryw.py --list


{"all": {"hosts": ["workstation.lab.example.com"], "vars": { }}}

9. Verifique la definición del grupo servers en el archivo /home/student/projects-


inventory/inventory/hosts. El grupo webservers definido en el inventario
dinámico se configura como secundario del grupo servers.

[student@workstation projects-inventory]$ cat inventory/hosts


[servers:children]
webservers

10. Ejecute el siguiente comando para verificar la lista de hosts en el grupo webservers. Se
produce un error porque el grupo webservers no está definido.

[student@workstation projects-inventory]$ ansible webservers --list-hosts


[WARNING]: * Failed to parse /home/student/projects-inventory/inventory/hosts
with yaml plugin: Syntax Error while loading YAML. found unexpected ':' The
error appears to have been in '/home/student/projects-inventory/inventory/hosts':
line 1, column 9, but may be elsewhere in the file depending on the exact syntax
problem. The offending line appears to be: [servers:children] ^ here

[WARNING]: * Failed to parse /home/student/projects-inventory/inventory/hosts


with ini plugin: /home/student/projects-inventory/inventory/hosts:2: Section
[servers:children] includes undefined group: webservers

[WARNING]: Unable to parse /home/student/projects-inventory/inventory/hosts as an


inventory source

hosts (1):
servera.lab.example.com

11. Para evitar este problema, el inventario estático debe tener una entrada de marcador de
posición que define un grupo de hosts webservers vacío. Es importante que el inventario

RH294-RHEL8.0-es-1-20200501 259
capítulo 7 | Administración de proyectos grandes

estático defina el grupo de hosts al cual hace referencia, dado que es posible que pueda
desaparecer dinámicamente de la fuente externa, lo que podría provocar este error.
Edite el archivo /home/student/projects-inventory/inventory/hosts para que
incluya el siguiente contenido:

[webservers]

[servers:children]
webservers

Importante
Si el script de inventario dinámico que proporciona el grupo de hosts lleva un
nombre que hace que quede ordenado antes del inventario estático que hace
referencia a este, entonces no verá este error. Sin embargo, si en algún momento el
grupo de hosts desaparece del inventario dinámico, y usted no tiene un marcador
de posición, el inventario estático estará haciendo referencia a un grupo de hosts
faltante y el error interrumpirá el análisis del inventario.

12. Vuelva a ejecutar el siguiente comando para verificar la lista de hosts en el grupo
webservers. Debe funcionar sin errores.

[student@workstation projects-inventory]$ ansible webservers --list-hosts


hosts (1):
servera.lab.example.com

Finalizar
En workstation, ejecute el comando lab projects-inventory finish para limpiar este
ejercicio.

[student@workstation ~]$ lab projects-inventory finish

Esto concluye el ejercicio guiado.

260 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Configuración del paralelismo

Objetivos
Después de finalizar esta sección, deberá ser capaz de ajustar la cantidad de conexiones
simultáneas que Ansible abre a los hosts administrados, así como la manera en que Ansible
procesa grupos de hosts administrados a través de las tareas de la reproducción.

Configurar el paralelismo en Ansible usando


bifurcaciones
Cuando Ansible procesa una guía, ejecuta cada reproducción en orden. Una vez que ha
determinado la lista de hosts para la reproducción, Ansible ejecuta cada tarea en orden.
Normalmente, todos los hosts deben completar una tarea con éxito antes de que cualquier host
inicie la siguiente tarea en la reproducción.

En teoría, Ansible podría conectarse simultáneamente a todos los hosts en la reproducción para
cada tarea. Esto funciona bien para pequeñas listas de hosts. Sin embargo, si la reproducción se
dirige a cientos de hosts, esto puede suponer una gran carga para el nodo de control.

El número máximo de conexiones simultáneas que Ansible hace es controlado por el parámetro
forks en el archivo de configuración Ansible. Se establece en 5 de forma predeterminada, lo que
puede verificarse con uno de los siguientes.

[student@demo ~]$ grep forks ansible.cfg


forks = 5

[student@demo ~]$ ansible-config dump |grep -i forks


DEFAULT_FORKS(default) = 5

[student@demo ~]$ ansible-config list |grep -i forks


DEFAULT_FORKS:
description: Maximum number of forks Ansible will use to execute tasks on target
- {name: ANSIBLE_FORKS}
- {key: forks, section: defaults}
name: Number of task forks

Por ejemplo, suponga que un nodo de control de Ansible está configurado con el valor
predeterminado de cinco bifurcaciones y la reproducción tiene diez hosts administrados. Ansible
ejecutará la primera tarea en la reproducción en los primeros cinco hosts administrados, seguido
de una segunda ronda de ejecución de la primera tarea en los otros cinco hosts administrados.
Después de que la primera tarea se haya ejecutado en todos los hosts administrados, Ansible
procederá a ejecutar la siguiente tarea en todos los hosts administrados en grupos de cinco hosts
a la vez. Ansible hará esto con cada tarea por turno hasta que la reproducción termine.

El valor predeterminado para forks va a ser muy conservador. Si su nodo de control está
administrando hosts de Linux, la mayoría de las tareas se ejecutarán en los hosts administrados y

RH294-RHEL8.0-es-1-20200501 261
capítulo 7 | Administración de proyectos grandes

el nodo de control tendrá menos carga. En este caso, normalmente se puede configurar forks a
un valor mucho más alto, posiblemente más cercano a 100, y ver mejoras en el rendimiento.

Si sus guías ejecutan una gran cantidad de código en el nodo de control, entonces deberá
aumentar el límite de la bifurcación con sensatez. Si usa Ansible para administrar enrutadores
y switches de red, entonces la mayoría de esos módulos se ejecutan en el nodo de control y no
en el dispositivo de red. Debido a la mayor carga que esto impone sobre el nodo de control, su
capacidad para soportar aumentos en el número de bifurcaciones será significativamente menor
que para un nodo de control que solo administre hosts Linux.

Puede anular la configuración predeterminada de forks desde la línea de comandos en el archivo


de configuración de Ansible. Tanto el comando ansible como el ansible-playbook ofrecen
las opciones -f o --forks para especificar el número de horquillas que se usará.

Gestión de actualizaciones continuas


Normalmente, cuando Ansible ejecuta una reproducción, se asegura de que todos los hosts
administrados hayan completado cada tarea antes de iniciar cualquier host en la siguiente tarea.
Una vez que todos los hosts administrados han completado todas las tareas, se ejecutan todos los
controladores notificados.

Sin embargo, ejecutar todas las tareas en todos los hosts puede provocar un comportamiento
no deseado. Por ejemplo, si la reproducción actualiza un grupo de servidores web con carga
balanceada, es posible que tenga que poner fuera de servicio cada servidor web mientras se
realiza la actualización. Si todos los servidores se actualizan en la misma reproducción, todos
podrían estar fuera de servicio al mismo tiempo.

Una forma de evitar este problema es usar la palabra clave serial para ejecutar los hosts a través
de la reproducción en lotes. Cada lote de hosts se ejecutará durante toda la reproducción antes de
que se inicie el siguiente lote.

En el siguiente ejemplo, Ansible ejecuta la reproducción en dos hosts administrados a la vez,


hasta que todos los hosts administrados se hayan actualizado. Ansible comienza ejecutando
las tareas en la reproducción en los dos primeros hosts administrados. Si alguno o ambos hosts
notificaron al controlador, entonces Ansible ejecuta el controlador según sea necesario para estos
dos hosts. Cuando se completa la ejecución de la reproducción en estos dos hosts administrados,
Ansible repite el proceso en los siguientes dos hosts administrados. Ansible continúa ejecutando la
reproducción de esta manera hasta que todos los hosts administrados se hayan actualizado.

---
- name: Rolling update
hosts: webservers
serial: 2
tasks:
- name: latest apache httpd package is installed
yum:
name: httpd
state: latest
notify: restart apache

handlers:
- name: restart apache
service:
name: httpd
state: restarted

262 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Supongamos que el grupo webservers del ejemplo anterior contiene cinco servidores web
que residen detrás de un equilibrador de carga. Con el parámetro serial establecido en 2,
la reproducción ejecutará hasta dos servidores web a la vez. Por ende, la mayoría de los cinco
servidores web estarán siempre disponibles.

Por el contrario, en ausencia de la palabra clave serial, la ejecución de la reproducción y, por lo


tanto, la ejecución del controlador se produciría en los cinco servidores web al mismo tiempo. Esto
probablemente conduciría a una interrupción del servicio, ya que los servicios web en todos los
servidores web se reiniciarían al mismo tiempo.

Importante
Para ciertos propósitos, cada lote de hosts cuenta como si fuera una reproducción
completa ejecutándose en un subconjunto de hosts. Esto significa que si falla un
lote completo, la reproducción falla, lo que hace que la ejecución de la guía falle.

En el caso anterior con serial: 2 configurado, si algo está mal y la reproducción


falla para los dos primeros hosts procesados, la guía se cancelará y los tres hosts
restantes no se ejecutarán a través de la reproducción. Esta es una función útil
porque solo un subconjunto de los servidores no estará disponible, por lo que el
servicio quedará degradado, pero no inactivo.

La palabra clave serial también se puede especificar como un porcentaje. Este porcentaje
se aplica al número total de hosts en la reproducción para determinar el tamaño del lote de la
actualización sucesiva. Independientemente del porcentaje, el número de hosts por pase será
siempre 1 o mayor.

Referencias
Actualización continua del tamaño del lote — Delegación, Actualizaciones
continuas y Acciones locales — Documentación Ansible
http://docs.ansible.com/ansible/playbooks_delegation.html#rolling-update-batch-
size

Ajuste del rendimiento de Ansible (por entretenimiento y ganancia)


https://www.ansible.com/blog/ansible-performance-tuning

RH294-RHEL8.0-es-1-20200501 263
capítulo 7 | Administración de proyectos grandes

Ejercicio Guiado

Configuración del paralelismo


En este ejercicio, explorará los efectos de diferentes directivas de serie y bifurcaciones sobre
cómo procesa Ansible una reproducción.

Resultados
Podrá ajustar las ejecuciones paralelas y en serie de una guía en múltiples hosts
administrados.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-parallelism start. El


script verifica que Ansible esté instalado en workstation; luego, crea una estructura de
directorio y archivos asociados para el entorno del trabajo de laboratorio.

[student@workstation ~]$ lab projects-parallelism start

1. Cambie al directorio /home/student/projects-parallelism. Examine el contenido


del directorio del proyecto para familiarizarse con los archivos del proyecto.

1.1. Revise el contenido del archivo ansible.cfg. Tenga en cuenta que el archivo de
inventario se establece en inventory. Tenga en cuenta también que el parámetro
forks se establece en 4.

[defaults]
inventory=inventory
remote_user=devops
forks=4
...output omitted...

1.2. Revise el contenido del archivo inventory. Tenga en cuenta que contiene un grupo
de hosts, webservers, que contiene cuatro hosts.

[webservers]
servera.lab.example.com
serverb.lab.example.com
serverc.lab.example.com
serverd.lab.example.com

1.3. Examine el contenido del archivo playbook.yml. La guía se ejecuta en el grupo de


hosts webservers, garantiza que el último paquete httpd esté instalado y que el
servicio httpd esté habilitado y en funcionamiento.

264 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

---
- name: Update web server
hosts: webservers

tasks:
- name: Lastest httpd package installed
yum:
name: httpd
state: latest
notify:
- Restart httpd

handlers:
- name: Restart httpd
service:
name: httpd
enabled: yes
state: restarted

1.4. Por último, examine el contenido del archivo remove_apache.yml. La guía se


ejecuta en el grupo de hosts webservers, garantiza que el servicio httpd esté
deshabilitado y detenido; luego, garantiza que el paquete httpd no esté instalado.

---
- hosts: webservers
tasks:
- service:
name: httpd
enabled: no
state: stopped
- yum:
name: httpd
state: absent

2. Ejecute la guía playbook.yml, usando el comando time para determinar cuánto tarda
en ejecutarse la guía. Mire la guía mientras se ejecuta. Observe cómo Ansible realiza cada
tarea en los cuatro hosts al mismo tiempo.

[student@workstation projects-parallelism]$ time ansible-playbook playbook.yml


PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [servera.lab.example.com]
ok: [serverd.lab.example.com]
ok: [serverb.lab.example.com]
ok: [serverc.lab.example.com]

...output omitted...

RH294-RHEL8.0-es-1-20200501 265
capítulo 7 | Administración de proyectos grandes

real 0m22.701s
user 0m23.275s
sys 0m2.637s

3. Ejecute la guía remove_apache.yml para detener y deshabilitar el servicio httpd y para


eliminar el paquete httpd.

[student@workstation projects-parallelism]$ ansible-playbook remove_apache.yml

4. Cambie el valor del parámetro forks a 1 en ansible.cfg.

[defaults]
inventory=inventory
remote_user=devops
forks=1
...output omitted...

5. Vuelva a ejecutar la guía playbook.yml, usando el comando time para determinar


cuánto tarda en ejecutarse la guía. Mire la guía mientras se ejecuta. Observe que esta
vez Ansible realiza cada tarea en un host a la vez. También tenga en cuenta cómo la
disminución del número de bifurcaciones hizo que la ejecución de la guía durara más que
antes.

[student@workstation projects-parallelism]$ time ansible-playbook playbook.yml

PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
ok: [serverc.lab.example.com]
ok: [serverd.lab.example.com]

...output omitted...

real 0m37.853s
user 0m22.414s
sys 0m4.749s

6. Ejecute la guía remove_apache.yml para detener y deshabilitar el servicio httpd y para


eliminar el paquete httpd.

[student@workstation projects-parallelism]$ ansible-playbook remove_apache.yml

266 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

7. Establezca el valor del parámetro forks en 2 en ansible.cfg.

[defaults]
inventory=inventory
remote_user=devops
forks=2
...output omitted...

8. Agregue el siguiente parámetro serial a la reproducción en la guía playbook.yml para


que la reproducción solo se ejecute en dos hosts a la vez. El inicio de la guía debe mostrarse
de la siguiente manera:

---
- name: Update web server
hosts: webservers
serial: 2

9. Vuelva a ejecutar la guía playbook.yml. Mire la guía mientras se ejecuta. Observe cómo
Ansible ejecuta la reproducción completa en solo dos hosts antes de volver a ejecutar la
reproducción en los dos hosts restantes.

[student@workstation projects-parallelism]$ ansible-playbook playbook.yml

PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]

TASK [Latest version of apache installed] **********************************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]

...output omitted...

PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [serverc.lab.example.com]
ok: [serverd.lab.example.com]

TASK [Latest version of apache installed] **********************************


changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]

...output omitted...

10. Ejecute la guía remove_apache.yml para detener y deshabilitar el servicio httpd y para
eliminar el paquete httpd.

[student@workstation projects-parallelism]$ ansible-playbook remove_apache.yml

RH294-RHEL8.0-es-1-20200501 267
capítulo 7 | Administración de proyectos grandes

11. Establezca el valor del parámetro forks de nuevo en 4 en ansible.cfg.

[defaults]
inventory=inventory
remote_user=devops
forks=4
...output omitted...

12. Establezca el parámetro serial en la guía playbook.yml en 3. El inicio de la guía debe


mostrarse de la siguiente manera:

---
- name: Update web server
hosts: webservers
serial: 3

13. Vuelva a ejecutar la guía playbook.yml. Mire la guía mientras se ejecuta. Observe cómo
Ansible ejecuta la reproducción completa en solo tres hosts y, luego, vuelve a ejecutar la
reproducción en el host restante.

[student@workstation projects-parallelism]$ ansible-playbook playbook.yml

PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
ok: [serverc.lab.example.com]

TASK [Latest version of apache installed] **********************************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
changed: [serverc.lab.example.com]

...output omitted...

PLAY [Update apache] *******************************************************

TASK [Gathering Facts] *****************************************************


ok: [serverd.lab.example.com]

TASK [Latest version of apache installed] **********************************


changed: [serverd.lab.example.com]

...output omitted...

Finalizar
En workstation, ejecute el comando lab projects-parallelism finish para limpiar
este ejercicio.

[student@workstation ~]$ lab projects-parallelism finish

268 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 269
capítulo 7 | Administración de proyectos grandes

Inclusión e importación de archivos

Objetivos
Tras finalizar esta sección, podrá administrar guías grandes importando o incluyendo otros guías o
tareas desde archivos externos, ya sea sin condiciones o sobre la base de una prueba condicional.

Gestión de guías grandes


Cuando una guía se torna larga o compleja, puede dividirla en archivos más pequeños para
que sea más fácil de administrar. Puede combinar varias guías en una guía principal de manera
modular, o insertar listas de tareas de un archivo a una reproducción. Esto puede facilitar la
reutilización de reproducciones o secuencias de tareas en diferentes proyectos.

Inclusión o importación de archivos


Existen dos operaciones que Ansible puede realizar para incorporar contenido en una guía. Usted
puede incluir contenido, o puede importar contenido.

Cuando incluye contenido, es una operación dinámica. Los procesos de Ansible incluyeron
contenido durante la ejecución de la guía, a medida que se abordaba el contenido.

Cuando importa contenido, es una operación estática. Los preprocesos de Ansible importaron
contenido cuando se analizó inicialmente la guía, antes de que comience la ejecución.

Importación de guías
La palabra clave import_playbook le permite importar archivos externos que contienen listas
de reproducciones en una guía. En otras palabras, puede tener una guía maestra que importa una
o más guías adicionales.

Debido a que el contenido que se importa es una guía completa, la función import_playbook
solo se puede usar en el nivel superior de una guía y no se puede usar dentro de una reproducción.
Si importa varias guías, se importarán y ejecutarán en orden.

A continuación se muestra un ejemplo simple de una guía maestra que importa dos guías
adicionales:

- name: Prepare the web server


import_playbook: web.yml

- name: Prepare the database server


import_playbook: db.yml

También puede intercalar reproducciones en la guía maestra con guías importadas.

270 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

- name: Play 1
hosts: localhost
tasks:
- debug:
msg: Play 1

- name: Import Playbook


import_playbook: play2.yml

En el ejemplo anterior, la Reproducción 1 se ejecuta primero y, luego, las reproducciones


importadas de la guía play2.yml.

Importación e inclusión de tareas


Puede importar o incluir una lista de tareas de un archivo de tareas a una reproducción. Un archivo
de tareas es un archivo que contiene una lista plana de tareas:

[admin@node ~]$ cat webserver_tasks.yml


- name: Installs the httpd package
yum:
name: httpd
state: latest

- name: Starts the httpd service


service:
name: httpd
state: started

Importación de archivos de tareas


Puede importar de forma estática un archivo de tareas en una reproducción dentro de una guía
usando la función import_tasks. Cuando importa un archivo de tareas, las tareas de ese archivo
se insertan directamente cuando se analiza la guía. La ubicación de import_tasks en los
controles de la guía donde se insertan las tareas y el orden en que se ejecutan las importaciones
múltiples.

---
- name: Install web server
hosts: webservers
tasks:
- import_tasks: webserver_tasks.yml

Cuando importa un archivo de tareas, las tareas de ese archivo se insertan directamente cuando
se analiza la guía. Debido a que import_tasks importa de forma estática las tareas cuando se
analiza la guía, hay algunos efectos sobre cómo funciona.

• Al usar la función import_tasks, las declaraciones condicionales establecidas en la


importación, como when, se aplican a cada una de las tareas que se importan.

• No se puede usar bucles con la función import_tasks.

• Si usa una variable para especificar el nombre del archivo por importar, no puede usar una
variable de inventario de host o grupo.

RH294-RHEL8.0-es-1-20200501 271
capítulo 7 | Administración de proyectos grandes

Inclusión de archivos de tareas


También puede incluir de forma dinámica un archivo de tarea en una reproducción dentro de la
guía usando la función include_tasks.

---
- name: Install web server
hosts: webservers
tasks:
- include_tasks: webserver_tasks.yml

La función include_tasks no procesa el contenido en la guía hasta que se ejecuta la


reproducción y se alcanza esa parte de esta. El orden en el que se procesa el contenido de la guía
afecta el funcionamiento de la función de incluir tareas.

• Al usar la función include_tasks, las declaraciones condicionales, como when, establecidas


determinan si las tareas están incluidas en la reproducción.

• Si ejecuta ansible-playbook --list-tasks para enumerar las tareas de la guía, no se


muestran las tareas en los archivos de tareas incluidos. Se muestran las tareas que incluyen
los archivos de tareas. En comparación, la función import_tasks no enumera las tareas que
importan archivos de tareas, sino las tareas individuales de los archivos de tareas importados.

• No puede usar ansible-playbook --start-at-task para iniciar la ejecución de la guía


desde una tarea que se encuentra en un archivo de tareas incluido.

• No puede usar una declaración notify para desencadenar un nombre de controlador que
se encuentra en un archivo de tarea incluido. Puede desencadenar un controlador en la guía
principal que incluye un archivo de tareas completo, en cuyo caso se ejecutarán todas las tareas
en el archivo incluido.

nota
Puede encontrar un análisis más detallado de las diferencias de comportamiento
entre import_tasks e include_tasks cuando se usan condicionales
en "Condicionales" [https://docs.ansible.com/ansible/latest/user_guide/
playbooks_conditionals.html#applying-when-to-roles-imports-and-includes] en la
Guía del usuario Ansible.

Casos de uso para archivos de tareas


Considere los siguientes ejemplos en los que puede ser útil gestionar conjuntos de tareas como
archivos externos separados de la guía:

• Si los servidores nuevos requieren una configuración completa, los administradores pueden
crear diferentes conjuntos de tareas para crear usuarios, instalar paquetes, configurar servicios,
configurar privilegios, configurar el acceso a un sistema de archivos compartido, reforzar los
servidores, instalar actualizaciones de seguridad e instalar un agente de monitoreo. Cada uno
de estos conjuntos de tareas se puede administrar a través de un archivo autónomo de tareas
separado.

• Si los desarrolladores, administradores de sistema y administradores de bases de datos


gestionan los servidores de manera colectiva, cada organización puede programar su propio
archivo de tareas que el administrador de sistemas luego puede revisar e integrar.

272 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

• Si un servidor requiere una configuración en particular, se la puede integrar como un conjunto


de tareas ejecutado en función de un condicional. En otras palabras, las tareas se incluyen solo si
se cumplen criterios específicos.

• Si un grupo de servidores tiene que ejecutar una tarea o un conjunto de tareas en particular, las
tareas solo se pueden ejecutar en un servidor si este es parte de un grupo específico de hosts.

Administrar archivos de tareas


Usted puede crear un directorio dedicado para archivos de tareas, y guardar todos los archivos de
tareas en ese directorio. Su guía puede simplemente incluir o importar archivos de tareas de ese
directorio. Esto permite la construcción de una guía compleja, al tiempo que facilita la gestión de
su estructura y sus componentes.

Definición de variables para reproducciones y tareas


externas
La incorporación de reproducciones o tareas de archivos externos a las guías con las funciones
de importación e inclusión de Ansible mejora enormemente la capacidad de reutilizar tareas y
guías en un entorno de Ansible. Para maximizar la posibilidad de reutilización, estos archivos de
tareas y reproducciones deben ser tan genéricos como sea posible. Las variables se pueden
usar para parametrizar elementos de reproducciones y tareas a fin de expandir la aplicación de
reproducciones y tareas.

Por ejemplo, el siguiente archivo de tareas instala el paquete necesario para un servicio web y,
luego, habilita e inicia el servicio requerido.

---
- name: Install the httpd package
yum:
name: httpd
state: latest
- name: Start the httpd service
service:
name: httpd
enabled: true
state: started

Si parametriza el paquete y los elementos de servicio como se muestra en el siguiente ejemplo, el


archivo de tareas también se puede usar para la instalación y administración de otro software y sus
servicios, en lugar de ser útil solo para el servicio web.

---
- name: Install the {{ package }} package
yum:
name: "{{ package }}"
state: latest
- name: Start the {{ service }} service
service:
name: "{{ service }}"
enabled: true
state: started

RH294-RHEL8.0-es-1-20200501 273
capítulo 7 | Administración de proyectos grandes

Posteriormente, al incorporar el archivo de tareas en una guía, defina las variables que se usarán
para la ejecución de la tarea de la siguiente manera:

...output omitted...
tasks:
- name: Import task file and set variables
import_tasks: task.yml
vars:
package: httpd
service: service

Ansible hace que las variables transferidas estén disponibles para las tareas importadas desde el
archivo externo.

Puede usar la misma técnica para hacer que los archivos de reproducción sean más reutilizables. Al
incorporar un archivo de reproducción en una guía, se transfieren las variables que se usarán para
la ejecución de la reproducción de la siguiente manera:

...output omitted...
- name: Import play file and set the variable
import_playbook: play.yml
vars:
package: mariadb

Importante
Las versiones anteriores de Ansible usaban una función include para incluir guías
y archivos de tareas, según el contexto. Esta función está en desuso por varios
motivos.

Antes de Ansible 2.0, include operaba como una importación estática. En


Ansible 2.0, se cambió para que funcione dinámicamente, pero esto causó ciertas
limitaciones. En Ansible 2.1, se hizo posible que include sea dinámico o estático
dependiendo de la configuración de la tarea, lo que era confuso y causaba errores.
También hubo problemas para asegurar que include funcionase correctamente en
todos los contextos.

Por esto, include fue reemplazado en Ansible 2.4 con nuevas directivas, como
include_tasks, import_tasks e import_playbook. Podría encontrar
ejemplos de include en guías más antiguas, pero debe evitar usarlo en otras más
nuevas.

Referencias
Inclusión e importación & mdash; Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_includes.html

Creando guías reutilizables & mdash; Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html

Condicionales — Documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html

274 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Ejercicio Guiado

Inclusión e importación de archivos


En este ejercicio, incluirá e importará guías y tareas en una Guía Ansible de máximo nivel.

Resultados
Será capaz de incluir archivos de guías y tareas en las guías.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-file start. El script crea el


directorio de trabajo, /home/student/projects-file, y los archivos de proyecto
asociados.

[student@workstation ~]$ lab projects-file start

1. En workstation, con el usuario student, cambie al directorio /home/student/


projects-file.

[student@workstation ~]$ cd ~/projects-file


[student@workstation projects-file]$

2. Revise el contenido de los tres archivos en el subdirectorio tasks.

2.1. Revise el contenido del archivo tasks/environment.yml. El archivo contiene


tareas para la instalación de paquetes y la administración del servicio.

[student@workstation projects-file]$ cat tasks/environment.yml


---
- name: Install the {{ package }} package
yum:
name: "{{ package }}"
state: latest
- name: Start the {{ service }} service
service:
name: "{{ service }}"
enabled: true
state: started

2.2. Revise el contenido del archivo tasks/firewall.yml. El archivo contiene tareas


para la instalación, administración y configuración del software de firewall.

[student@workstation projects-file]$ cat tasks/firewall.yml


---
- name: Install the firewall

RH294-RHEL8.0-es-1-20200501 275
capítulo 7 | Administración de proyectos grandes

yum:
name: "{{ firewall_pkg }}"
state: latest

- name: Start the firewall


service:
name: "{{ firewall_svc }}"
enabled: true
state: started

- name: Open the port for {{ rule }}


firewalld:
service: "{{ item }}"
immediate: true
permanent: true
state: enabled
loop: "{{ rule }}"

2.3. Revise el contenido del archivo tasks/placeholder.yml. Este archivo contiene


una tarea para completar un archivo de contenido web de marcador de posición.

[student@workstation projects-file]$ cat tasks/placeholder.yml


---
- name: Create placeholder file
copy:
content: "{{ ansible_facts['fqdn'] }} has been customized using Ansible.\n"
dest: "{{ file }}"

3. Revise el contenido del archivo test.yml en el subdirectorio plays. Este archivo contiene
una reproducción que prueba las conexiones a un servicio web.

---
- name: Test web service
hosts: localhost
become: no
tasks:
- name: connect to internet web server
uri:
url: "{{ url }}"
status_code: 200

4. Cree una guía denominada playbook.yml. Defina la primera reproducción con el


nombre Configure web server (Configurar servidor web). La reproducción debe
ejecutarse contra el host administrado servera.lab.example.com definido en el
archivo inventory. El comienzo del archivo debe verse así:

---
- name: Configure web server
hosts: servera.lab.example.com

5. En la guía playbook.yml, defina la sección de tareas con tres conjuntos de tareas.


Incluya el primer conjunto de tareas del archivo de tareas tasks/environment.yml.

276 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Defina las variables necesarias para instalar el paquete httpd y para habilitar e iniciar el
servicio httpd. Importe el segundo conjunto de tareas del archivo de tareas tasks/
firewall.yml. Defina las variables necesarias para instalar el paquete firewalld a fin de
habilitar e iniciar el servicio firewalld, y permitir las conexiones http. Importe el tercer
conjunto de tareas desde el archivo de tareas tasks/placeholder.yml.

5.1. Cree la sección de tareas en la primera reproducción agregando la siguiente entrada a


la guía playbook.yml.

tasks:

5.2. Importe el primer conjunto de tareas desde tasks/environment.yml con la


función import_tasks. Establezca las variables package y service en httpd.
Establezca la variable svc_state en started.

- name: Include the environment task file and set the variables
include_tasks: tasks/environment.yml
vars:
package: httpd
service: httpd
when: ansible_facts['os_family'] == 'RedHat'

5.3. Importe el segundo conjunto de tareas desde tasks/firewall.yml con la función


import_tasks. Establezca las variables firewall_pkg y firewall_svc en
firewalld. Establezca la variable rule en http.

- name: Import the firewall task file and set the variables
import_tasks: tasks/firewall.yml
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
rule:
- http
- https

5.4. Importe el último conjunto de tareas desde tasks/placeholder.yml con


la función import_tasks. Establezca la variable file en /var/www/html/
index.html.

- name: Import the placeholder task file and set the variable
import_tasks: tasks/placeholder.yml
vars:
file: /var/www/html/index.html

6. Agregue una segunda y última reproducción a la guía playbook.yml usando el contenido


de la guía plays/test.yml.

6.1. Agregue una segunda reproducción a la guía playbook.yml para validar la


instalación del servidor web. Importe la reproducción desde plays/test.yml.
Establezca la variable url en http://servera.lab.example.com.

RH294-RHEL8.0-es-1-20200501 277
capítulo 7 | Administración de proyectos grandes

- name: Import test play file and set the variable


import_playbook: plays/test.yml
vars:
url: 'http://servera.lab.example.com'

6.2. La guía deberá verse de la siguiente manera después de que se completen los
cambios:

---
- name: Configure web server
hosts: servera.lab.example.com

tasks:
- name: Include the environment task file and set the variables
include_tasks: tasks/environment.yml
vars:
package: httpd
service: httpd
when: ansible_facts['os_family'] == 'RedHat'

- name: Import the firewall task file and set the variables
import_tasks: tasks/firewall.yml
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
rule:
- http
- https

- name: Import the placeholder task file and set the variable
import_tasks: tasks/placeholder.yml
vars:
file: /var/www/html/index.html

- name: Import test play file and set the variable


import_playbook: plays/test.yml
vars:
url: 'http://servera.lab.example.com'

6.3. Guarde los cambios en la guía playbook.yml.

7. Antes de ejecutar la guía, ejecute ansible-playbook --syntax-check para verificar


que la sintaxis sea correcta. Si informa errores, corríjalos antes de continuar con el siguiente
paso.

[student@workstation projects-file]$ ansible-playbook playbook.yml --syntax-check

playbook: playbook.yml

8. Ejecute la guía playbook.yml. En la salida de la guía, se muestran la importación de la


tarea y los archivos de reproducción.

278 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

[student@workstation projects-file]$ ansible-playbook playbook.yml

PLAY [Configure web server] ***********************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Install the httpd package] ******************************************


changed: [servera.lab.example.com]

TASK [Start the httpd service] ********************************************


changed: [servera.lab.example.com]

TASK [Install the firewall] ***********************************************


ok: [servera.lab.example.com]

TASK [Start the firewall] *************************************************


ok: [servera.lab.example.com]

TASK [Open the port for http] *********************************************


changed: [servera.lab.example.com]

TASK [Create placeholder file] ********************************************


changed: [servera.lab.example.com]

PLAY [Test web service] ***************************************************

TASK [Gathering Facts] ****************************************************


ok: [localhost]

TASK [connect to internet web server] *************************************


ok: [localhost]

PLAY RECAP ****************************************************************


localhost : ok=2 changed=0 unreachable=0 failed=0
servera.lab.example.com : ok=8 changed=4 unreachable=0 failed=0

Finalizar
En workstation, ejecute el script lab projects-file finish para limpiar este ejercicio.

[student@workstation ~]$ lab projects-file finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 279
capítulo 7 | Administración de proyectos grandes

Trabajo de laboratorio

Administración de proyectos grandes


Lista de verificación de rendimiento
En este trabajo de laboratorio, modificará una guía grande para que sea más fácil de
administrar mediante el uso de patrones de host, inclusiones, importaciones y un inventario
dinámico. También ajustará la manera en que Ansible procesa la guía.

Resultados
Puede simplificar las referencias de host administradas en una guía especificando patrones
de host frente a un inventario dinámico. También debe ser capaz de reestructurar una guía
para que las tareas se importen desde archivos de tareas externos y ajustar la guía para
actualizaciones continuas.

Instrucciones
Ha heredado una guía del administrador anterior. La guía se usa para configurar el
servicio web en servera.lab.example.com, serverb.lab.example.com,
serverc.lab.example.com y serverd.lab.example.com. En la guía, también se
configura el firewall en los cuatro hosts administrados para permitir el tráfico web.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-review start. El script de


configuración garantiza que se pueda acceder a los hosts administrados en la red. También
garantiza que el archivo de configuración, el inventario Ansible y la guía correctos estén
instalados en el nodo de control.

[student@workstation ~]$ lab projects-review start

Realice los siguientes cambios en el archivo de la guía playbook.yml para que sea más fácil de
administrar y ajústelo para que las ejecuciones futuras usen actualizaciones continuas a fin de
evitar que los cuatro servidores web estén no disponibles al mismo tiempo.
1. Simplifique la lista de hosts administrados en la guía usando un patrón de host comodín. Use
el script de inventario dinámico inventory/inventory.py para verificar el patrón de host
comodín.
2. Reestructure la guía para que las tres primeras tareas de la guía se guarden en un archivo de
tareas externo ubicado en tasks/web_tasks.yml. Use la función import_tasks para
incorporar este archivo de tareas en la guía.
3. Reestructure la guía para que la cuarta, quinta y sexta tareas en la guía se guarden en un
archivo de tareas externo ubicado en tasks/firewall_tasks.yml. Use la característica
import_tasks para incorporar este archivo de tareas en la guía.
4. Hay algunas tareas duplicadas entre los archivos tasks/web_tasks.yml y tasks/
firewall_tasks.yml. Mueva las tareas que instalan paquetes y habilitan servicios a un
archivo nuevo llamado tasks/install_and_enable.yml y actualícelos para que usen

280 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

variables. Reemplace las tareas originales con declaraciones de import_tasks, pasando


valores apropiados de variables.
5. Debido a que el controlador para reiniciar el servicio httpd podría desencadenarse si hay
cambios futuros en el archivo files/tune.conf, implemente la función de actualización
periódica en la guía playbook.yml y establezca el tamaño del lote de actualización
periódica en dos hosts.
6. Verifique que los cambios en la guía playbook.yml se hayan hecho correctamente y, luego,
ejecute la guía.

Evaluación
En workstation, ejecute el comando lab projects-review grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab projects-review grade

Finalizar
En workstation, ejecute el script lab projects-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab projects-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 281
capítulo 7 | Administración de proyectos grandes

Solución

Administración de proyectos grandes


Lista de verificación de rendimiento
En este trabajo de laboratorio, modificará una guía grande para que sea más fácil de
administrar mediante el uso de patrones de host, inclusiones, importaciones y un inventario
dinámico. También ajustará la manera en que Ansible procesa la guía.

Resultados
Puede simplificar las referencias de host administradas en una guía especificando patrones
de host frente a un inventario dinámico. También debe ser capaz de reestructurar una guía
para que las tareas se importen desde archivos de tareas externos y ajustar la guía para
actualizaciones continuas.

Instrucciones
Ha heredado una guía del administrador anterior. La guía se usa para configurar el
servicio web en servera.lab.example.com, serverb.lab.example.com,
serverc.lab.example.com y serverd.lab.example.com. En la guía, también se
configura el firewall en los cuatro hosts administrados para permitir el tráfico web.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab projects-review start. El script de


configuración garantiza que se pueda acceder a los hosts administrados en la red. También
garantiza que el archivo de configuración, el inventario Ansible y la guía correctos estén
instalados en el nodo de control.

[student@workstation ~]$ lab projects-review start

Realice los siguientes cambios en el archivo de la guía playbook.yml para que sea más fácil de
administrar y ajústelo para que las ejecuciones futuras usen actualizaciones continuas a fin de
evitar que los cuatro servidores web estén no disponibles al mismo tiempo.
1. Simplifique la lista de hosts administrados en la guía usando un patrón de host comodín. Use
el script de inventario dinámico inventory/inventory.py para verificar el patrón de host
comodín.

1.1. Cambie el directorio al directorio de trabajo /home/student/projects-review.


Revise el archivo de configuración ansible.cfg para determinar la ubicación del
archivo de inventario. El inventario se define como el subdirectorio inventory y este
subdirectorio contiene un script de inventario dinámico inventory.py.

[student@workstation ~]$ cd ~/projects-review


[student@workstation projects-review]$ cat ansible.cfg
[defaults]
inventory = inventory

282 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

...output omitted...
[student@workstation projects-review]$ ll
total 16
-rw-rw-r--. 1 student student 33 Dec 19 00:48 ansible.cfg
drwxrwxr-x. 2 student student 4096 Dec 18 22:35 files
drwxrwxr-x. 2 student student 4096 Dec 19 01:18 inventory
-rw-rw-r--. 1 student student 959 Dec 18 23:48 playbook.yml
[student@workstation projects-review]$ ll inventory/
total 4
-rwxrwxr-x. 1 student student 612 Dec 19 01:18 inventory.py

1.2. Haga que el script de inventario dinámico inventory/inventory.py sea ejecutable;


luego, ejecute el script de inventario dinámico con la opción --list para mostrar la
lista completa de hosts en el inventario.

[student@workstation projects-review]$ chmod 755 inventory/inventory.py


[student@workstation projects-review]$ inventory/inventory.py --list
{"all": {"hosts": ["servera.lab.example.com", "serverb.lab.example.com",
"serverc.lab.example.com", "serverd.lab.example.com",
"workstation.lab.example.com"], "vars": { }}}

1.3. Verifique que el patrón del host server*.lab.example.com identifique


correctamente los cuatro hosts administrados que son el objetivo de la guía
playbook.yml.

[student@workstation projects-review]$ ansible server*.lab.example.com \


> --list-hosts
hosts (4):
serverb.lab.example.com
serverd.lab.example.com
servera.lab.example.com
serverc.lab.example.com

1.4. Reemplace la lista de hosts en la guía playbook.yml con el patrón de host


server*.lab.example.com.

---
- name: Install and configure web service
hosts: server*.lab.example.com
...output omitted...

2. Reestructure la guía para que las tres primeras tareas de la guía se guarden en un archivo de
tareas externo ubicado en tasks/web_tasks.yml. Use la función import_tasks para
incorporar este archivo de tareas en la guía.

2.1. Cree el subdirectorio tasks.

[student@workstation projects-review]$ mkdir tasks

2.2. Coloque el contenido de las tres primeras tareas en la guía playbook.yml dentro del
archivo tasks/web_tasks.yml. El archivo de tareas deberá incluir lo siguiente:

RH294-RHEL8.0-es-1-20200501 283
capítulo 7 | Administración de proyectos grandes

---
- name: Install httpd
yum:
name: httpd
state: latest

- name: Enable and start httpd


service:
name: httpd
enabled: true
state: started

- name: Tuning configuration installed


copy:
src: files/tune.conf
dest: /etc/httpd/conf.d/tune.conf
owner: root
group: root
mode: 0644
notify:
- restart httpd

2.3. Elimine las tres primeras tareas de la guía playbook.yml y coloque las siguientes
líneas en su lugar para importar el archivo de tareas tasks/web_tasks.yml.

- name: Import the web_tasks.yml task file


import_tasks: tasks/web_tasks.yml

3. Reestructure la guía para que la cuarta, quinta y sexta tareas en la guía se guarden en un
archivo de tareas externo ubicado en tasks/firewall_tasks.yml. Use la característica
import_tasks para incorporar este archivo de tareas en la guía.

3.1. Coloque el contenido de las tres tareas restantes en la guía playbook.yml dentro del
archivo tasks/firewall_tasks.yml. El archivo de tareas deberá incluir lo siguiente.

---
- name: Install firewalld
yum:
name: firewalld
state: latest

- name: Enable and start the firewall


service:
name: firewalld
enabled: true
state: started

- name: Open the port for http


firewalld:
service: http

284 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

immediate: true
permanent: true
state: enabled

3.2. Elimine las tres tareas restantes de la guía playbook.yml y coloque las siguientes
líneas en su lugar para importar el archivo de tareas tasks/firewall_tasks.yml.

- name: Import the firewall_tasks.yml task file


import_tasks: tasks/firewall_tasks.yml

4. Hay algunas tareas duplicadas entre los archivos tasks/web_tasks.yml y tasks/


firewall_tasks.yml. Mueva las tareas que instalan paquetes y habilitan servicios a un
archivo nuevo llamado tasks/install_and_enable.yml y actualícelos para que usen
variables. Reemplace las tareas originales con declaraciones de import_tasks, pasando
valores apropiados de variables.

4.1. Copie las tareas de yum y de servicio de tasks/web_tasks.yml en un archivo nuevo


llamado tasks/install_and_enable.yml.

---
- name: Install httpd
yum:
name: httpd
state: latest

- name: Enable and start httpd


service:
name: httpd
enabled: true
state: started

4.2. Reemplace los nombres del paquete y el servicio en tasks/


install_and_enable.yml con las variables package y service.

---
- name: Install {{ package }}
yum:
name: "{{ package }}"
state: latest

- name: Enable and start {{ service }}


service:
name: "{{ service }}"
enabled: true
state: started

4.3. Reemplace las tareas de yum y de servicio en tasks/web_tasks.yml y tasks/


firewall_tasks.yml con declaraciones de import_tasks.

RH294-RHEL8.0-es-1-20200501 285
capítulo 7 | Administración de proyectos grandes

---
- name: Install and start httpd
import_tasks: install_and_enable.yml
vars:
package: httpd
service: httpd

---
- name: Install and start firewalld
import_tasks: install_and_enable.yml
vars:
package: firewalld
service: firewalld

5. Debido a que el controlador para reiniciar el servicio httpd podría desencadenarse si hay
cambios futuros en el archivo files/tune.conf, implemente la función de actualización
periódica en la guía playbook.yml y establezca el tamaño del lote de actualización
periódica en dos hosts.

5.1. Agregue el parámetro serial a la guía playbook.yml.

---
- name: Install and configure web service
hosts: server*.lab.example.com
serial: 2
...output omitted...

6. Verifique que los cambios en la guía playbook.yml se hayan hecho correctamente y, luego,
ejecute la guía.

6.1. Verifique que la guía playbook.yml incluya el siguiente contenido.

---
- name: Install and configure web service
hosts: server*.lab.example.com
serial: 2

tasks:
- name: Import the web_tasks.yml task file
import_tasks: tasks/web_tasks.yml

- name: Import the firewall_tasks.yml task file


import_tasks: tasks/firewall_tasks.yml

handlers:
- name: restart httpd
service:
name: httpd
state: restarted

6.2. Ejecute la guía con ansible-playbook --syntax-check para verificar que la guía
no contiene errores de sintaxis. Si hay errores presentes, corríjalos antes de proceder.

286 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

[student@workstation projects-review]$ ansible-playbook playbook.yml \


> --syntax-check
playbook: playbook.yml

6.3. Ejecute la guía. La guía debe ejecutarse contra el host como una actualización
periódica con un tamaño de lote de dos hosts administrados.

[student@workstation projects-review]$ ansible-playbook playbook.yml

PLAY [Install and configure web service] ***********************************

TASK [Gathering Facts] *****************************************************


ok: [serverd.lab.example.com]
ok: [serverb.lab.example.com]

TASK [Install httpd] *******************************************************


changed: [serverd.lab.example.com]
changed: [serverb.lab.example.com]

TASK [Enable and start httpd] **********************************************


changed: [serverd.lab.example.com]
changed: [serverb.lab.example.com]

TASK [Tuning configuration installed] **************************************


changed: [serverb.lab.example.com]
changed: [serverd.lab.example.com]

TASK [Install firewalld] ***************************************************


ok: [serverb.lab.example.com]
ok: [serverd.lab.example.com]

TASK [Enable and start firewalld] ******************************************


ok: [serverd.lab.example.com]
ok: [serverb.lab.example.com]

TASK [Open the port for http] **********************************************


changed: [serverd.lab.example.com]
changed: [serverb.lab.example.com]

RUNNING HANDLER [restart httpd] ********************************************


changed: [serverb.lab.example.com]
changed: [serverd.lab.example.com]

PLAY [Install and configure web service] ***********************************

TASK [Gathering Facts] *****************************************************


ok: [serverc.lab.example.com]
ok: [servera.lab.example.com]

TASK [Install httpd] *******************************************************


changed: [serverc.lab.example.com]
changed: [servera.lab.example.com]

RH294-RHEL8.0-es-1-20200501 287
capítulo 7 | Administración de proyectos grandes

TASK [Enable and start httpd] **********************************************


changed: [serverc.lab.example.com]
changed: [servera.lab.example.com]

TASK [Tuning configuration installed] **************************************


changed: [servera.lab.example.com]
changed: [serverc.lab.example.com]

TASK [Install firewalld] ***************************************************


ok: [servera.lab.example.com]
ok: [serverc.lab.example.com]

TASK [Enable and start firewalld] ******************************************


ok: [servera.lab.example.com]
ok: [serverc.lab.example.com]

TASK [Open the port for http] **********************************************


changed: [servera.lab.example.com]
changed: [serverc.lab.example.com]

RUNNING HANDLER [restart httpd] ********************************************


changed: [serverc.lab.example.com]
changed: [servera.lab.example.com]

PLAY RECAP *****************************************************************


servera.lab.example.com : ok=8 changed=2 unreachable=0 failed=0
serverb.lab.example.com : ok=8 changed=5 unreachable=0 failed=0
serverc.lab.example.com : ok=8 changed=5 unreachable=0 failed=0
serverd.lab.example.com : ok=8 changed=5 unreachable=0 failed=0

Evaluación
En workstation, ejecute el comando lab projects-review grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab projects-review grade

Finalizar
En workstation, ejecute el script lab projects-review finish para limpiar los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab projects-review finish

Esto concluye el trabajo de laboratorio.

288 RH294-RHEL8.0-es-1-20200501
capítulo 7 | Administración de proyectos grandes

Resumen
En este capítulo, aprendió lo siguiente:

• Los patrones de host se usan para especificar los hosts administrados a los que debe apuntar
una reproducción o un comando ad hoc.

• Los scripts de inventario dinámico se pueden usar para generar listas dinámicas de hosts
administrados desde servicios de directorio u otras fuentes externas a Ansible.

• El parámetro forks en el archivo de configuración de Ansible establece el número máximo de


conexiones paralelas a los hosts administrados.

• El parámetro serial se puede usar para implementar actualizaciones periódicas en los hosts
administrados definiendo la cantidad de hosts administrados en cada lote de actualizaciones
periódicas.

• Puede usar la función import_playbook para incorporar archivos de reproducción externos a


las guías.

• Puede usar las funciones include_tasks o import_tasks para incorporar archivos de tareas
externos a las guías.

RH294-RHEL8.0-es-1-20200501 289
290 RH294-RHEL8.0-es-1-20200501
capítulo 8

Simplificación de guías con


roles
Meta Usar los roles de Ansible para desarrollar guías más
rápidamente y reutilizar el código de Ansible.

Objetivos • Describir qué es un rol, cómo está estructurado


y cómo puede usarlo en una guía.
• Crear un rol en el directorio de proyectos de
una guía y ejecutarlo como parte de una de las
reproducciones de la guía.
• Seleccionar y recuperar roles de Ansible Galaxy
u otras fuentes, como un repositorio Git, y
utilizarlos en sus guías.
• Escribir guías que aprovechen los roles del
sistema de Red Hat Enterprise Linux para
realizar operaciones estándares.

Secciones • Descripción de la estructura del rol (y


cuestionario)
• Reutilización de contenido con roles de sistema
(y ejercicio guiado)
• Creación de roles (y ejercicio guiado)
• Implementación de roles con Ansible Galaxy (y
ejercicio guiado)

Trabajo de • Simplificación de guías con roles


laboratorio

RH294-RHEL8.0-es-1-20200501 291
capítulo 8 | Simplificación de guías con roles

Descripción de la estructura del rol

Objetivos
Después de completar esta sección, debe ser capaz de describir qué es un rol, cómo está
estructurado y cómo puede usarlo en una guía.

Estructuración de Ansible Playbooks con roles


A medida que desarrolla más guías, probablemente descubrirá que tiene muchas oportunidades
para volver a usar el código de guías que ya ha escrito. Tal vez una reproducción para configurar
una base de datos MySQL para una aplicación podría ser reutilizada, con diferentes nombres de
host, contraseñas y usuarios, para configurar una base de datos MySQL para otra aplicación.

Pero en el mundo real, esa reproducción puede ser larga y complejo, con muchos archivos
incluidos o importados, y con tareas y controladores para gestionar diversas situaciones. Copiar
todo ese código en otra guía podría ser un trabajo no menor.

Los roles de Ansible le proporcionan una forma de hacer que sea más fácil volver a usar el
código de Ansible de forma genérica. Puede empaquetar, en una estructura de directorios
estandarizada, todas las tareas, variables, archivos, plantillas y otros recursos necesarios para
brindar infraestructura o implementar aplicaciones. Copie ese rol de proyecto a proyecto
simplemente copiando el directorio. A continuación, puede simplemente llamar a ese rol desde
una reproducción para ejecutarlo.

Un rol bien escrito le permitirá pasar variables al rol de la guía que ajusta su comportamiento,
configurando todos los nombres de host, direcciones IP, nombres de usuario, secretos o
detalles que necesitas, específicos para el sitio y de la ubicación. Por ejemplo, una función para
implementar un servidor de base de datos podría haber sido escrita para admitir variables que
configuran el nombre de host, el usuario administrador de la base de datos y la contraseña, y otros
parámetros que necesitan personalización para su instalación. El autor del rol también puede
garantizar que se establezcan valores predeterminados razonables para esas variables si elige no
establecerlas en la reproducción.

Los roles Ansible tienen los siguientes beneficios:

• Contenido del grupo de roles, lo que permite intercambiar el código fácilmente con otros

• Los roles se pueden escribir para definir los elementos fundamentales de un tipo de sistema:
servidor web, servidor de base de datos, repositorio git u otro propósito

• Los roles hacen que los proyectos más grandes sean más manejables

• Los roles se pueden desarrollar en paralelo por diferentes administradores

Además de escribir, usar, volver a usar y compartir sus propios roles, puede obtener roles de otras
fuentes. Algunos roles se incluyen como parte de Red Hat Enterprise Linux, en el paquete rhel-
system-roles. También puede obtener muchos roles respaldados por la comunidad del sitio web de
Ansible Galaxy. Más adelante en este capítulo, aprenderá más sobre estos roles.

292 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Análisis de la estructura de roles de Ansible


Una función Ansible se define mediante una estructura estandarizada de subdirectorios y archivos.
El directorio de nivel superior define el nombre del propio rol. Los archivos se organizan en
subdirectorios que se nombran de acuerdo con el propósito de cada archivo en el rol, como
tasks y handlers. Los subdirectorios files y templates contienen archivos a los que hacen
referencia tareas en otros los archivos YAML.

El siguiente comando tree muestra la estructura de directorio del rol user.example.

[user@host roles]$ tree user.example


user.example/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

Subdirectorios del rol Ansible

Subdirectorio Función

defaults El archivo main.yml en este directorio contiene los valores


predeterminados de variables de rol que se pueden sobrescribir cuando
se utiliza un rol. Estas variables tienen poca prioridad y están destinadas
a ser modificadas y personalizadas en las reproducciones.

files Este directorio contiene archivos estáticos a los que hacen referencia
las tareas de los roles.

handlers El archivo main.yml en este directorio contiene las definiciones del


manejador de roles.

meta El archivo main.yml en este directorio contiene información acerca del


rol, incluido el autor, la licencia, las plataformas y las dependencias de
roles opcionales.

tasks El archivo main.yml en este directorio contiene las definiciones de


tareas de roles.

templates Este directorio contiene plantillas Jinja2 a las que hacen referencia las
tareas de los roles.

RH294-RHEL8.0-es-1-20200501 293
capítulo 8 | Simplificación de guías con roles

Subdirectorio Función

tests Este directorio puede contener un inventario y una guía test.yml que
se pueden utilizar para probar un rol.

vars El archivo main.yml en este directorio define los valores de la variable


del rol. A menudo, estas variables se utilizan para fines internos dentro
del rol. Estas variables tienen una alta prioridad y no están diseñadas
para ser cambiadas cuando se utilizan en una guía.

No todos los roles tendrán todos estos directorios.

Definición de variables y valores predeterminados


Las variables del rol se definen mediante la creación de un archivo vars/main.yml con pares
de clave: valor en la jerarquía del directorio del rol. Son nombrados en el archivo YAML del rol
como cualquier otra variable: {{ VAR_NAME }}. Estas variables tienen una alta prioridad y no
se las puede reemplazar por variables de inventario. La intención de estas variables es que sean
utilizadas por el funcionamiento interno del rol.

Las variables predeterminadas permiten que se establezcan valores predeterminados para


las variables que se pueden usar en una reproducción para configurar el rol o personalizar su
comportamiento. Se definen mediante la creación de un archivo defaults/main.yml con
pares de clave: valor en la jerarquía del directorio del rol. Las variables predeterminadas tienen
la prioridad más baja de cualquier variable disponible. Se las puede reemplazar fácilmente
con cualquier otra variable, incluidas las variables de inventario. El objetivo de estas variables
es proporcionarle a la persona que escribe una reproducción que utiliza el rol una manera de
personalizar o controlar exactamente lo que va a hacer. Se pueden usar para proporcionarle
información al rol de que necesita configurar o implementar algo correctamente.

Defina una variable específica en vars/main.yml o defaults/main.yml, pero no en ambos


lugares. Las variables predeterminadas deben utilizarse cuando se pretende que se reemplacen
sus valores.

Importante
Los roles no deben tener datos específicos del sitio en ellos. Definitivamente no
deben contener ningún secreto como contraseñas o claves privadas.

Esto se debe a que se supone que los roles son genéricos, reutilizables y se pueden
compartir libremente. Los detalles específicos del sitio no deben ser codificados en
ellos.

Los secretos deben proporcionarse al rol a través de otros medios. Esta es una de
las razones por las que puede querer establecer variables de rol al llamar a un rol.
Las variables de rol establecidas en la reproducción podrían proporcionar el secreto,
o apuntar a un archivo cifrado por Ansible Vault que contenga el secreto.

Uso de los roles de Ansible en una guía


El uso de los roles en una guía es sencillo. El siguiente ejemplo muestra una forma de llamar roles
Ansible.

294 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

---
- hosts: remote.example.com
roles:
- role1
- role2

Por cada rol especificado, las tareas, los manejadores, las variables y las dependencias de los
roles se importarán a una guía, en ese orden. Cualquier tarea de copy, script, template, o
include_tasks/import_tasks en el rol puede hacer referencia a los archivos, plantillas o
tareas pertinentes en el rol sin nombres de ruta absolutos o relativos. Ansible los busca en los
subdirectorios files templates o tasks del rol, respectivamente.

Cuando usa una sección de roles para importar roles a una reproducción, los roles se ejecutarán
primero, antes que cualquier tarea que defina para esa reproducción.

En el siguiente ejemplo, se establecen valores para dos variables de rol de role2, var1 y var2.
Las variables defaults y vars se anulan cuando se usa role2.

---
- hosts: remote.example.com
roles:
- role: role1
- role: role2
var1: val1
var2: val2

Otra sintaxis de YAML equivalente que puede ver en este caso es:

---
- hosts: remote.example.com
roles:
- role: role1
- { role: role2, var1: val1, var2: val2 }

Hay situaciones en las que esto puede ser más difícil de leer, aunque sea más compacto.

Importante
Las variables de rol establecidas en línea (parámetros de rol), como en los ejemplos
anteriores, tienen precedencia muy alta. Anularán a la mayoría de las otras variables.

Tenga mucho cuidado de no volver a usar los nombres de las variables de rol que
establezca en línea en cualquier otro lugar de su reproducción, ya que los valores de
las variables de rol anularán las variables de inventario y las vars de la reproducción.

Control del orden de ejecución


Para cada reproducción de una guía, las tareas se ejecutan según el orden de la lista de tareas. Una
vez ejecutadas todas las tareas, se ejecutan todos los manejadores notificados.

Cuando se agrega un rol a una reproducción, las tareas del rol se agregan al principio de la lista de
tareas. Si se incluye un segundo rol en una reproducción, su lista de tareas se agrega después del
primer rol.

RH294-RHEL8.0-es-1-20200501 295
capítulo 8 | Simplificación de guías con roles

Los manejadores de rol se agregan a las reproducciones de la misma manera que las tareas de
rol se agregan a las reproducciones. Cada reproducción define una lista de manejadores. Los
manejadores de rol se agregan primero a la lista de manejadores, seguidos de los manejadores
definidos en la sección handlers de la reproducción.

En ciertos escenarios, puede que algunas tareas de reproducción se deban ejecutar antes que
los roles. Para admitir tales escenarios, se puede configurar una sección pre_tasks en las
reproducciones. Todas las tareas detalladas en esta sección se ejecutan antes que los roles. Si
alguna de estas tareas notifica a un manejador, las tareas del manejador se ejecutan antes que los
roles o las tareas normales.

Las reproducciones también admiten una palabra clave post_tasks. Estas tareas se ejecutan
después de las tareas normales de la reproducción, y se ejecutan todos los manejadores que
notifican.

En la siguiente reproducción, se muestra un ejemplo con pre_tasks, roles, tasks,


post_tasks y handlers. Es raro que una reproducción tenga todas estas secciones.

- name: Play to illustrate order of execution


hosts: remote.example.com
pre_tasks:
- debug:
msg: 'pre-task'
notify: my handler
roles:
- role1
tasks:
- debug:
msg: 'first task'
notify: my handler
post_tasks:
- debug:
msg: 'post-task'
notify: my handler
handlers:
- name: my handler
debug:
msg: Running my handler

En el ejemplo anterior, una tarea debug se ejecuta en cada sección para notificar al manejador my
handler. La tarea my handler se ejecuta tres veces:

• después de que se hayan ejecutado todas las tareas de pre_tasks

• después de que se hayan ejecutado todas las tareas de la sección tasks

• después de que se hayan ejecutado todas las tareas de post_tasks

Los roles se pueden agregar a una reproducción con una tarea común, no solo incluyéndolos en la
sección roles de una reproducción. Use el módulo include_role para incluir dinámicamente
un rol y use el módulo import_role para importar estáticamente un rol.

La guía siguiente muestra cómo se puede incluir un rol usando una tarea con el módulo
include_role.

296 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

- name: Execute a role as a task


hosts: remote.example.com
tasks:
- name: A normal task
debug:
msg: 'first task'
- name: A task to include role2 here
include_role: role2

nota
El módulo include_role se agregó en Ansible 2.3, y el módulo import_role, en
Ansible 2.4.

Referencias
Roles — Documentación de Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

RH294-RHEL8.0-es-1-20200501 297
capítulo 8 | Simplificación de guías con roles

Cuestionario

Descripción de la estructura del rol


Elija las respuestas correctas para las siguientes preguntas:

1. ¿Cuál de las siguientes declaraciones describe mejor los roles?


a. Configuración que permite que usuarios específicos ejecuten guías Ansible.
b. Guías para un centro de datos.
c. Recopilación de archivos de tareas YAML y elementos complementarios dispuestos en
una estructura específica para un intercambio, portabilidad y reutilización sencillos.

2. ¿Cuáles de los siguientes se pueden especificar en roles?


a. Manejadores
b. Tareas
c. Plantillas
d. Variables
e. Todos los anteriores

3. ¿Qué archivo declara dependencias de roles?


a. La guía Ansible que usa el rol.
b. El archivo meta/main.yml dentro de la jerarquía de roles.
c. El archivo meta/main.yml en el directorio del proyecto.
d. Las dependencias de roles no se pueden definir en Ansible.

4. ¿Qué archivo en la jerarquía de directorio de un rol debe contener los valores iniciales
de variables que se pueden usar como parámetros para el rol?
a. defaults/main.yml
b. meta/main.yml
c. vars/main.yml
d. El archivo del inventario del host.

298 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Solución

Descripción de la estructura del rol


Elija las respuestas correctas para las siguientes preguntas:

1. ¿Cuál de las siguientes declaraciones describe mejor los roles?


a. Configuración que permite que usuarios específicos ejecuten guías Ansible.
b. Guías para un centro de datos.
c. Recopilación de archivos de tareas YAML y elementos complementarios dispuestos en
una estructura específica para un intercambio, portabilidad y reutilización sencillos.

2. ¿Cuáles de los siguientes se pueden especificar en roles?


a. Manejadores
b. Tareas
c. Plantillas
d. Variables
e. Todos los anteriores

3. ¿Qué archivo declara dependencias de roles?


a. La guía Ansible que usa el rol.
b. El archivo meta/main.yml dentro de la jerarquía de roles.
c. El archivo meta/main.yml en el directorio del proyecto.
d. Las dependencias de roles no se pueden definir en Ansible.

4. ¿Qué archivo en la jerarquía de directorio de un rol debe contener los valores iniciales
de variables que se pueden usar como parámetros para el rol?
a. defaults/main.yml
b. meta/main.yml
c. vars/main.yml
d. El archivo del inventario del host.

RH294-RHEL8.0-es-1-20200501 299
capítulo 8 | Simplificación de guías con roles

Reutilización de contenido con roles de


sistema

Objetivos
Tras haber completado esta sección, debe ser capaz de escribir guías que aprovechen los roles del
sistema de Red Hat Enterprise Linux para realizar operaciones estándares.

Roles de sistema de Red Hat Enterprise Linux


A partir de Red Hat Enterprise Linux 7.4, se proporciona una serie de roles de Ansible con el
sistema operativo como parte del paquete de rhel-system-roles. En Red Hat Enterprise Linux 8, el
paquete está disponible en el canal AppStream. Una breve descripción de cada rol:

Roles de sistema RHEL

Nombre Estado Descripción del rol

rhel-system- Compatibilidad completa Configura el servicio de


roles.kdump recuperación ante fallos
kdump.

rhel-system- Compatibilidad completa Configura interfaces de red.


roles.network

rhel-system- Compatibilidad completa Configura y administra la


roles.selinux personalización de SELinux,
incluido el modo SELinux,
los contextos de archivos
y puertos, la configuración
booleana y los usuarios de
SELinux.

rhel-system- Compatibilidad completa Configura la sincronización


roles.timesync de tiempo usando el
protocolo de tiempo de red
o el protocolo de tiempo de
precisión.

rhel-system- Vista previa de la tecnología Configura cada host como


roles.postfix un agente de transferencia
de correo usando el servicio
Postfix.

rhel-system- En desarrollo Configura el firewall de un


roles.firewall host.

rhel-system- En desarrollo Configura el servicio tuned


roles.tuned para sintonizar el rendimiento
del sistema.

300 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Los roles del sistema apuntan a estandarizar la configuración de subsistemas de Red Hat
Enterprise Linux en varias versiones. Use los roles del sistema para configurar cualquier instancia
de Red Hat Enterprise Linux, versión 6.10 y posteriores.

Administración simplificada de configuraciones


Como ejemplo, el servicio de sincronización de tiempo recomendado para Red Hat
Enterprise Linux 7 es el servicio chronyd. Sin embargo, en Red Hat Enterprise Linux 6, el
servicio recomendado es ntpd. En un entorno con una combinación de hosts con Red Hat
Enterprise Linux 6 y 7, un administrador debe administrar los archivos de configuración para
ambos servicios.

Con los roles del sistema RHEL, los administradores ya no necesitan mantener los archivos de
configuración para ambos servicios. Los administradores pueden usar el rol rhel-system-
roles.timesync para configurar la sincronización de tiempo para hosts de Red Hat
Enterprise Linux 6 y 7. Un archivo YAML simplificado que contiene variables de roles define la
configuración de la sincronización de tiempo para ambos tipos de hosts.

Soporte para roles de sistema RHEL


Los roles de sistema RHEL se derivan del proyecto de roles de sistema de Linux de código abierto,
que se encuentra en Ansible Galaxy. A diferencia de los roles de sistema de Linux, los roles de
sistema RHEL son compatibles con Red Hat como parte de una suscripción estándar de Red Hat
Enterprise Linux. Los roles de sistema RHEL tienen los mismos beneficios de soporte de ciclo de
vida que la suscripción a Red Hat Enterprise Linux.

Todos los roles del sistema están probados y son estables. Los roles de sistema totalmente
compatibles también tienen interfaces estables. Para cualquier rol de sistema totalmente
compatible , Red Hat se esforzará por garantizar que las variables del rol no se modifiquen en
futuras versiones. La refactorización de la guía debido a cambios en el rol del sistema debe ser
mínima.

Los roles de sistema Vista previa de tecnología pueden utilizar diferentes variables de rol
en versiones futuras. Se recomiendan pruebas de integración para guías que incorporan roles de
Vista previa de tecnología. Las guías pueden requerir refactorización si las variables de
rol cambian en una versión futura del rol.

Se están desarrollando otros roles en el proyecto de roles ascendentes de sistema de Linux, pero
aún no están disponibles a través de una suscripción de RHEL. Estos roles están disponibles a
través de Ansible Galaxy.

Instalación de roles de sistema RHEL


Los roles del sistema RHEL vienen en el paquete rhel-system-roles, que está disponible en el canal
AppStream. Instale este paquete en el nodo de control de Ansible.

Use el siguiente procedimiento para instalar el paquete rhel-system-roles. El procedimiento asume


que el nodo de control está registrado en una suscripción de Red Hat Enterprise Linux y que
Ansible Engine está instalado. Consulte la sección sobre Instalación de Ansible para obtener más
información.

1. Instale los roles de sistema RHEL.

[root@host ~]# yum install rhel-system-roles

RH294-RHEL8.0-es-1-20200501 301
capítulo 8 | Simplificación de guías con roles

Después de la instalación, los roles de sistema RHEL se encuentran en el directorio /usr/share/


ansible/roles:

[root@host ~]# ls -l /usr/share/ansible/roles/


total 20
...output omitted... linux-system-roles.kdump -> rhel-system-roles.kdump
...output omitted... linux-system-roles.network -> rhel-system-roles.network
...output omitted... linux-system-roles.postfix -> rhel-system-roles.postfix
...output omitted... linux-system-roles.selinux -> rhel-system-roles.selinux
...output omitted... linux-system-roles.timesync -> rhel-system-roles.timesync
...output omitted... rhel-system-roles.kdump
...output omitted... rhel-system-roles.network
...output omitted... rhel-system-roles.postfix
...output omitted... rhel-system-roles.selinux
...output omitted... rhel-system-roles.timesync

El nombre ascendente correspondiente de cada rol está vinculado al rol de sistema RHEL. Esto
permite que cualquiera de los dos nombres hagan referencia a un rol en una guía.

El roles_path predeterminado en Red Hat Enterprise Linux incluye /usr/share/ansible/


roles en la ruta, por lo que Ansible debe encontrar automáticamente esos roles cuando se hace
referencia a ellos en una guía.

nota
Ansible podría no encontrar los roles de sistema si roles_path se ha anulado
en el archivo de configuración actual de Ansible, si la variable de entorno
ANSIBLE_ROLES_PATH está configurada o si hay otro rol con el mismo nombre en
un directorio listado anteriormente en roles_path.

Acceso a la documentación para roles de sistema RHEL


Después de la instalación, la documentación de los roles de sistema RHEL se encuentra en el
directorio /usr/share/doc/rhel-system-roles-<version>/. La documentación está
organizada en subdirectorios por subsistema:

[root@host ~]# ls -l /usr/share/doc/rhel-system-roles/


total 4
drwxr-xr-x. ...output omitted... kdump
drwxr-xr-x. ...output omitted... network
drwxr-xr-x. ...output omitted... postfix
drwxr-xr-x. ...output omitted... selinux
drwxr-xr-x. ...output omitted... timesync

El directorio de documentación de cada rol contiene un archivo README.md. El archivo


README.md contiene una descripción del rol, junto con la información de uso del rol.

El archivo README.md también describe las variables de rol que afectan el comportamiento del
rol. A menudo el archivo README.md contiene un fragmento de guía que muestra la configuración
de variables para un escenario de configuración común.

Algunos directorios de documentación de roles contienen ejemplos de guías. Cuando use un rol
por primera vez, revise las guías de ejemplo adicionales en el directorio de documentación.

302 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

La documentación de roles para los roles de sistema RHEL coincide con la documentación de
roles del sistema Linux. Use un navegador web para acceder a la documentación de roles para los
roles ascendentes en el sitio de Ansible Galaxy, https://galaxy.ansible.com.

Ejemplo de rol de sincronización de tiempos


Supongamos que necesita configurar la sincronización temporal de NTP en sus servidores.
Podría escribir la automatización usted mismo para realizar cada una de las tareas necesarias.
Sin embargo, los roles de sistema RHEL incluyen un rol que puede hacer esto, rhel-system-
roles.timesync.

El rol está documentado en su README.md en el directorio /usr/share/doc/rhel-system-


roles/timesync. El archivo describe todas las variables que afectan el comportamiento del
rol y contiene tres fragmentos de guía que ilustran diferentes configuraciones de sincronización
temporal.

Para configurar manualmente los servidores NTP, el rol tiene una variable llamada
timesync_ntp_servers. Se necesita una lista de servidores NTP para usarla. Cada ítem de la
lista se compone de uno o más atributos. A continuación se detallan los dos atributos clave:

atributos timesync_ntp_servers

Atributo Propósito

hostname El nombre de host de un servidor NTP con el que se puede


sincronizar.

iburst Un valor booleano que habilita o deshabilita la sincronización


inicial rápida. Se establece de forma predeterminada en no en el
rol; normalmente debe establecerse en yes.

Dada esta información, el siguiente ejemplo es una reproducción que utiliza el rol rhel-system-
roles.timesync para configurar los hosts administrados a fin de obtener el tiempo de tres
servidores NTP utilizando la sincronización inicial rápida. Además, se ha agregado una tarea que
utiliza el módulo timezone para configurar la zona horaria de los hosts en UTC.

- name: Time Synchronization Play


hosts: servers
vars:
timesync_ntp_servers:
- hostname: 0.rhel.pool.ntp.org
iburst: yes
- hostname: 1.rhel.pool.ntp.org
iburst: yes
- hostname: 2.rhel.pool.ntp.org
iburst: yes
timezone: UTC

roles:
- rhel-system-roles.timesync

tasks:

RH294-RHEL8.0-es-1-20200501 303
capítulo 8 | Simplificación de guías con roles

- name: Set timezone


timezone:
name: "{{ timezone }}"

nota
Si desea establecer una zona horaria diferente, puede utilizar el comando
tzselect para buscar otros valores aceptados. También puede usar el comando
timedatectl para comprobar la configuración actual del reloj.

Este ejemplo establece las variables de rol en una sección vars de la reproducción, pero una
mejor práctica sería configurarlas como variables de inventario para hosts o grupos de hosts.

Considere un proyecto de guía con la siguiente estructura:

[root@host playbook-project]# tree


.
├── ansible.cfg
├── group_vars
│ └── servers
│ └── timesync.yml
├── inventory
└── timesync_playbook.yml

Define las variables de sincronización temporal que anulan los valores predeterminados de rol
para los hosts en el grupo servers del inventario. A continuación se muestra un ejemplo de
cómo se vería este archivo:

timesync_ntp_servers:
- hostname: 0.rhel.pool.ntp.org
iburst: yes
- hostname: 1.rhel.pool.ntp.org
iburst: yes
- hostname: 2.rhel.pool.ntp.org
iburst: yes
timezone: UTC

El contenido de la guía se simplifica a lo siguiente:

- name: Time Synchronization Play


hosts: servers
roles:
- rhel-system-roles.timesync
tasks:
- name: Set timezone
timezone:
name: "{{ timezone }}"

Esta estructura separa claramente el rol, el código de la guía y los ajustes de configuración. El
código de la guía es simple, fácil de leer y no debe requerir una refactorización compleja. Red Hat
mantiene y admite el contenido del rol. Todas las configuraciones se manejan como variables de
inventario.

304 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Esta estructura también admite un entorno dinámico y heterogéneo. Los hosts con nuevos
requisitos de sincronización temporal se pueden colocar en un nuevo grupo de hosts. Las variables
apropiadas se definen en un archivo YAML y se colocan en el subdirectorio correspondiente
group_vars (o host_vars).

Ejemplo de rol de SELinux


Como otro ejemplo, el rol rhel-system-roles.selinux simplifica la administración de ajustes
de configuración de SELinux. Se implementa utilizando los módulos de Ansible relacionados con
SELinux. La ventaja de usar este rol en lugar de escribir sus propias tareas es que lo exime de la
responsabilidad de escribir esas tareas. En su lugar, proporciona variables al rol para configurarlo, y
el código mantenido en el rol garantizará que se aplique la configuración deseada de SELinux.

A continuación se detallan algunas de las tareas que puede realizar este rol:

• Establecer el modo de ejecución o permisivo

• Ejecutar restorecon en partes de la jerarquía del sistema de archivos

• Configurar valores booleanos de SELinux

• Configurar de manera persistente los contextos de archivos de SELinux

• Configurar asignaciones de usuarios de SELinux

Llamada al rol de SELinux


A veces, el rol SELinux debe garantizar que los hosts administrados se reinicien para aplicar
completamente los cambios. Sin embargo, nunca reinicia los hosts por sí mismo. Esto le permite
controlar cómo se maneja el reinicio. No obstante, significa que es un poco más complicado de lo
habitual utilizar correctamente este rol en una reproducción.

Esto funciona así: el rol establecerá una variable booleana, selinux_reboot_required,


en true y fallará si se necesita un reinicio. Puede usar una estructura block/rescue para
recuperarse de la falla, ya sea que falle la reproducción porque la variable no se configura en true,
o que reinicie el host administrado y vuelva a ejecutar el rol porque está en true. El bloque de la
reproducción debe verse parecido a lo siguiente:

- name: Apply SELinux role


block:
- include_role:
name: rhel-system-roles.selinux
rescue:
- name: Check for failure for other reasons than required reboot
fail:
when: not selinux_reboot_required

- name: Restart managed host


reboot:

- name: Reapply SELinux role to complete changes


include_role:
name: rhel-system-roles.selinux

RH294-RHEL8.0-es-1-20200501 305
capítulo 8 | Simplificación de guías con roles

Configuración del rol de SELinux


Las variables utilizadas para configurar el rol rhel-system-roles.selinux se documentan en
el archivo README.md. En los siguientes ejemplos, se muestran algunas formas de usar este rol.

La variable selinux_state establece el modo en que se ejecuta SELinux. Se puede configurar


en modo de enforcing (cumplimiento), permissive (permisivo) o disabled (deshabilitado).
Si no está configurada, el modo no se cambia.

selinux_state: enforcing

La variable selinux_booleans toma una lista de valores booleanos de SELinux para ajustarse.
Cada ítem de la lista es un hash/diccionario de variables: name del booleano, state (tanto en on
como en off), e independientemente de que el ajuste deba ser persistent en los reinicios.

Este ejemplo establece httpd_enable_homedirs en on continuamente:

selinux_booleans:
- name: 'httpd_enable_homedirs'
state: 'on'
persistent: 'yes'

La variable selinux_fcontext requiere una lista de contextos de archivo para establecerse


continuamente (o eliminarse). Funciona muy parecido al comando selinux fcontext.

En el siguiente ejemplo, se garantiza que la política tenga una regla para establecer el tipo de
SELinux predeterminado para todos los archivos de /srv/www en httpd_sys_content_t.

selinux_fcontexts:
- target: '/srv/www(/.*)?'
setype: 'httpd_sys_content_t'
state: 'present'

La variable selinux_restore_dirs especifica una lista de directorios en los que se puede


ejecutar restorecon:

selinux_restore_dirs:
- /srv/www

La variable selinux_ports toma una lista de puertos que deben tener un tipo específico de
SELinux.

selinux_ports:
- ports: '82'
setype: 'http_port_t'
proto: 'tcp'
state: 'present'

Existen otras variables y opciones para este rol. Consulte su archivo README.md para obtener más
información.

306 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Referencias
Roles de sistema de Red Hat Enterprise Linux (RHEL)
https://access.redhat.com/articles/3050101

Roles de sistema de Linux


https://linux-system-roles.github.io/

RH294-RHEL8.0-es-1-20200501 307
capítulo 8 | Simplificación de guías con roles

Ejercicio Guiado

Reutilización de contenido con roles de


sistema
En este ejercicio, utilizará uno de los roles de sistema de Red Hat Enterprise Linux junto con
una tarea normal para configurar la sincronización temporal y la zona horaria de los hosts
administrados.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Instalar los roles de sistema de Red Hat Enterprise Linux.

• Buscar y usar la documentación de roles de sistema RHEL.

• Utilizar el rol rhel-system-roles.timesync en una guía para configurar la


sincronización temporal en hosts remotos.

Descripción general del escenario


Su organización mantiene dos centros de datos: uno en Estados Unidos (Chicago) y otro en
Finlandia (Helsinki). Para facilitar el análisis de registros de los servidores de bases de datos
en los centros de datos, asegúrese de que el reloj del sistema de cada host esté sincronizado
mediante el protocolo de tiempo de red. Para facilitar el análisis de actividades por hora del
día en los centros de datos, asegúrese de que cada servidor de base de datos tenga una
zona horaria configurada que se corresponda con la ubicación del centro de datos del host.

La sincronización temporal tiene los siguientes requisitos:

• Utilice el servidor NTP ubicado en classroom.example.com. Habilite la opción iburst


para acelerar la sincronización temporal inicial.

• Use el paquete chrony para la sincronización temporal.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab role-system start. Esto crea el directorio


de trabajo, /home/student/role-system, y lo completa con un archivo de configuración
de Ansible y un inventario de hosts.

[student@workstation ~]$ lab role-system start

1. Cambie al directorio de trabajo /home/student/role-system.

[student@workstation ~]$ cd ~/role-system


[student@workstation role-system]$

308 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

2. Instale los roles de sistema de Red Hat Enterprise Linux en el nodo de control,
workstation.lab.example.com. Verifique la ubicación de instalación de los roles en el
nodo de control.

2.1. Utilice el comando ansible-galaxy para verificar que no haya roles disponibles
inicialmente para su uso en el proyecto de guía.

[student@workstation role-system]$ ansible-galaxy list


# /home/student/role-system/roles
# /usr/share/ansible/roles
# /etc/ansible/roles
[student@workstation role-system]$

El comando ansible-galaxy busca roles en tres directorios, como lo indica la


entrada roles_path del archivo ansible.cfg:

• ./roles

• /usr/share/ansible/roles

• /etc/ansible/roles

En la salida anterior, se indica que no hay roles en ninguno de estos directorios.

2.2. Instale el paquete rhel-system-roles.

[student@workstation role-system]$ sudo yum install rhel-system-roles

Escriba y cuando se le solicite instalar el paquete.

2.3. Use el comando ansible-galaxy para verificar que los roles del sistema ahora
estén disponibles.

[student@workstation role-system]$ ansible-galaxy list


# /home/student/role-system/roles
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles

Los roles están ubicados en el directorio /usr/share/ansible/roles. Cualquier


rol que comience con linux-system-roles es en realidad un enlace simbólico al
rol rhel-system-roles correspondiente.

3. Cree una guía, configure_time.yml, con una reproducción orientada al grupo de hosts
database_servers. Incluya el rol rhel-system-roles.timesync en la sección
roles de la reproducción.

RH294-RHEL8.0-es-1-20200501 309
capítulo 8 | Simplificación de guías con roles

---
- name: Time Synchronization
hosts: database_servers

roles:
- rhel-system-roles.timesync

4. La documentación del rol contiene una descripción de cada variable del rol, incluido el valor
predeterminado de la variable. Determine las variables de rol que se anularán para cumplir
con los requisitos de sincronización temporal.
Coloque los valores de las variables de rol en un archivo denominado timesync.yml.
Debido a que los valores de estas variables se aplican a todos los hosts del inventario,
coloque el archivo timesync.yml en el subdirectorio group_vars/all.

4.1. Consulte la sección Variables de rol del archivo README.md para conocer el rol rhel-
system-roles.timesync.

[student@workstation role-system]$ cat \


> /usr/share/doc/rhel-system-roles/timesync/README.md
...output omitted...
Role Variables
--------------

...output omitted...
# List of NTP servers
timesync_ntp_servers:
- hostname: foo.example.com # Hostname or address of the server
minpoll: 4 # Minimum polling interval (default 6)
maxpoll: 8 # Maximum polling interval (default 10)
iburst: yes # Flag enabling fast initial synchronization
# (default no)
pool: no # Flag indicating that each resolved address
# of the hostname is a separate NTP server
# (default no)
...output omitted...
# Name of the package which should be installed and configured for NTP.
# Possible values are "chrony" and "ntp". If not defined, the currently active
# or enabled service will be configured. If no service is active or enabled, a
# package specific to the system and its version will be selected.
timesync_ntp_provider: chrony
...output omitted...

4.2. Cree el subdirectorio group_vars/all.

[student@workstation role-system]$ mkdir -pv group_vars/all


mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/all'

4.3. Cree un archivo group_vars/all/timesync.yml nuevo con el editor de texto.


Agregue definiciones de variables para satisfacer los requisitos de sincronización
temporal. El archivo ahora contiene lo siguiente:

310 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

---
#rhel-system-roles.timesync variables for all hosts

timesync_ntp_provider: chrony

timesync_ntp_servers:
- hostname: classroom.example.com
iburst: yes

5. Agregue una tarea a configure_time.yml para establecer la zona horaria para cada
host. Asegúrese de que la tarea use el módulo timezone y se ejecute después del rol
rhel-system-roles.timesync.
Debido a que los hosts no pertenecen a la misma zona horaria, use una variable
(host_timezone) para el nombre de la zona horaria.

5.1. Revise la sección Ejemplos de la documentación del módulo timezone.

[student@workstation role-system]$ ansible-doc timezone | grep -A 4 "EXAMPLES"


EXAMPLES:
- name: set timezone to Asia/Tokyo
timezone:
name: Asia/Tokyo

5.2. Agregue una tarea a la sección post_tasks de la reproducción en la guía


configure_time.yml. Modele la tarea siguiendo el ejemplo de la documentación,
pero use la variable host_timezone para el nombre de la zona horaria.
La documentación de ansible-doc timezone recomienda reiniciar el servicio
Cron si el módulo cambia la zona horaria, para asegurarse de que los trabajos de Cron
se ejecuten a la hora indicada. Agregue una palabra clave notify a la tarea, con un
valor asociado de restart crond. La sección post_tasks de la reproducción
debe decir:

post_tasks:
- name: Set timezone
timezone:
name: "{{ host_timezone }}"
notify: restart crond

5.3. Agregue el manejador restart crond a la reproducción Time


Synchronization. La guía completa ahora contiene lo siguiente:

---
- name: Time Synchronization
hosts: database_servers

roles:
- rhel-system-roles.timesync

post_tasks:
- name: Set timezone
timezone:

RH294-RHEL8.0-es-1-20200501 311
capítulo 8 | Simplificación de guías con roles

name: "{{ host_timezone }}"


notify: restart crond

handlers:
- name: restart crond
service:
name: crond
state: restarted

6. Para cada centro de datos, cree un archivo llamado timezone.yml con un valor apropiado
para la variable host_timezone. Use el comando timedatectl list-timezones para
encontrar la cadena de zona horaria válida para cada centro de datos.

6.1. Cree los subdirectorios group_vars para los grupos de hosts na_datacenter y
europe_datacenter.

[student@workstation role-system]$ mkdir -pv \


> group_vars/{na_datacenter,europe_datacenter}
mkdir: created directory 'group_vars/na_datacenter'
mkdir: created directory 'group_vars/europe_datacenter'

6.2. Use el comando timedatectl list-timezones para determinar la zona horaria


para los centros de datos de EE. UU. y Europa:

[student@workstation role-system]$ timedatectl list-timezones | grep Chicago


America/Chicago
[student@workstation role-system]$ timedatectl list-timezones | grep Helsinki
Europe/Helsinki

6.3. Cree el timezone.yml para ambos centros de datos:

[student@workstation role-system]$ echo "host_timezone: America/Chicago" > \


> group_vars/na_datacenter/timezone.yml
[student@workstation role-system]$ echo "host_timezone: Europe/Helsinki" > \
> group_vars/europe_datacenter/timezone.yml

7. Ejecute la guía.

[student@workstation role-system]$ ansible-playbook configure_time.yml

PLAY [Time Synchronization] **************************************************

TASK [Gathering Facts] *******************************************************


ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]

TASK [rhel-system-roles.timesync : Check if only NTP is needed] **************


ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]

...output omitted...

312 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

TASK [rhel-system-roles.timesync : Enable timemaster] ************************


skipping: [servera.lab.example.com]
skipping: [serverb.lab.example.com]

RUNNING HANDLER [rhel-system-roles.timesync : restart chronyd] ***************


changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]

TASK [Set timezone] **********************************************************


changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]

RUNNING HANDLER [restart crond] **********************************************


changed: [serverb.lab.example.com]
changed: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=17 changed=6 unreachable=0 failed=0
skipped=20 rescued=0 ignored=6
serverb.lab.example.com : ok=17 changed=6 unreachable=0 failed=0
skipped=20 rescued=0 ignored=6

8. Verifique la configuración de zona horaria de cada servidor. Use un comando ad hoc de


Ansible para ver la salida del comando date en todos los servidores de bases de datos.

nota
Las zonas horarias reales enumeradas variarán según la época del año y si el horario
de verano está activo.

[student@workstation role-system]$ ansible database_servers -m shell -a date


serverb.lab.example.com | CHANGED | rc=0 >>
Wed Apr 3 06:27:01 EEST 2019

servera.lab.example.com | CHANGED | rc=0 >>


Tue Apr 2 22:27:01 CDT 2019

Cada servidor tiene una configuración de zona horaria basada en su ubicación geográfica.

Finalizar
Ejecute el comando lab role-system finish para limpiar el host administrado.

[student@workstation ~]$ lab role-system finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 313
capítulo 8 | Simplificación de guías con roles

Creación de roles

Objetivos
Tras haber completado esta sección, deberá ser capaz de crear un rol en un directorio de proyecto
de guía y ejecutarlo como parte de una de las reproducciones de la guía.

El proceso de creación de roles


Crear roles en Ansible no requiere herramientas de desarrollo especiales. Crear y usar un rol es un
proceso de tres pasos:

1. Cree la estructura del directorio de roles.

2. Defina el contenido de los roles.

3. Use el rol en una guía.

Creación de la estructura del directorio de roles


De manera predeterminada, Ansible busca roles en un subdirectorio llamado roles en el
directorio que contiene la Ansible Playbook. Esto le permite almacenar roles con la guía y otros
archivos de soporte.

Si Ansible no puede encontrar el rol allí, buscará en los directorios especificados por la
configuración de Ansible roles_path, en orden. Esta variable contiene una lista de directorios
separada por dos puntos para realizar la búsqueda. El valor predeterminado de esta variable es:

~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles

Esto permite instalar roles en el sistema que se comparten entre varios proyectos. Por
ejemplo, puede tener sus propios roles instalados en su directorio de inicio en el subdirectorio
~/.ansible/roles, y el sistema puede tener roles instalados para todos los usuarios en el
directorio /usr/share/ansible/roles.

Cada rol tiene su propio directorio con una estructura de directorios estandarizada. Por ejemplo, la
siguiente estructura de directorio contiene los archivos que definen el rol motd.

[user@host ~]$ tree roles/


roles/
└── motd
├── defaults
│ └── main.yml
├── files
├── handlers
├── meta
│ └── main.yml
├── README.md
├── tasks

314 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

│ └── main.yml
└── templates
└── motd.j2

README.md proporciona, en términos legibles para el ser humano, una descripción básica del
rol, documentación y ejemplos de cómo usarlo, y todos los requisitos ajenos a Ansible que podría
necesitar para funcionar. El subdirectorio meta contiene un archivo main.yml que especifica
información sobre el autor, la licencia, la compatibilidad y las dependencias del módulo. El
subdirectorio files contiene archivos de contenido fijo y el subdirectorio templates contiene
plantillas que se pueden implementar mediante el rol cuando se lo utiliza. Los otros subdirectorios
pueden contener los archivos main.yml que definen valores de variables predeterminados,
manejadores, tareas, metadatos de roles o variables, según el subdirectorio en el que se
encuentran.

Si existe un subdirectorio pero se encuentra vacío, como handlers en este ejemplo, es ignorado.
Si un rol no usa una característica, el subdirectorio se puede omitir por completo. Por ejemplo, el
subdirectorio vars se ha omitido en este ejemplo.

Creación de un esqueleto de roles


Puede crear todos los subdirectorios y archivos necesarios para un rol nuevo mediante comandos
estándares de Linux. Como alternativa, existen utilidades de línea de comandos para automatizar
el proceso de creación de nuevos roles.

La herramienta de línea de comandos ansible-galaxy (que se analiza en más detalle más


adelante en este curso) se utiliza para administrar los roles de Ansible, incluida la creación de
nuevos roles. Puede ejecutar ansible-galaxy init para crear la estructura de directorios
para un nuevo rol. Especifique el nombre del rol como argumento del comando, lo que crea un
subdirectorio para el nuevo rol en el directorio de trabajo actual.

[user@host playbook-project]$ cd roles


[user@host roles]$ ansible-galaxy init my_new_role
- my_new_role was created successfully
[user@host roles]$ ls my_new_role/
defaults files handlers meta README.md tasks templates tests vars

Definición del contenido de los roles


Una vez que haya creado la estructura de directorios, debe escribir el contenido del rol. Un buen
lugar para comenzar es el archivo de tareas ROLENAME/tasks/main.yml, la lista principal de
tareas ejecutadas por el rol.

El siguiente archivo tasks/main.yml gestiona el archivo /etc/motd en los hosts administrados.


Usa el módulo template para implementar la plantilla denominada motd.j2 en el host
administrado. Como el módulo template se configura dentro de una tarea de rol, la plantilla
motd.j2 se recupera del subdirectorio templates del rol, y no de una tarea de guía.

[user@host ~]$ cat roles/motd/tasks/main.yml


---
# tasks file for motd

- name: deliver motd file


template:
src: motd.j2

RH294-RHEL8.0-es-1-20200501 315
capítulo 8 | Simplificación de guías con roles

dest: /etc/motd
owner: root
group: root
mode: 0444

El siguiente comando muestra el contenido de la plantilla motd.j2 del rol motd. Menciona datos
de Ansible y una variable system_owner.

[user@host ~]$ cat roles/motd/templates/motd.j2


This is the system {{ ansible_facts['hostname'] }}.

Today's date is: {{ ansible_facts['date_time']['date'] }}.

Only use this system with permission.


You can ask {{ system_owner }} for access.

El rol define un valor predeterminado para la variable system_owner. El archivo defaults/


main.yml de la estructura de directorio del rol es donde se configura este valor.

El siguiente archivo defaults/main.yml configura la variable system_owner como


[email protected]. Esta será la dirección de correo electrónico que se escribe en el
archivo /etc/motd de hosts administrados al que se aplica este rol.

[user@host ~]$ cat roles/motd/defaults/main.yml


---
system_owner: [email protected]

Prácticas recomendadas para el desarrollo de contenido de rol


Los roles permiten que las guías se escriban de manera modular. Para maximizar la eficacia de los
roles recién desarrollados, considere implementar las siguientes prácticas recomendadas en el
desarrollo de roles:

• Mantenga cada rol en su propio repositorio de control de versiones. Ansible funciona bien con
repositorios basados en git.

• La información confidencial, como las contraseñas o claves SSH, no debe almacenarse en


el repositorio de roles. Los valores confidenciales deben parametrizarse como variables con
valores predeterminados que no son confidenciales. Las guías que usan el rol son responsables
de definir variables sensibles a través de archivos de variables de Ansible Vault, variables de
entorno u otras opciones de ansible-playbook.

• Use ansible-galaxy init para iniciar su rol y elimine los directorios y archivos que no
necesite.

• Cree y mantenga los archivos README.md y meta/main.yml para documentar para qué sirve
su rol, quién lo escribió y cómo usarlo.

• Mantenga su rol enfocado en un propósito o una función específicos. En lugar de escribir un rol
que haga muchas cosas, puede escribir más de un rol.

• Reutilice y refactorice los roles a menudo. Evite crear nuevos roles para las configuraciones
perimetrales. Si un rol existente sirve para la mayoría de la configuración requerida, refactorice
el rol existente para integrar el nuevo escenario de configuración. Use técnicas de prueba
de integración y regresión para asegurarse de que el rol proporcione la nueva funcionalidad
requerida y que no cause problemas a las guías existentes.

316 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Definición de las dependencias del rol


Las dependencias del rol permiten que un rol incluya otros roles como dependencias. Por ejemplo,
un rol que define un servidor de documentación puede depender de otro rol que instale y
configure un servidor web. Las dependencias se definen en el archivo meta/main.yml en la
jerarquía del directorio del rol.

El siguiente es un archivo meta/main.yml de muestra.

---
dependencies:
- role: apache
port: 8080
- role: postgres
dbname: serverlist
admin_user: felix

De manera predeterminada, los roles se agregan solamente como una dependencia a


una guía solo una vez. Si otro rol también lo enumera como una dependencia, no se lo
ejecutará nuevamente. Este comportamiento se puede reemplazar estableciendo la variable
allow_duplicates como yes en el archivo meta/main.yml.

Importante
Limite las dependencias del rol en otros roles. Las dependencias dificultan el
mantenimiento del rol, en especial si tiene muchas dependencias complejas.

Uso del rol en una guía


Para acceder a un rol, menciónelo en la sección roles: de una reproducción. La siguiente guía
se refiere al rol motd. Debido a que no se especifican variables, el rol se aplica con sus valores de
variables predeterminados.

[user@host ~]$ cat use-motd-role.yml


---
- name: use motd role playbook
hosts: remote.example.com
remote_user: devops
become: true
roles:
- motd

Al ejecutarse la guía, las tareas realizadas por un rol se pueden identificar por el prefijo del nombre
del rol. En el siguiente ejemplo de salida, se muestra esto con el prefijo motd : en el nombre de la
tarea:

[user@host ~]$ ansible-playbook -i inventory use-motd-role.yml

PLAY [use motd role playbook] **************************************************

TASK [setup] *******************************************************************


ok: [remote.example.com]

RH294-RHEL8.0-es-1-20200501 317
capítulo 8 | Simplificación de guías con roles

TASK [motd : deliver motd file] ************************************************


changed: [remote.example.com]

PLAY RECAP *********************************************************************


remote.example.com : ok=2 changed=1 unreachable=0 failed=0

En el escenario anterior, se supone que el rol motd se encuentra en el directorio roles. Más
adelante en el curso, verá cómo usar un rol remoto en un repositorio de control de versiones.

Cambio del comportamiento de un rol con variables


Un rol bien redactado usa variables predeterminadas para alterar el comportamiento del rol para
que coincida con un escenario de configuración relacionado. Esto ayuda a que el rol sea más
genérico y reutilizable en una variedad de contextos.

El valor de cualquier variable definida en el directorio defaults de un rol se sobrescribirá si se


define esa misma variable:

• en un archivo de inventario, como una variable de host o una variable de grupo

• en un archivo YAML en los directorios group_vars o host_vars de un proyecto de guía

• como una variable anidada en la palabra clave vars de una reproducción

• como una variable cuando se incluye el rol en la palabra clave roles de una reproducción

En el siguiente ejemplo, se muestra cómo usar el rol motd con un valor diferente para la variable
del rol system_owner. El valor especificado, [email protected], reemplazará a la
referencia de variable cuando se aplique el rol a un host administrado.

[user@host ~]$ cat use-motd-role.yml


---
- name: use motd role playbook
hosts: remote.example.com
remote_user: devops
become: true
vars:
system_owner: [email protected]
roles:
- role: motd

Cuando se define de esta manera, la variable system_owner reemplaza el valor de la variable


predeterminada del mismo nombre. Todas las definiciones de variables anidadas dentro de la
palabra clave vars no reemplazarán el valor de la misma variable si se la define en el directorio
vars de un rol.

El siguiente ejemplo también muestra cómo usar el rol motd con un valor diferente para la variable
del rol system_owner. El valor especificado, [email protected], reemplazará
la referencia de variable independientemente de que esté definida en el directorio vars o
defaults del rol.

[user@host ~]$ cat use-motd-role.yml


---
- name: use motd role playbook
hosts: remote.example.com
remote_user: devops

318 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

become: true
roles:
- role: motd
system_owner: [email protected]

Importante
La precedencia de variables puede causar confusión al trabajar con variables de rol
en una reproducción.

• Casi cualquier otra variable anulará las variables predeterminadas de un rol:


variables de inventario, vars de reproducción, parámetros de rol en línea, etc.

• Menos variables pueden anular las variables definidas en el directorio vars


de un rol. Los datos, las variables cargadas con include_vars, las variables
registradas y los parámetros de rol son algunas de las variables que pueden
hacer eso. Las variables de inventario y vars de reproducción no pueden
hacerlo. Esto es importante porque ayuda a evitar que la reproducción modifique
accidentalmente el funcionamiento interno del rol.

• No obstante, las variables declaradas en línea como parámetros de rol, como en


el último de los ejemplos anteriores, tienen precedencia muy alta. Pueden anular
las variables definidas en el directorio vars de un rol. Si un parámetro de rol tiene
el mismo nombre que una variable establecida en vars de la reproducción, un
vars de rol o una variable de inventario o guía, el parámetro de rol anulará a la
otra variable.

Referencias
Uso de roles — Documentación de Ansible
https://docs.ansible.com/ansible/latest/user_guide/
playbooks_reuse_roles.html#using-roles

Uso de variables — Documentación de Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

RH294-RHEL8.0-es-1-20200501 319
capítulo 8 | Simplificación de guías con roles

Ejercicio Guiado

Creación de roles
En este ejercicio, creará un rol de Ansible que usa variables, archivos, plantillas, tareas y
manejadores para implementar un servicio de red.

Resultados
Debe ser capaz de crear un rol que use variables y parámetros.

El rol myvhost instala y configura el servicio Apache en un host. Se provee una plantilla
llamada vhost.conf.j2 que se usará para generar /etc/httpd/conf.d/vhost.conf.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab role-create start. Esto crea el directorio


de trabajo, /home/student/role-create, y lo completa con un archivo de configuración
de Ansible y un inventario de hosts.

[student@workstation ~]$ lab role-create start

1. Cambie al directorio de trabajo /home/student/role-create.

[student@workstation ~]$ cd ~/role-create


[student@workstation role-create]$

2. Cree la estructura de directorio para un rol denominado myvhost. El rol incluye archivos,
plantillas, tareas y manejadores corregidos.

[student@workstation role-create]$ mkdir -v roles; cd roles


mkdir: created directory 'roles'
[student@workstation roles]$ ansible-galaxy init myvhost
- myvhost was created successfully
[student@workstation roles]$ rm -rvf myvhost/{defaults,vars,tests}
removed 'myvhost/defaults/main.yml'
removed directory: 'myvhost/defaults'
removed 'myvhost/vars/main.yml'
removed directory: 'myvhost/vars'
removed 'myvhost/tests/inventory'
removed 'myvhost/tests/test.yml'
removed directory: 'myvhost/tests'
[student@workstation roles]$ cd ..
[student@workstation role-create]$

3. Edite el archivo main.yml en el subdirectorio tasks del rol. El rol debe ejecutar las
siguientes tareas:

320 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

• Instalar el paquete httpd

• Que el servicio httpd se inicie y se habilite

• Instalar el archivo de configuración del servidor web, con una plantilla proporcionada por
el rol

3.1. Edite el archivo roles/myvhost/tasks/main.yml. Incluya el código para usar el


módulo yum a fin de instalar el paquete httpd. El contenido del archivo debe verse de
la siguiente forma:

---
# tasks file for myvhost

- name: Ensure httpd is installed


yum:
name: httpd
state: latest

3.2. Agregue código adicional al archivo roles/myvhost/tasks/main.yml para usar


el módulo service con el objeto de iniciar y habilitar el servicio httpd.

- name: Ensure httpd is started and enabled


service:
name: httpd
state: started
enabled: true

3.3. Agregue otra estrofa para usar el módulo template a fin de crear /etc/httpd/
conf.d/vhost.conf en el host administrado. Debe invocar un manejador para
reiniciar el daemon httpd cuando se actualiza el archivo.

- name: vhost file is installed


template:
src: vhost.conf.j2
dest: /etc/httpd/conf.d/vhost.conf
owner: root
group: root
mode: 0644
notify:
- restart httpd

3.4. Guarde sus cambios y salga del archivo roles/myvhost/tasks/main.yml.

4. Cree el manejador para reiniciar el servicio httpd. Edite el archivo roles/myvhost/


handlers/main.yml e incluya el código para usar el módulo service, luego guarde el
archivo y salga. El contenido del archivo debe verse de la siguiente forma:

RH294-RHEL8.0-es-1-20200501 321
capítulo 8 | Simplificación de guías con roles

---
# handlers file for myvhost

- name: restart httpd


service:
name: httpd
state: restarted

5. Mueva la plantilla vhost.conf.j2 del directorio del proyecto al subdirectorio templates


del rol.

[student@workstation role-create]$ mv -v vhost.conf.j2 roles/myvhost/templates/


renamed 'vhost.conf.j2' -> 'roles/myvhost/templates/vhost.conf.j2'

6. Cree el contenido HTML que alojará el servidor web.

6.1. Cree el directorio files/html/ para almacenar el contenido.

[student@workstation role-create]$ mkdir -pv files/html


mkdir: created directory 'files/html'

6.2. Cree un archivo index.html debajo del directorio con el contenido: simple
index.

[student@workstation role-create]$ echo \


> 'simple index' > files/html/index.html

7. Pruebe el rol myvhost para asegurarse de que funciona adecuadamente.

7.1. Escriba una guía que use el rol, denominada use-vhost-role.yml. Incluya una
tarea para copiar el contenido HTML de files/html/. Use el módulo copy e
incluya una barra oblicua final después del nombre del directorio fuente. Debe incluir
el siguiente contenido:

---
- name: Use myvhost role playbook
hosts: webservers
pre_tasks:
- name: pre_tasks message
debug:
msg: 'Ensure web server configuration.'

roles:
- myvhost

post_tasks:
- name: HTML content is installed
copy:
src: files/html/
dest: "/var/www/vhosts/{{ ansible_hostname }}"

322 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

- name: post_tasks message


debug:
msg: 'Web server is configured.'

7.2. Antes de ejecutar la guía, ejecute ansible-playbook con --syntax-check para


verificar que su sintaxis sea correcta. Si informa errores, corríjalos antes de pasar al
siguiente paso. Debe ver una salida similar a la siguiente:

[student@workstation role-create]$ ansible-playbook use-vhost-role.yml \


> --syntax-check

playbook: use-vhost-role.yml

7.3. Ejecute la guía. Revise la salida para confirmar que Ansible realizó las acciones en el
servidor web, servera.

[student@workstation role-create]$ ansible-playbook use-vhost-role.yml

PLAY [Use myvhost role playbook] *********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [pre_tasks message] *****************************************************


ok: [servera.lab.example.com] => {
"msg": "Ensure web server configuration."
}

TASK [myvhost : Ensure httpd is installed] ***********************************


changed: [servera.lab.example.com]

TASK [myvhost : Ensure httpd is started and enabled] *************************


changed: [servera.lab.example.com]

TASK [myvhost : vhost file is installed] *************************************


changed: [servera.lab.example.com]

RUNNING HANDLER [myvhost : restart httpd] ************************************


changed: [servera.lab.example.com]

TASK [HTML content is installed] ***********************************


changed: [servera.lab.example.com]

TASK [post_tasks message] ****************************************************


ok: [servera.lab.example.com] => {
"msg": "Web server is configured."
}

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=8 changed=5 unreachable=0 failed=0

7.4. Ejecute los comandos ad hoc para confirmar que el rol funcionó. El paquete httpd
debe instalarse y el servicio httpd debe estar ejecutándose.

RH294-RHEL8.0-es-1-20200501 323
capítulo 8 | Simplificación de guías con roles

[student@workstation role-create]$ ansible webservers -a \


> 'systemctl is-active httpd'
servera.lab.example.com | CHANGED | rc=0 >>
active

[student@workstation role-create]$ ansible webservers -a \


> 'systemctl is-enabled httpd'
servera.lab.example.com | CHANGED | rc=0 >>
enabled

7.5. La configuración Apache debe estar instalada con las variables de plantilla ampliadas.

[student@workstation role-create]$ ansible webservers -a \


> 'cat /etc/httpd/conf.d/vhost.conf'
servera.lab.example.com | CHANGED | rc=0 >>
# Ansible managed:

<VirtualHost *:80>
ServerAdmin [email protected]
ServerName servera.lab.example.com
ErrorLog logs/servera-error.log
CustomLog logs/servera-common.log common
DocumentRoot /var/www/vhosts/servera/

<Directory /var/www/vhosts/servera/>
Options +Indexes +FollowSymlinks +Includes
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

7.6. El contenido HTML debe encontrarse en un directorio denominado /var/www/


vhosts/servera. El archivo index.html debe contener la cadena “simple index”.

[student@workstation role-create]$ ansible webservers -a \


> 'cat /var/www/vhosts/servera/index.html'
servera.lab.example.com | CHANGED | rc=0 >>
simple index

7.7. Use el módulo uri en un comando ad hoc para verificar que el contenido web esté
disponible localmente. Configure el parámetro return_content en true para
agregar el contenido de la respuesta del servidor a la salida. El contenido del servidor
debe ser la cadena "simple index\n".

[student@workstation role-create]$ ansible webservers -m uri \


> -a 'url=http://localhost return_content=true'
servera.lab.example.com | SUCCESS => {
"accept_ranges": "bytes",
"changed": false,
"connection": "close",
"content": "simple index\n",
...output omitted...

324 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

"status": 200,
"url": "http://localhost"
}

7.8. Confirme que el contenido del servidor web esté disponible para clientes remotos.

[student@workstation role-create]$ curl http://servera.lab.example.com


simple index

Finalizar
Ejecute el comando lab role-create finish para limpiar el host administrado.

[student@workstation ~]$ lab role-create finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 325
capítulo 8 | Simplificación de guías con roles

Implementación de roles con Ansible


Galaxy

Objetivos
Tras haber completado esta sección, debe ser capaz de seleccionar y recuperar roles de Ansible
Galaxy u otras fuentes como un repositorio de Git, y usarlos en guías.

Presentación de Ansible Galaxy


Ansible Galaxy [https://galaxy.ansible.com] es una librería pública de contenido de Ansible
programada por una variedad de administradores y usuarios de Ansible. Contiene miles de roles
de Ansible y cuenta con una base de datos de búsqueda que ayuda a los usuarios de Ansible a
identificar roles que podrían ayudarlos a realizar una tarea administrativa. Ansible Galaxy incluye
enlaces a la documentación y videos para nuevos usuarios y desarrolladores de roles de Ansible.

Figura 8.1: Página de inicio de Ansible Galaxy

Además, el comando ansible-galaxy que utiliza para obtener y administrar roles de Ansible
Galaxy también se puede usar para obtener y administrar roles que sus proyectos necesitan de sus
propios repositorios Git.

Ayuda con Ansible Galaxy


La pestaña Documentation en la página de inicio del sitio web de Ansible Galaxy conduce a una
página que describe cómo usar Ansible Galaxy. Hay contenido que describe cómo descargar y
usar roles desde Ansible Galaxy. En esta página, también se encuentran instrucciones de cómo
desarrollar roles y cargarlos a Ansible Galaxy.

Búsqueda de roles en Ansible Galaxy


La pestaña Search del lado izquierdo de la página de inicio del sitio web Ansible Galaxy le da a
los usuarios acceso a información acerca de los roles publicados en Ansible Galaxy. Puede buscar
un rol de Ansible por nombre, con etiquetas o por otros atributos de roles. Los resultados se

326 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

presentan en orden descendente por puntuación de Mejor coincidencia, que se calcula en


función de la calidad del rol, la popularidad del rol y los criterios de búsqueda.

nota
Puntuación de contenido [https://galaxy.ansible.com/docs/contributing/
content_scoring.html] en la documentación tiene más información sobre la
puntuación de los roles de Ansible Galaxy.

Figura 8.2: Pantalla de búsqueda de Ansible Galaxy

Ansible Galaxy informa la cantidad de veces que se ha descargado cada rol de Ansible Galaxy.
Además, Ansible Galaxy también informa la cantidad de visualizaciones, bifurcaciones y estrellas
que tiene el repositorio de GitHub del rol. Los usuarios pueden usar esta información para ayudar
a determinar qué tan activo es el desarrollo para un rol y qué tan popular es en la comunidad.

En la siguiente figura, se muestran los resultados de la búsqueda que Ansible Galaxy mostró
después de buscar la palabra clave redis. El primer resultado tiene una puntuación de Mejor
coincidencia de 0,9009.

RH294-RHEL8.0-es-1-20200501 327
capítulo 8 | Simplificación de guías con roles

Figura 8.3: Ejemplo de resultados de búsqueda de Ansible Galaxy

El menú desplegable Filters (Filtros) a la derecha del cuadro de búsqueda permite realizar
búsquedas por palabras clave, ID de autor, plataforma y etiquetas. Los posibles valores de
la plataforma incluyen EL para Red Hat Enterprise Linux (y distribuciones estrechamente
relacionadas como CentOS) y Fedora, entre otros.

Las etiquetas son cadenas arbitrarias de una palabra establecidas por el autor del rol que
describen y categorizan el rol. Los usuarios pueden usar etiquetas para encontrar roles relevantes.
Los posibles valores de las etiquetas incluyen system, development, web, monitoring y otros.
Un rol puede tener hasta 20 etiquetas en Ansible Galaxy.

Importante
En la interfaz de búsqueda de Ansible Galaxy, las búsquedas por palabra clave
coinciden con las palabras o frases del archivo README, el nombre del contenido o
la descripción del contenido. Las búsquedas por etiqueta, por el contrario, coinciden
específicamente con los valores de las etiquetas establecidos por el autor para el
rol.

Herramienta de línea de comando de Ansible Galaxy


La herramienta de línea de comando ansible-galaxy se puede utilizar para buscar, instalar,
enumerar, eliminar o iniciar roles, así como para mostrar información acerca de ellos.

Búsqueda de roles desde la línea de comando


El subcomando ansible-galaxy search busca roles en Ansible Galaxy. Si especifica una
cadena como argumento, se usa para buscar roles en Ansible Galaxy por palabra clave. Puede
usar las opciones --author, --platforms y --galaxy-tags para acotar los resultados de la
búsqueda. También puede usar esas opciones como término de búsqueda principal. Por ejemplo,
el comando ansible-galaxy search --author geerlingguy mostrará todos los roles
enviados por el usuario geerlingguy.

Los resultados se muestran en orden alfabético, no en orden descendente por Mejor


coincidencia. En el ejemplo siguiente, se muestran los nombres de los roles que incluyen
redis y están disponibles para la plataforma Enterprise Linux (EL).

328 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

[user@host ~]$ ansible-galaxy search 'redis' --platforms EL

Found 124 roles matching your search:

Name Description
---- -----------
1it.sudo Ansible role for managing sudoers
AerisCloud.librato Install and configure the Librato Agent
AerisCloud.redis Installs redis on a server
AlbanAndrieu.java Manage Java installation
andrewrothstein.redis builds Redis from src and installs
...output omitted...
geerlingguy.php-redis PhpRedis support for Linux
geerlingguy.redis Redis for Linux
gikoluo.filebeat Filebeat for Linux.
...output omitted...

El subcomando ansible-galaxy info muestra información más detallada acerca de un rol.


Ansible Galaxy obtiene esta información de varios lugares, incluido el archivo meta/main.yml
del rol y su repositorio de GitHub. El siguiente comando muestra información acerca del rol
geerlingguy.redis, disponible desde Ansible Galaxy.

[user@host ~]$ ansible-galaxy info geerlingguy.redis

Role: geerlingguy.redis
description: Redis for Linux
active: True
...output omitted...
download_count: 146209
forks_count: 82
github_branch: master
github_repo: ansible-role-redis
github_user: geerlingguy
...output omitted...
license: license (BSD, MIT)
min_ansible_version: 2.4
modified: 2018-11-19T14:53:29.722718Z
open_issues_count: 11
path: [u'/etc/ansible/roles', u'/usr/share/ansible/roles']
role_type: ANS
stargazers_count: 98
...output omitted...

Instalación de roles desde Ansible Galaxy


El subcomando ansible-galaxy install descarga un rol de Ansible Galaxy y lo instala a nivel
local en el nodo de control.

De manera predeterminada, los roles se instalan en el primer directorio que se puede escribir en
el roles_path del usuario. Según el roles_path predeterminado configurado para Ansible,
normalmente el rol se instalará en el directorio ~/.ansible/roles del usuario. El roles_path
predeterminado puede ser anulado por el archivo de configuración actual de Ansible o por la

RH294-RHEL8.0-es-1-20200501 329
capítulo 8 | Simplificación de guías con roles

variable de entorno ANSIBLE_ROLES_PATH, lo que afecta el comportamiento de ansible-


galaxy.

También puede especificar un directorio específico para instalar el rol utilizando la opción -p
DIRECTORY.

En el siguiente ejemplo, ansible-galaxy instala el rol geerlingguy.redis en el directorio


roles de un proyecto de guía. El directorio de trabajo actual del comando es /opt/project.

[user@host project]$ ansible-galaxy install geerlingguy.redis -p roles/


- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/...output omitted...
- extracting geerlingguy.redis to /opt/project/roles/geerlingguy.redis
- geerlingguy.redis (1.6.0) was installed successfully
[user@host project]$ ls roles/
geerlingguy.redis

Instalación de roles con un archivo de requisitos


También puede usar ansible-galaxy para instalar una lista de roles basados en definiciones
en un archivo de texto. Por ejemplo, si tiene una guía en la que se deben instalar roles específicos,
puede crear un archivo roles/requirements.yml en el directorio del proyecto que especifica
los roles que son necesarios. Este archivo actúa como manifiesto de dependencias para el
proyecto de guía, lo que permite desarrollar y probar las guías por separado desde cualquier rol de
soporte.

Por ejemplo, un simple requirements.yml para instalar geerlingguy.redis podría decir:

- src: geerlingguy.redis
version: "1.5.0"

El atributo src especifica la fuente del rol, en este caso, el rol geerlingguy.redis de Ansible
Galaxy. El atributo version es opcional y especifica la versión del rol que se instalará, en este
caso, 1.5.0.

Importante
Debe especificar la versión del rol en su archivo requirements.yml, en especial
para las guías en producción.

Si no especifica una versión, obtendrá la última versión del rol. Si el autor en sentido
ascendente realiza cambios en el rol que son incompatibles con su guía, puede
causar una falla de automatización u otros problemas.

Para instalar los roles con un archivo de roles, use la opción -r REQUIREMENTS-FILE:

[user@host project]$ ansible-galaxy install -r roles/requirements.yml \


> -p roles
- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-redis/
archive/1.6.0.tar.gz
- extracting geerlingguy.redis to /opt/project/roles/geerlingguy.redis
- geerlingguy.redis (1.6.0) was installed successfully

330 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Puede usar ansible-galaxy para instalar roles que no están en Ansible Galaxy. Puede alojar
sus propios roles internos o propietarios en un repositorio privado de Git o en un servidor web.
En el siguiente ejemplo, se muestra cómo configurar un archivo de requisitos con una variedad de
fuentes remotas.

[user@host project]$ cat roles/requirements.yml


# from Ansible Galaxy, using the latest version
- src: geerlingguy.redis

# from Ansible Galaxy, overriding the name and using a specific version
- src: geerlingguy.redis
version: "1.5.0"
name: redis_prod

# from any Git-based repository, using HTTPS


- src: https://gitlab.com/guardianproject-ops/ansible-nginx-acme.git
scm: git
version: 56e00a54
name: nginx-acme

# from any Git-based repository, using SSH


- src: [email protected]:guardianproject-ops/ansible-nginx-acme.git
scm: git
version: master
name: nginx-acme-ssh

# from a role tar ball, given a URL;


# supports 'http', 'https', or 'file' protocols
- src: file:///opt/local/roles/myrole.tar
name: myrole

La palabra clave src especifica el nombre de rol de Ansible Galaxy. Si el rol no está alojado en
Ansible Galaxy, la palabra clave src indica la URL del rol.

Si el rol está alojado en un repositorio de control de origen, se necesita el atributo scm. El


comando ansible-galaxy es capaz de descargar e instalar roles desde un repositorio de
software basado en Git o en Mercurial. Un repositorio basado en Git requiere un valor scm de
git, mientras que un rol alojado en un repositorio Mercurial requiere un valor de hg. Si el rol está
alojado en Ansible Galaxy o como una colección de archivos tar en un servidor web, se omite la
palabra clave scm.

La palabra clave name se utiliza para anular el nombre local del rol. La palabra clave version se
utiliza para especificar la versión de un rol. La palabra clave version puede tener cualquier valor
que corresponda a una bifurcación, etiqueta o hash de confirmación del repositorio de software
del rol.

Para instalar los roles asociados con un proyecto de guía, ejecute el comando ansible-galaxy
install:

[user@host project]$ ansible-galaxy install -r roles/requirements.yml \


> -p roles
- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-redis/
archive/1.6.0.tar.gz

RH294-RHEL8.0-es-1-20200501 331
capítulo 8 | Simplificación de guías con roles

- extracting geerlingguy.redis to /opt/project/roles/geerlingguy.redis


- geerlingguy.redis (1.6.0) was installed successfully
- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-redis/
archive/1.5.0.tar.gz
- extracting redis_prod to /opt/project/roles/redis_prod
- redis_prod (1.5.0) was installed successfully
- extracting nginx-acme to /opt/project/roles/nginx-acme
- nginx-acme (56e00a54) was installed successfully
- extracting nginx-acme-ssh to /opt/project/roles/nginx-acme-ssh
- nginx-acme-ssh (master) was installed successfully
- downloading role from file:///opt/local/roles/myrole.tar
- extracting myrole to /opt/project/roles/myrole
- myrole was installed successfully

Gestión de roles descargados


El comando ansible-galaxy también puede administrar roles locales, como aquellos que se
encuentran en el directorio roles de un proyecto de guía. El subcomando ansible-galaxy
list enumera los roles que se encuentran a nivel local.

[user@host project]$ ansible-galaxy list


- geerlingguy.redis, 1.6.0
- myrole, (unknown version)
- nginx-acme, 56e00a54
- nginx-acme-ssh, master
- redis_prod, 1.5.0

Un rol se puede eliminar de manera local con el subcomando ansible-galaxy remove.

[user@host ~]$ ansible-galaxy remove nginx-acme-ssh


- successfully removed nginx-acme-ssh
[user@host ~]$ ansible-galaxy list
- geerlingguy.redis, 1.6.0
- myrole, (unknown version)
- nginx-acme, 56e00a54
- redis_prod, 1.5.0

Los roles descargados e instalados se pueden utilizar en guías como cualquier otro rol. Pueden
mencionarse en la sección roles utilizando el nombre de rol de descarga. Si un rol no está en
el directorio roles del proyecto, el roles_path se verificará para ver si el rol está instalado en
uno de esos directorios; se usará la primera coincidencia. La siguiente guía use-role.yml hace
referencia a los roles redis_prod y geerlingguy.redis:

[user@host project]$ cat use-role.yml


---
- name: use redis_prod for Prod machines
hosts: redis_prod_servers
remote_user: devops
become: true
roles:
- redis_prod

332 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

- name: use geerlingguy.redis for Dev machines


hosts: redis_dev_servers
remote_user: devops
become: true
roles:
- geerlingguy.redis

Esta guía hace que diferentes versiones del rol geerlingguy.redis se apliquen a los servidores
de producción y desarrollo. De esta manera, los cambios en el rol se pueden probar e integrar
sistemáticamente antes de la implementación en los servidores de producción. Si un cambio
reciente en un rol causa problemas, usar el control de versiones para desarrollar el rol permite
revertirlo a una versión anterior y estable.

Referencias
Ansible Galaxy — Documentación Ansible
https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html

RH294-RHEL8.0-es-1-20200501 333
capítulo 8 | Simplificación de guías con roles

Ejercicio Guiado

Implementación de roles con Ansible


Galaxy
En este ejercicio, utilizará Ansible Galaxy para descargar e instalar un rol de Ansible.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• crear un archivo de roles para especificar las dependencias de roles para una guía

• instalar roles especificados en un archivo de roles

• enumerar roles con el comando ansible-galaxy

Descripción general del escenario


Su organización coloca archivos personalizados en el directorio /etc/skel en todos los
hosts. Como resultado, las nuevas cuentas de usuario se configuran con un entorno Bash
estandarizado específico de la organización.

Probará la versión de desarrollo del rol de Ansible responsable de la implementación de


archivos de esqueleto del entorno Bash.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el comando lab role-galaxy start. Esto crea el directorio


de trabajo, /home/student/role-galaxy, y lo completa con un archivo de configuración
de Ansible y un inventario de hosts.

[student@workstation ~]$ lab role-galaxy start

1. Cambie al directorio de trabajo role-galaxy.

[student@workstation ~]$ cd ~/role-galaxy


[student@workstation role-galaxy]$

2. Para probar el rol de Ansible que configura los archivos de esqueleto, agregue la
especificación de rol a un archivo de roles.
Ejecute su editor de texto favorito y cree un archivo denominado
requirements.yml en el subdirectorio roles. La URL del repositorio Git del rol es:
[email protected]:student/bash_env. Para ver cómo el rol
afecta el comportamiento de los hosts de producción, use la bifurcación master del
repositorio. Establezca el nombre local del rol en student.bash_env.
roles/requirements.yml ahora incluye el siguiente contenido:

334 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

---
# requirements.yml

- src: [email protected]:student/bash_env
scm: git
version: master
name: student.bash_env

3. Use el comando ansible-galaxy para procesar el archivo de roles que recién creó e
instalar el rol student.bash_env.

3.1. Para comparar, muestre el contenido del subdirectorio roles antes de que se instale
el rol.

[student@workstation role-galaxy]$ ls roles/


requirements.yml

3.2. Use Ansible Galaxy para descargar e instalar los roles enumerados en el archivo
roles/requirements.yml. Asegúrese de que los roles descargados se almacenen
en el subdirectorio roles.

[student@workstation role-galaxy]$ ansible-galaxy install -r \


> roles/requirements.yml -p roles
- extracting student.bash_env to /home/student/role-galaxy/roles/student.bash_env
- student.bash_env (master) was installed successfully

3.3. Exhiba el subdirectorio roles después de que se haya instalado el rol. Confirme que
tiene un nuevo subdirectorio, denominado student.bash_env, que coincide con el
valor de name especificado en el archivo YAML.

[student@workstation role-galaxy]$ ls roles/


requirements.yml student.bash_env

3.4. Intente usar el comando ansible-galaxy, sin ninguna opción, para enumerar los
roles del proyecto:

[student@workstation role-galaxy]$ ansible-galaxy list


# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.

RH294-RHEL8.0-es-1-20200501 335
capítulo 8 | Simplificación de guías con roles

Como usó la opción -p con el comando ansible-galaxy install, el rol


student.bash_env no se instaló en la ubicación predeterminada. Use la opción -p
con el comando ansible-galaxy list para enumerar los roles descargados:

[student@workstation role-galaxy]$ ansible-galaxy list -p roles


# /home/student/role-galaxy/roles
- student.bash_env, master
...output omitted...
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.

nota
El directorio /home/student/.ansible/roles está en el roles_path
predeterminado, pero como no ha intentado instalar un rol sin usar la opción -p,
ansible-galaxy aún no ha creado el directorio.

4. Cree una guía, denominada use-bash_env-role.yml, la cual usa el rol


student.bash_env. El contenido de la guía debe coincidir con lo siguiente:

---
- name: use student.bash_env role playbook
hosts: devservers
vars:
default_prompt: '[\u on \h in \W dir]\$ '
pre_tasks:
- name: Ensure test user does not exist
user:
name: student2
state: absent
force: yes
remove: yes

roles:
- student.bash_env

post_tasks:
- name: Create the test user
user:
name: student2
state: present
password: "{{ 'redhat' | password_hash('sha512', 'mysecretsalt') }}"

Para ver los efectos del cambio de configuración, se debe crear una nueva cuenta de
usuario. Las secciones pre_tasks y post_tasks de la guía garantizan que la cuenta de
usuario student2 se crea cada vez que se ejecuta la guía. Después de la ejecución de la
guía, se accede a la cuenta student2 con la contraseña redhat.

nota
La contraseña de user2 se genera con un filtro. Los filtros toman datos y
los modifican; aquí, la cadena redhat se modifica al pasarla por el módulo
password_hash. Los filtros son un tema avanzado que no se trata en este curso.

336 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

5. Ejecute la guía. El rol student.bash_env crea archivos de configuración de plantillas


estándares en /etc/skel en el host administrado. Los archivos que crea incluyen
.bashrc, .bash_profile y .vimrc.

[student@workstation role-galaxy]$ ansible-playbook use-bash_env-role.yml

PLAY [use student.bash_env role playbook] ************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Ensure test user does not exist] ***************************************


ok: [servera.lab.example.com]

TASK [student.bash_env : put away .bashrc] ***********************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .bash_profile] *****************************


ok: [servera.lab.example.com]

TASK [student.bash_env : put away .vimrc] ************************************


changed: [servera.lab.example.com]

TASK [Create the test user] **************************************************


changed: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=4 unreachable=0 failed=0

6. Conéctese a servera como el usuario student2 utilizando SSH. Observe el aviso


personalizado para el usuario student2 y desconéctese de servera.

[student@workstation role-galaxy]$ ssh student2@servera


Activate the web console with: systemctl enable --now cockpit.socket

[student2 on servera in ~ dir]$ exit


logout
Connection to servera closed.
[student@workstation role-galaxy]$

7. Ejecute la guía usando la versión de desarrollo del rol student.bash_env.


La versión de desarrollo del rol se encuentra en la bifurcación dev del repositorio Git. La
versión de desarrollo del rol usa una nueva variable, prompt_color. Antes de ejecutar la
guía, agregue la variable prompt_color a la sección vars de la guía y establezca su valor
en blue.

7.1. Actualice el archivo roles/requirements.yml y establezca el valor de version


en dev. El archivo roles/requirements.yml ahora contiene:

RH294-RHEL8.0-es-1-20200501 337
capítulo 8 | Simplificación de guías con roles

---
# requirements.yml

- src: [email protected]:student/bash_env
scm: git
version: dev
name: student.bash_env

7.2. Use el comando ansible-galaxy install para instalar el rol con el archivo
de roles actualizado. Use la opción --force para sobrescribir la versión master
existente del rol con la versión dev del rol.

[student@workstation role-galaxy]$ ansible-galaxy install \


> -r roles/requirements.yml --force -p roles
- changing role student.bash_env from master to dev
- extracting student.bash_env to /home/student/role-galaxy/roles/student.bash_env
- student.bash_env (dev) was installed successfully

7.3. Edite el archivo use-bash_env-role.yml. Agregue la variable prompt_color con


un valor de blue a la sección vars de la guía. El archivo ahora contiene lo siguiente:

---
- name: use student.bash_env role playbook
hosts: devservers
vars:
prompt_color: blue
default_prompt: '[\u on \h in \W dir]\$ '
pre_tasks:
...output omitted...

7.4. Ejecute la guía use-bash_env-role.yml.

[student@workstation role-galaxy]$ ansible-playbook use-bash_env-role.yml

PLAY [use student.bash_env role playbook] ************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Ensure test user does not exist] ***************************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .bashrc] ***********************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .bash_profile] *****************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .vimrc] ************************************


okay: [servera.lab.example.com]

TASK [Create the test user] **************************************************

338 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

changed: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=4 unreachable=0 failed=0

8. Conéctese de nuevo a servera como el usuario student2 utilizando SSH. Observe el


error para el usuario student2 y desconéctese de servera.

[student@workstation role-galaxy]$ ssh student2@servera


Activate the web console with: systemctl enable --now cockpit.socket

-bash: [: missing `]'


[student2@servera ~]$ exit
logout
Connection to servera closed.
[student@workstation role-galaxy]$

Se produjo un error de Bash al analizar el archivo .bash_profile del usuario student2.

9. Corrija el error en la versión de desarrollo del rol student.bash_env y vuelva a ejecutar la


guía.

9.1. Edite el archivo roles/student.bash_env/templates/_bash_profile.j2.


Agregue el carácter ] faltante a la línea 4 y guarde el archivo. La parte superior del
archivo ahora dice:

# .bash_profile

# Get the aliases and functions


if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

Guarde el archivo.

9.2. Ejecute la guía use-bash_env-role.yml.

[student@workstation role-galaxy]$ ansible-playbook use-bash_env-role.yml

PLAY [use student.bash_env role playbook] ************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Ensure test user does not exist] ***************************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .bashrc] ***********************************

RH294-RHEL8.0-es-1-20200501 339
capítulo 8 | Simplificación de guías con roles

ok: [servera.lab.example.com]

TASK [student.bash_env : put away .bash_profile] *****************************


changed: [servera.lab.example.com]

TASK [student.bash_env : put away .vimrc] ************************************


ok: [servera.lab.example.com]

TASK [Create the test user] **************************************************


changed: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=3 unreachable=0 failed=0

9.3. Conéctese de nuevo a servera como el usuario student2 utilizando SSH.

[student@workstation role-galaxy]$ ssh student2@servera


Activate the web console with: systemctl enable --now cockpit.socket

[student2 on servera in ~ dir]$ exit


logout
Connection to servera closed.
[student@workstation role-galaxy]$

El mensaje de error ya no está presente. El indicador personalizado para el usuario


student2 ahora se muestra con caracteres azules.

Los pasos anteriores demuestran que la versión de desarrollo del rol student.bash_env es
defectuosa. Sobre la base de los resultados de las pruebas, los desarrolladores realizarán las
correcciones necesarias en la bifurcación de desarrollo del rol. Cuando la bifurcación de desarrollo
pasa los controles de calidad requeridos, los desarrolladores combinan las características de la
bifurcación de desarrollo en la bifurcación master.

La confirmación de cambios de rol en un repositorio Git está fuera del alcance de este curso.

Importante
Al rastrear la última versión de un rol en un proyecto, vuelva a instalar el rol
periódicamente para actualizarlo. Esto asegura que la copia local se mantenga
actualizada con correcciones de errores, parches y otras características.

No obstante, si usa un rol de terceros en la producción, especifique la versión


que desea usar para evitar problemas debido a cambios inesperados. Actualícese
periódicamente a la última versión del rol de su entorno de prueba para que pueda
adoptar mejoras y cambios de manera controlada.

Finalizar
Ejecute el comando lab role-galaxy finish para limpiar el host administrado.

[student@workstation ~]$ lab role-galaxy finish

Esto concluye el ejercicio guiado.

340 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Trabajo de laboratorio

Simplificación de guías con roles


Lista de verificación de rendimiento
En este trabajo de laboratorio, creará roles de Ansible que utilizan variables, archivos,
plantillas, tareas y manejadores.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Cree roles de Ansible que utilicen variables, archivos, plantillas, tareas y manejadores para
configurar un servidor web de desarrollo.

• Use un rol que esté alojado en un repositorio remoto de una guía.

• Use un rol de sistema de Red Hat Enterprise Linux en una guía.

Descripción general del escenario


Su organización debe proporcionar un único servidor web para alojar el código de desarrollo
para todos los desarrolladores web. Tiene la tarea de escribir una guía para configurar este
servidor web de desarrollo.

El servidor web de desarrollo debe cumplir varios requisitos:

• La configuración del servidor de desarrollo debe coincidir con la configuración del servidor
de producción. El servidor de producción se debe configurar mediante un rol Ansible,
desarrollado por el equipo de infraestructura de la organización.

• Cada desarrollador recibe un directorio en el servidor de desarrollo para alojar el código


y el contenido. Se accede al contenido de cada desarrollador con un puerto asignado no
estándar.

• SELinux se establece en cumplimiento y dirigido.

Su guía:

• Usará un rol para configurar directorios y puertos para cada desarrollador del servidor web.
Debe escribir este rol.

Este rol depende de un rol escrito por la organización para configurar Apache. Debe definir
la dependencia con la versión v1.4 del rol organizativo. La URL del repositorio de la
dependencia es: [email protected]:infra/apache

• Use el rol rhel-system-roles.selinux para configurar SELinux para los puertos


HTTP no estándares utilizados por el servidor web. Se le proporcionará un archivo de
variable selinux.yml que se puede instalar como un archivo group_vars para pasar la
configuración correcta al rol.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

RH294-RHEL8.0-es-1-20200501 341
capítulo 8 | Simplificación de guías con roles

En workstation, ejecute el comando lab role-review start. El script crea el


directorio de trabajo, denominado /home/student/role-review, y lo completa con un
archivo de configuración Ansible, un inventario de host y otros archivos de laboratorio.

[student@workstation ~]$ lab role-review start

1. Cambie al directorio de trabajo /home/student/role-review.


2. Cree una guía llamada web_dev_server.yml con una sola reproducción denominada
Configure Dev Web Server (Configurar servidor web de desarrollo). Configure la
reproducción para apuntar al grupo de hosts dev_webserver. No agregue ningún rol ni
tarea a la reproducción todavía.
Asegúrese de que la reproducción obligue a los manejadores a ejecutarse, ya que puede
encontrar un error al desarrollar la guía.
3. Verifique la sintaxis de la guía. Ejecute la guía. Se debe aprobar la comprobación de la sintaxis
y la guía debe ejecutarse correctamente.
4. Asegúrese de que las dependencias del rol de la guía estén instaladas.
El rol apache.developer_configs que creará depende del rol infra.apache. Cree
un archivo roles/requirements.yml. Debe instalar el rol desde el repositorio Git
en [email protected]:infra/apache, usar la versión v1.4
y denominarla infra.apache a nivel local. Puede suponer que las claves SSH están
configuradas para permitirle obtener roles de ese repositorio automáticamente. Instale el rol
con el comando ansible-galaxy.
Además, instale el paquete rhel-system-roles, si no está instalado.
5. Inicie un nuevo rol llamado apache.developer_configs en el subdirectorio roles.
Agregue el rol infra.apache como una dependencia para el nuevo rol, usando la misma
información de nombre, fuente, versión y sistema de control de versión del archivo roles/
requirements.yml.
El archivo developer_tasks.yml del directorio del proyecto contiene tareas para el rol.
Mueva este archivo a la ubicación correcta para que sea el archivo de tareas para este rol y
reemplace el archivo existente en esa ubicación.
El archivo developer.conf.j2 del directorio del proyecto es una plantilla de Jinja2
usada por el archivo de tareas. Muévalo a la ubicación correcta para los archivos de plantilla
utilizados por este rol.
6. El rol apache. developer_configs procesará una lista de usuarios definidos en una
variable denominada web_developers. El archivo web_developers.yml del directorio
del proyecto define la variable de lista de usuarios de web_developers. Revise este archivo
y utilícelo para definir la variable web_developers para el grupo de hosts del servidor web
de desarrollo.
7. Agregue el rol apache.developer_configs a la reproducción de la guía
web_dev_server.yml.
8. Verifique la sintaxis de la guía. Ejecute la guía. La verificación de la sintaxis debe aprobarse,
pero la guía debe fallar cuando el rol infra.apache intenta reiniciar Apache HTTPD.
9. Apache HTTPD no pudo reiniciarse en el paso anterior porque los puertos de red que utiliza
para sus desarrolladores están etiquetados con los contextos de SELinux incorrectos. Se
le ha proporcionado un archivo de variables, selinux.yml, que se puede utilizar con el rol
rhel-system-roles.selinux para corregir el problema.

342 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Cree una sección pre_tasks para su reproducción en la guía web_dev_server.yml.


En esa sección, use una tarea para incluir el rol rhel-system-roles.selinux en una
estructura block/rescue para que se lo aplique correctamente. Revise la conferencia o la
documentación de este rol para ver cómo hacer esto.
Inspeccione el archivo selinux.yml. Muévalo a la ubicación correcta, de modo que sus
variables se configuren para el grupo de hosts dev_webserver.
10. Verifique la sintaxis de la guía final. Se debe aprobar la comprobación de la sintaxis.
11. Ejecute la guía. Debe ser capaz de realizarse de manera correcta.
12. Pruebe la configuración del servidor web de desarrollo. Verifique que todos los extremos
sean accesibles y proporcionen el contenido de cada desarrollador.

Evaluación
Evalúe su trabajo ejecutando el comando lab role-review grade de su máquina
workstation. Corrija los errores informados y vuelva a ejecutar el script hasta obtener un
resultado satisfactorio.

[student@workstation ~]$ lab role-review grade

Finalizar
En workstation, ejecute el script lab role-review finish para limpiar este ejercicio.

[student@workstation ~]$ lab role-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 343
capítulo 8 | Simplificación de guías con roles

Solución

Simplificación de guías con roles


Lista de verificación de rendimiento
En este trabajo de laboratorio, creará roles de Ansible que utilizan variables, archivos,
plantillas, tareas y manejadores.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Cree roles de Ansible que utilicen variables, archivos, plantillas, tareas y manejadores para
configurar un servidor web de desarrollo.

• Use un rol que esté alojado en un repositorio remoto de una guía.

• Use un rol de sistema de Red Hat Enterprise Linux en una guía.

Descripción general del escenario


Su organización debe proporcionar un único servidor web para alojar el código de desarrollo
para todos los desarrolladores web. Tiene la tarea de escribir una guía para configurar este
servidor web de desarrollo.

El servidor web de desarrollo debe cumplir varios requisitos:

• La configuración del servidor de desarrollo debe coincidir con la configuración del servidor
de producción. El servidor de producción se debe configurar mediante un rol Ansible,
desarrollado por el equipo de infraestructura de la organización.

• Cada desarrollador recibe un directorio en el servidor de desarrollo para alojar el código


y el contenido. Se accede al contenido de cada desarrollador con un puerto asignado no
estándar.

• SELinux se establece en cumplimiento y dirigido.

Su guía:

• Usará un rol para configurar directorios y puertos para cada desarrollador del servidor web.
Debe escribir este rol.

Este rol depende de un rol escrito por la organización para configurar Apache. Debe definir
la dependencia con la versión v1.4 del rol organizativo. La URL del repositorio de la
dependencia es: [email protected]:infra/apache

• Use el rol rhel-system-roles.selinux para configurar SELinux para los puertos


HTTP no estándares utilizados por el servidor web. Se le proporcionará un archivo de
variable selinux.yml que se puede instalar como un archivo group_vars para pasar la
configuración correcta al rol.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

344 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

En workstation, ejecute el comando lab role-review start. El script crea el


directorio de trabajo, denominado /home/student/role-review, y lo completa con un
archivo de configuración Ansible, un inventario de host y otros archivos de laboratorio.

[student@workstation ~]$ lab role-review start

1. Cambie al directorio de trabajo /home/student/role-review.

[student@workstation ~]$ cd ~/role-review


[student@workstation role-review]$

2. Cree una guía llamada web_dev_server.yml con una sola reproducción denominada
Configure Dev Web Server (Configurar servidor web de desarrollo). Configure la
reproducción para apuntar al grupo de hosts dev_webserver. No agregue ningún rol ni
tarea a la reproducción todavía.
Asegúrese de que la reproducción obligue a los manejadores a ejecutarse, ya que puede
encontrar un error al desarrollar la guía.
Una vez terminada, la guía /home/student/role-review/web_dev_server.yml
contiene lo siguiente:

---
- name: Configure Dev Web Server
hosts: dev_webserver
force_handlers: yes

3. Verifique la sintaxis de la guía. Ejecute la guía. Se debe aprobar la comprobación de la sintaxis


y la guía debe ejecutarse correctamente.

[student@workstation role-review]$ ansible-playbook \


> --syntax-check web_dev_server.yml

playbook: web_dev_server.yml
[student@workstation role-review]$ ansible-playbook web_dev_server.yml
PLAY [Configure Dev Web Server] **********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=1 changed=0 unreachable=0 failed=0

4. Asegúrese de que las dependencias del rol de la guía estén instaladas.


El rol apache.developer_configs que creará depende del rol infra.apache. Cree
un archivo roles/requirements.yml. Debe instalar el rol desde el repositorio Git
en [email protected]:infra/apache, usar la versión v1.4
y denominarla infra.apache a nivel local. Puede suponer que las claves SSH están
configuradas para permitirle obtener roles de ese repositorio automáticamente. Instale el rol
con el comando ansible-galaxy.
Además, instale el paquete rhel-system-roles, si no está instalado.

RH294-RHEL8.0-es-1-20200501 345
capítulo 8 | Simplificación de guías con roles

4.1. Cree un subdirectorio roles para el proyecto de guía.

[student@workstation role-review]$ mkdir -v roles


mkdir: created directory 'roles'

4.2. Cree un archivo roles/requirements.yml y agregue una entrada para el rol


infra.apache. Use la versión v1.4 del repositorio git del rol.
Una vez terminado, el archivo roles/requirements.yml contiene lo siguiente:

- name: infra.apache
src: [email protected]:infra/apache
scm: git
version: v1.4

4.3. Instale las dependencias del proyecto.

[student@workstation role-review]$ ansible-galaxy install \


> -r roles/requirements.yml -p roles
- extracting infra.apache to /home/student/role-review/roles/infra.apache
- infra.apache (v1.4) was installed successfully

4.4. Instale el paquete RHEL System Roles, si no está instalado. Esto se instaló en un
ejercicio anterior.

[student@workstation role-review]$ sudo yum install rhel-system-roles

5. Inicie un nuevo rol llamado apache.developer_configs en el subdirectorio roles.


Agregue el rol infra.apache como una dependencia para el nuevo rol, usando la misma
información de nombre, fuente, versión y sistema de control de versión del archivo roles/
requirements.yml.
El archivo developer_tasks.yml del directorio del proyecto contiene tareas para el rol.
Mueva este archivo a la ubicación correcta para que sea el archivo de tareas para este rol y
reemplace el archivo existente en esa ubicación.
El archivo developer.conf.j2 del directorio del proyecto es una plantilla de Jinja2
usada por el archivo de tareas. Muévalo a la ubicación correcta para los archivos de plantilla
utilizados por este rol.

5.1. Use ansible-galaxy init para crear un esqueleto de rol para el rol
apache.developer_configs.

[student@workstation role-review]$ cd roles


[student@workstation roles]$ ansible-galaxy init apache.developer_configs
- apache.developer_configs was created successfully
[student@workstation roles]$ cd ..
[student@workstation role-review]$

5.2. Actualice el archivo roles/apache.developer_configs/meta/main.yml


del rol apache.developer_configs para reflejar una dependencia en el rol
infra.apache.
Después de la edición, la variable dependencies se define de la siguiente manera:

346 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

dependencies:
- name: infra.apache
src: [email protected]:infra/apache
scm: git
version: v1.4

5.3. Reemplace el archivo tasks/main.yml del rol con el archivo


developer_tasks.yml.

[student@workstation role-review]$ mv -v developer_tasks.yml \


> roles/apache.developer_configs/tasks/main.yml
renamed 'developer_tasks.yml' -> 'roles/apache.developer_configs/tasks/main.yml'

5.4. Coloque el archivo developer.conf.j2 en el directorio templates del rol.

[student@workstation role-review]$ mv -v developer.conf.j2 \


> roles/apache.developer_configs/templates/
renamed 'developer.conf.j2' -> 'roles/apache.developer_configs/templates/
developer.conf.j2'

6. El rol apache. developer_configs procesará una lista de usuarios definidos en una


variable denominada web_developers. El archivo web_developers.yml del directorio
del proyecto define la variable de lista de usuarios de web_developers. Revise este archivo
y utilícelo para definir la variable web_developers para el grupo de hosts del servidor web
de desarrollo.

6.1. Revise el archivo web_developers.yml.

---
web_developers:
- username: jdoe
name: John Doe
user_port: 9081
- username: jdoe2
name: Jane Doe
user_port: 9082

Se definen name, username y user_port para cada desarrollador web.

6.2. Coloque el archivo web_developers.yml en el subdirectorio group_vars/


dev_webserver.

[student@workstation role-review]$ mkdir -pv group_vars/dev_webserver


mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/dev_webserver'
[student@workstation role-review]$ mv -v web_developers.yml \
> group_vars/dev_webserver/
renamed 'web_developers.yml' -> 'group_vars/dev_webserver/web_developers.yml'

7. Agregue el rol apache.developer_configs a la reproducción de la guía


web_dev_server.yml.
La guía editada:

RH294-RHEL8.0-es-1-20200501 347
capítulo 8 | Simplificación de guías con roles

---
- name: Configure Dev Web Server
hosts: dev_webserver
force_handlers: yes
roles:
- apache.developer_configs

8. Verifique la sintaxis de la guía. Ejecute la guía. La verificación de la sintaxis debe aprobarse,


pero la guía debe fallar cuando el rol infra.apache intenta reiniciar Apache HTTPD.

[student@workstation role-review]$ ansible-playbook \


> --syntax-check web_dev_server.yml

playbook: web_dev_server.yml
[student@workstation role-review]$ ansible-playbook web_dev_server.yml

PLAY [Configure Dev Web Server] **********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

...output omitted...

TASK [infra.apache : Install a skeleton index.html] ***************************


skipping: [servera.lab.example.com]

TASK [apache.developer_configs : Create user accounts] ***********************


changed: [servera.lab.example.com] => (item={u'username': u'jdoe', u'user_port':
9081, u'name': u'John Doe'})
changed: [servera.lab.example.com] => (item={u'username': u'jdoe2', u'user_port':
9082, u'name': u'Jane Doe'})

...output omitted...

RUNNING HANDLER [infra.apache : restart firewalld] ***************************


changed: [servera.lab.example.com]

RUNNING HANDLER [infra.apache : restart apache] ******************************


fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "msg": "Unable to
restart service httpd: Job for httpd.service failed because the control process
exited with error code. See \"systemctl status httpd.service\" and \"journalctl -
xe\" for details.\n"}

NO MORE HOSTS LEFT ***********************************************************


to retry, use: --limit @/home/student/role-review/web_dev_server.retry

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=13 changed=11 unreachable=0 failed=1
skipped=1 rescued=0 ignored=0

Se produce un error al reiniciar el servicio httpd. El daemon de servicio httpd no puede


enlazar a los puertos HTTP no estándares, debido al contexto de SELinux en esos puertos.

348 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

9. Apache HTTPD no pudo reiniciarse en el paso anterior porque los puertos de red que utiliza
para sus desarrolladores están etiquetados con los contextos de SELinux incorrectos. Se
le ha proporcionado un archivo de variables, selinux.yml, que se puede utilizar con el rol
rhel-system-roles.selinux para corregir el problema.
Cree una sección pre_tasks para su reproducción en la guía web_dev_server.yml.
En esa sección, use una tarea para incluir el rol rhel-system-roles.selinux en una
estructura block/rescue para que se lo aplique correctamente. Revise la conferencia o la
documentación de este rol para ver cómo hacer esto.
Inspeccione el archivo selinux.yml. Muévalo a la ubicación correcta, de modo que sus
variables se configuren para el grupo de hosts dev_webserver.

9.1. La sección pre_tasks se puede agregar al final de la reproducción en la guía


web_dev_server.yml.
Puede analizar el bloque en /usr/share/doc/rhel-system-roles-1.0/
selinux/example-selinux-playbook.yml para ver un esquema básico de cómo
aplicar el rol, pero Red Hat Ansible Engine 2.7 le permite reemplazar la lógica compleja
de shell y wait_for con el módulo reboot.
En la sección pre_tasks, se debe incluir lo siguiente:

pre_tasks:
- name: Check SELinux configuration
block:
- include_role:
name: rhel-system-roles.selinux
rescue:
# Fail if failed for a different reason than selinux_reboot_required.
- name: Check for general failure
fail:
msg: "SELinux role failed."
when: not selinux_reboot_required

- name: Restart managed host


reboot:
msg: "Ansible rebooting system for updates."

- name: Reapply SELinux role to complete changes


include_role:
name: rhel-system-roles.selinux

9.2. El archivo selinux.yml contiene definiciones de variables para el rol rhel-system-


roles.selinux. Utilice el archivo para definir variables para el grupo de hosts de la
reproducción.

[student@workstation role-review]$ cat selinux.yml


---
# variables used by rhel-system-roles.selinux

selinux_policy: targeted
selinux_state: enforcing

selinux_ports:
- ports:
- "9081"

RH294-RHEL8.0-es-1-20200501 349
capítulo 8 | Simplificación de guías con roles

- "9082"
proto: 'tcp'
setype: 'http_port_t'
state: 'present'

[student@workstation role-review]$ mv -v selinux.yml \


> group_vars/dev_webserver/
renamed 'selinux.yml' -> 'group_vars/dev_webserver/selinux.yml'

10. Verifique la sintaxis de la guía final. Se debe aprobar la comprobación de la sintaxis.

[student@workstation role-review]$ ansible-playbook \


> --syntax-check web_dev_server.yml

playbook: web_dev_server.yml

En la guía web_dev_server.yml final, se debe leer lo siguiente:

---
- name: Configure Dev Web Server
hosts: dev_webserver
force_handlers: yes
roles:
- apache.developer_configs
pre_tasks:
- name: Check SELinux configuration
block:
- include_role:
name: rhel-system-roles.selinux
rescue:
# Fail if failed for a different reason than selinux_reboot_required.
- name: Check for general failure
fail:
msg: "SELinux role failed."
when: not selinux_reboot_required

- name: Restart managed host


reboot:
msg: "Ansible rebooting system for updates."

- name: Reapply SELinux role to complete changes


include_role:
name: rhel-system-roles.selinux

nota
Para ansible-playbook, no tiene importancia que pre_tasks esté al final de
la reproducción o en la posición "correcta" en cuanto al orden de ejecución en el
archivo de guía. Aun así ejecutará las tareas de la reproducción en el orden correcto.

11. Ejecute la guía. Debe ser capaz de realizarse de manera correcta.

350 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

[student@workstation role-review]$ ansible-playbook web_dev_server.yml

PLAY [Configure Dev Web Server] **********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [include_role : rhel-system-roles.selinux] ******************************

TASK [rhel-system-roles.selinux : Install SELinux python3 tools] *************


ok: [servera.lab.example.com]

...output omitted...

TASK [infra.apache : Apache Service is started] ******************************


changed: [servera.lab.example.com]

...output omitted...

TASK [apache.developer_configs : Copy Per-Developer Config files] ************


ok: [servera.lab.example.com] => (item={u'username': u'jdoe', u'user_port': 9081,
u'name': u'John Doe'})
ok: [servera.lab.example.com] => (item={u'username': u'jdoe2', u'user_port': 9082,
u'name': u'Jane Doe'})

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=19 changed=3 unreachable=0 failed=0
skipped=14 rescued=0 ignored=0

12. Pruebe la configuración del servidor web de desarrollo. Verifique que todos los extremos
sean accesibles y proporcionen el contenido de cada desarrollador.

[student@workstation role-review]$ curl servera


servera.lab.example.com has been customized using Ansible.
[student@workstation role-review]$ curl servera:9081
This is index.html for user: John Doe (jdoe)
[student@workstation role-review]$ curl servera:9082
This is index.html for user: Jane Doe (jdoe2)
[student@workstation role-review]$

Evaluación
Evalúe su trabajo ejecutando el comando lab role-review grade de su máquina
workstation. Corrija los errores informados y vuelva a ejecutar el script hasta obtener un
resultado satisfactorio.

[student@workstation ~]$ lab role-review grade

Finalizar
En workstation, ejecute el script lab role-review finish para limpiar este ejercicio.

RH294-RHEL8.0-es-1-20200501 351
capítulo 8 | Simplificación de guías con roles

[student@workstation ~]$ lab role-review finish

Esto concluye el trabajo de laboratorio.

352 RH294-RHEL8.0-es-1-20200501
capítulo 8 | Simplificación de guías con roles

Resumen
En este capítulo, aprendió lo siguiente:

Roles de Ansible

• Los roles organizan el código de Ansible de manera que permita la reutilización y el intercambio.
• Los roles de Red Hat Enterprise Linux son una colección de roles probados y admitidos,
diseñados para ayudarlo a configurar los subsistemas de host en las versiones de Red Hat
Enterprise Linux.
• Ansible Galaxy [https://galaxy.ansible.com] es una librería pública de roles de Ansible, escrita
por usuarios de Ansible. El comando ansible-galaxy puede buscar, instalar, enumerar,
eliminar o iniciar roles, así como mostrar información acerca de ellos.
• Los roles externos que necesita una guía se pueden definir en el archivo roles/
requirements.yml. El comando ansible-galaxy install -r roles/
requirements.yml usa este archivo para instalar los roles en el nodo de control.

RH294-RHEL8.0-es-1-20200501 353
354 RH294-RHEL8.0-es-1-20200501
capítulo 9

Resolución de problemas de
Ansible
Meta Resolver problemas de guías y hosts
administrados.

Objetivos • Solucionar problemas genéricos con una nueva


guía y repararlos
• Solucionar fallas en hosts administrados
cuando se ejecuta una guía

Secciones • Resolución de problemas de guías (y ejercicio


guiado)
• Resolución de problemas en hosts
administrados de Ansible (y ejercicio guiado)

Trabajo de • Solución de problemas de Ansible


laboratorio

RH294-RHEL8.0-es-1-20200501 355
capítulo 9 | Resolución de problemas de Ansible

Solución de problemas de guías

Objetivos
Después de completar esta sección, debe ser capaz de solucionar problemas genéricos con una
nueva guía y repararlos.

Archivos de registro de Ansible


De manera predeterminada, Red Hat Ansible Engine no está configurado para registrar sus
resultados en ningún archivo de registro. Aporta una infraestructura de registro incorporada, la
cual se puede configurar mediante el parámetro log_path en la sección default del archivo
de configuración ansible.cfg o a través de la variable de entorno $ANSIBLE_LOG_PATH.
Si alguno o ambos están configurados, Ansible almacena la salida de los comandos ansible
y ansible-playbook en el archivo de registro configurado, ya sea mediante el archivo de
configuración ansible.cfg o la variable de entorno $ANSIBLE_LOG_PATH.

Si configura Ansible para escribir archivos de registro en /var/log, Red Hat recomienda que
configure logrotate para gestionar los archivos de registro de Ansible.

El módulo Debug (Depuración)


El módulo debug (depuración) proporciona una visión de lo que está sucediendo en la
reproducción. Este módulo puede mostrar el valor de una determinada variable en cierto punto de
la reproducción. Esta función es clave para depurar tareas que usan variables para comunicarse
entre sí (por ejemplo, usando el resultado de una tarea como dato para la siguiente).

Los siguientes ejemplos usan las configuraciones msg y var dentro de las tareas debug. El primer
ejemplo muestra el valor en el tiempo de ejecución del dato ansible_facts['memfree_mb']
como parte de un mensaje impreso en el resultado de ansible-playbook. El segundo ejemplo
muestra el valor de la variable output.

- name: Display free memory


debug:
msg: "Free memory for this system is {{ ansible_facts['memfree_mb'] }}"

- name: Display the "output" variable


debug:
var: output
verbosity: 2

Gestión de errores
Muchos problemas pueden ocurrir durante la ejecución de una guía, principalmente relacionados
con la sintaxis de la guía o de cualquiera de las plantillas que utiliza, o debido a problemas
de conectividad con los hosts administrados (por ejemplo, un error en el nombre del host
administrado en el archivo de inventario). Estos errores se emiten por el comando ansible-
playbook al momento de la ejecución.

356 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Anteriormente en este curso, aprendió sobre la opción --syntax-check, que comprueba la


sintaxis YAML para la guía. Es una buena práctica ejecutar una verificación de sintaxis en su guía
antes de usarla o si tiene problemas con ella.

[student@demo ~]$ ansible-playbook play.yml --syntax-check

También puede usar la opción --step para recorrer una guía una tarea a la vez. El comando
ansible-playbook --step solicita de forma interactiva la confirmación de que desea que se
ejecute cada tarea.

[student@demo ~]$ ansible-playbook play.yml --step

La opción --start-at-task le permite iniciar la ejecución de una guía desde una tarea
específica. Toma como argumento el nombre de la tarea en la que se debe comenzar.

[student@demo ~]$ ansible-playbook play.yml --start-at-task="start httpd service"

Depuración
La salida dada por la ejecución de una guía con el comando ansible-playbook es un buen
punto de partida para la solución de problemas relacionados con hosts administrados por Ansible.
Considere el siguiente resultado de la ejecución de una guía:

PLAY [Service Deployment] ***************************************************


...output omitted...
TASK: [Install a service] ***************************************************
ok: [demoservera]
ok: [demoserverb]

PLAY RECAP ******************************************************************


demoservera : ok=2 changed=0 unreachable=0 failed=0
demoserverb : ok=2 changed=0 unreachable=0 failed=0

El resultado anterior muestra el encabezado PLAY con el nombre de la reproducción que debe
ejecutarse, seguido de uno o más encabezados TASK. Cada uno de estos encabezados representa
su tarea relacionada en la guía y se ejecuta en todos los hosts administrados que pertenecen al
grupo incluido en la guía en el parámetro hosts.

A medida que cada host administrado ejecuta cada una de las tareas de reproducción, se muestra
el nombre del host administrado debajo del encabezado TASK correspondiente, junto con el
estado de la tarea en ese host administrado. Los estados de tarea pueden aparecer como ok,
fatal, changed o skipping.

En la parte inferior de los resultados de cada reproducción, la sección PLAY RECAP muestra la
cantidad de tareas ejecutadas para cada host administrado.

Como se comentó anteriormente en el curso, puede aumentar el detalle del resultado de


ansible-playbook agregando una o más opciones -v. El comando ansible-playbook -v
aporta información de depuración adicional, con hasta cuatro niveles totales.

RH294-RHEL8.0-es-1-20200501 357
capítulo 9 | Resolución de problemas de Ansible

Configuración de detalle

Opción Descripción

-v Aparecen los datos del resultado.

-vv Aparecen tanto los datos de entrada como los de salida.

-vvv Incluye información acerca de las conexiones a los hosts


administrados.

-vvvv Incluye información adicional, como los scripts que se ejecutan en


cada host remoto, y el usuario que ejecuta cada script.

Prácticas recomendadas para la gestión de guías


Aunque las herramientas previamente analizadas pueden ayudar a identificar y resolver problemas
en guías, al desarrollar estas guías, es importante tener en mente algunas prácticas recomendadas
que pueden ayudar a facilitar el proceso de resolución de problemas. Estas son algunas de las
prácticas recomendadas para el desarrollo de guías:

• Use una descripción concisa del propósito de la reproducción o tarea para nombrar las
reproducciones y las tareas. El nombre de la reproducción o tarea se muestra cuando se ejecuta
la guía. Esto también ayuda a documentar lo que se supone que debe lograr cada reproducción
o tarea, y posiblemente por qué se necesita.

• Incluye comentarios para agregar documentación en línea adicional acerca de tareas.

• Haga un uso eficaz del espacio en blanco vertical. En general, organice los atributos de las
tareas verticalmente para que sean más fáciles de leer.

• Una sangría horizontal consistente es fundamental. Use espacios, no tabulaciones, para evitar
errores de sangría. Configure su editor de texto para insertar espacios cuando presione la tecla
Tab para hacer esto más fácil.

• Intente mantener la guía lo más simple posible. Solo use las funciones que necesita.

Referencias
Configuración de Ansible; documentación Ansible
https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html

depurar: Imprimir declaraciones durante la ejecución; documentación Ansible


https://docs.ansible.com/ansible/latest/modules/debug_module.html

Prácticas recomendadas; documentación Ansible


https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html

358 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Ejercicio Guiado

Solución de problemas de guías


En este ejercicio, solucionará los problemas de una guía que le proporcionaron y que no
funciona correctamente.

Resultados
Debe ser capaz de solucionar problemas y resolver problemas en las guías.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student.

En workstation, ejecute el script lab troubleshoot-playbook start. Verifica que


Ansible esté instalado en workstation. También crea el directorio /home/student/
troubleshoot-playbook/, y descarga en este directorio los archivos inventory,
samba.yml y samba.conf.j2 de http://materials.example.com/labs/
troubleshoot-playbook/.

[student@workstation ~]$ lab troubleshoot-playbook start

1. En workstation, cambie al directorio /home/student/troubleshoot-playbook/.

[student@workstation ~]$ cd ~/troubleshoot-playbook/

2. Cree un archivo denominado ansible.cfg en el directorio actual. Debería configurar


el parámetro log_path para escribir registros Ansible en el archivo /home/student/
troubleshoot-playbook/ansible.log. Debería configurar el parámetro inventory
para utilizar el archivo /home/student/troubleshoot-playbook/inventory
implementado por el script de laboratorio.
Al finalizar, ansible.cfg debería incluir el siguiente contenido:

[defaults]
log_path = /home/student/troubleshoot-playbook/ansible.log
inventory = /home/student/troubleshoot-playbook/inventory

3. Ejecute la guía. Fallará con un error.


Esta guía configuraría un servidor Samba si todo estuviera correcto. Sin embargo,
la ejecución fallará debido a la falta de comillas dobles en la definición de la variable
random_var. Lea el mensaje de error para ver cómo ansible-playbook reporta el
problema. Observe que a la variable random_var se le asigna un valor que contiene dos
puntos y no contiene comillas.

[student@workstation troubleshoot-playbook]$ ansible-playbook samba.yml


ERROR! Syntax Error while loading YAML.
mapping values are not allowed in this context

RH294-RHEL8.0-es-1-20200501 359
capítulo 9 | Resolución de problemas de Ansible

The error appears to have been in '/home/student/troubleshoot-playbook/samba.yml':


line 8, column 30, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

install_state: installed
random_var: This is colon: test
^ here

4. Confirme que el error se haya registrado correctamente en el archivo /home/student/


troubleshoot-playbook/ansible.log.

[student@workstation troubleshoot-playbook]$ tail ansible.log


The error appears to have been in '/home/student/troubleshoot-playbook/samba.yml':
line 8, column 30, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

install_state: installed
random_var: This is colon: test
^ here

5. Edite la guía y corrija el error agregando comillas a todo el valor que se está asignando a
random_var. La versión corregida de samba.yml debería incluir el siguiente contenido:

...output omitted...
vars:
install_state: installed
random_var: "This is colon: test"
...output omitted...

6. Verifique la guía usando la opción --syntax-check. Se informa otro error debido al


espacio en blanco adicional en la sangría en la última tarea, deliver samba config.

[student@workstation troubleshoot-playbook]$ ansible-playbook --syntax-check \


> samba.yml
ERROR! Syntax Error while loading YAML.
did not find expected key

The error appears to have been in '/home/student/troubleshoot-playbook/samba.yml':


line 44, column 4, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: deliver samba config


^ here

360 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

7. Edite la guía y elimine el espacio adicional para todas las líneas en esa tarea. La guía
corregida debe aparecer de la siguiente manera:

...output omitted...
- name: configure firewall for samba
firewalld:
state: enabled
permanent: true
immediate: true
service: samba

- name: deliver samba config


template:
src: templates/samba.conf.j2
dest: /etc/samba/smb.conf
owner: root
group: root
mode: 0644

8. Ejecute la guía usando la opción --syntax-check. Un error se emite debido a que la


variable install_state se usa como parámetro en la tarea install samba. No tiene
comillas.

[student@workstation troubleshoot-playbook]$ ansible-playbook --syntax-check \


> samba.yml
ERROR! Syntax Error while loading YAML.
found unacceptable key (unhashable type: 'AnsibleMapping')

The error appears to have been in '/home/student/troubleshoot-playbook/samba.yml':


line 14, column 15, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

name: samba
state: {{ install_state }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

with_items:
- {{ foo }}

Should be written as:

with_items:
- "{{ foo }}"

RH294-RHEL8.0-es-1-20200501 361
capítulo 9 | Resolución de problemas de Ansible

9. Edite la guía y corrija la tarea install samba. La referencia a la variable install_state


debe estar entre comillas. El contenido del archivo resultante debe verse de la siguiente
forma:

...output omitted...
tasks:
- name: install samba
yum:
name: samba
state: "{{ install_state }}"
...output omitted...

10. Ejecute la guía usando la opción --syntax-check. Ahora debería mostrar errores de
sintaxis adicionales.

[student@workstation troubleshoot-playbook]$ ansible-playbook --syntax-check \


> samba.yml

playbook: samba.yml

11. Ejecute la guía. Se emitirá un error relacionado con SSH.

[student@workstation troubleshoot-playbook]$ ansible-playbook samba.yml


PLAY [Install a samba server] **************************************************

TASK [Gathering Facts] *********************************************************


fatal: [servera.lab.exammple.com]: UNREACHABLE! => {"changed": false,
"msg":"Failed to connect to the host via ssh: ssh: Could not resolve hostname
servera.lab.exammple.com: Name or service not known\r\n", "unreachable": true}

PLAY RECAP *********************************************************************


servera.lab.exammple.com : ok=0 changed=0 unreachable=1 failed=0

12. Asegúrese de que se esté ejecutando el host administrado servera.lab.example.com,


con el comando ping.

[student@workstation troubleshoot-playbook]$ ping -c3 servera.lab.example.com


PING servera.lab.example.com (172.25.250.10) 56(84) bytes of data.
64 bytes from servera.lab.example.com (172.25.250.10): icmp_seq=1 ttl=64
time=0.247 ms
64 bytes from servera.lab.example.com (172.25.250.10): icmp_seq=2 ttl=64
time=0.329 ms
64 bytes from servera.lab.example.com (172.25.250.10): icmp_seq=3 ttl=64
time=0.320 ms

--- servera.lab.example.com ping statistics ---


3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.247/0.298/0.329/0.041 ms

362 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

13. Asegúrese de que puede conectarse al host administrado servera.lab.example.com


como el usuario devops usando SSH, y que las claves SSH correctas estén instaladas.
Vuelva a cerrar la sesión cuando haya terminado.

[student@workstation troubleshoot-playbook]$ ssh [email protected]


Warning: Permanently added 'servera.lab.example.com,172.25.250.10' (ECDSA) to the
list of known hosts.
...output omitted...
[devops@servera ~]$ exit
Connection to servera.lab.example.com closed.

14. Vuelva a ejecutar la guía con -vvvv para obtener más información acerca de la
ejecución. Se emite un error, ya que no se puede acceder al host administrado
servera.lab.example.com.

[student@workstation troubleshoot-playbook]$ ansible-playbook -vvvv samba.yml


...output omitted...

PLAYBOOK: samba.yml ******************************************************


1 plays in samba.yml

PLAY [Install a samba server] ********************************************

TASK [Gathering Facts] ***************************************************


task path: /home/student/troubleshoot-playbook/samba.yml:2
<servera.lab.exammple.com> ESTABLISH SSH CONNECTION FOR USER: devops
...output omitted...
fatal: [servera.lab.exammple.com]: UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: OpenSSH_7.8p1, OpenSSL 1.1.1
FIPS 11 Sep 2018\r\ndebug1: Reading configuration data /home/student/.ssh/
config\r\ndebug1: /home/student/.ssh/config line 1: Applying options for *
\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug3: /etc/
ssh/ssh_config line 52: Including file /etc/ssh/ssh_config.d/01-training.conf
depth 0\r\ndebug1: Reading configuration data /etc/ssh/ssh_config.d/01-
training.conf\r\ndebug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying
options for *\r\ndebug3: /etc/ssh/ssh_config line 52: Including file /etc/ssh/
ssh_config.d/05-redhat.conf depth 0\r\ndebug1: Reading configuration data /etc/
ssh/ssh_config.d/05-redhat.conf\r\ndebug3: /etc/ssh/ssh_config.d/05-redhat.conf
line 2: Including file /etc/crypto-policies/back-ends/openssh.config depth
1\r\ndebug1: Reading configuration data /etc/crypto-policies/back-ends/
openssh.config\r\ndebug3: gss kex names ok: [gss-gex-sha1-,gss-group14-sha1-]\r
\ndebug3: kex names ok: [[email protected],ecdh-sha2-nistp256,ecdh-
sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-
hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-
sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1]\r
\ndebug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for
*\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket \"/
home/student/.ansible/cp/d4775f48c9\" does not exist\r\ndebug2: resolving
\"servera.lab.exammple.com\" port 22\r\ndebug2: ssh_connect_direct\r\ndebug1:
Connecting to servera.lab.exammple.com [18.211.9.206] port 22.\r\ndebug2: fd 6
setting O_NONBLOCK\r\ndebug1: connect to address 18.211.9.206 port 22: Connection
timed out\r\nssh: connect to host servera.lab.exammple.com port 22: Connection
timed out",

RH294-RHEL8.0-es-1-20200501 363
capítulo 9 | Resolución de problemas de Ansible

"unreachable": true
}

...output omitted...
PLAY RECAP ***************************************************************
servera.lab.exammple.com : ok=0 changed=0 unreachable=1 failed=0

15. Al aplicar el mayor nivel de detalle con Ansible, el archivo de registro de Ansible es una
mejor opción para verificar el resultado que la consola. Revise el resultado del comando
anterior en el archivo /home/student/troubleshoot-playbook/ansible.log.

[student@workstation troubleshoot-playbook]$ tail ansible.log


2018-12-17 19:22:50,508 p=18287 u=student | task path: /home/student/
troubleshoot-playbook/samba.yml:2
2018-12-17 19:22:50,549 p=18287 u=student | fatal: [servera.lab.exammple.com]:
UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: OpenSSH_7.8p1, OpenSSL 1.1.1
FIPS 11 Sep 2018\r\ndebug1: Reading configuration data /home/student/.ssh/
config\r\ndebug1: /home/student/.ssh/config line 1: Applying options for *
\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug3: /etc/
ssh/ssh_config line 52: Including file /etc/ssh/ssh_config.d/01-training.conf
depth 0\r\ndebug1: Reading configuration data /etc/ssh/ssh_config.d/01-
training.conf\r\ndebug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying
options for *\r\ndebug3: /etc/ssh/ssh_config line 52: Including file /etc/ssh/
ssh_config.d/05-redhat.conf depth 0\r\ndebug1: Reading configuration data /etc/
ssh/ssh_config.d/05-redhat.conf\r\ndebug3: /etc/ssh/ssh_config.d/05-redhat.conf
line 2: Including file /etc/crypto-policies/back-ends/openssh.config depth
1\r\ndebug1: Reading configuration data /etc/crypto-policies/back-ends/
openssh.config\r\ndebug3: gss kex names ok: [gss-gex-sha1-,gss-group14-sha1-]\r
\ndebug3: kex names ok: [[email protected],ecdh-sha2-nistp256,ecdh-
sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-
hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-
sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1]\r
\ndebug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for
*\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket \"/
home/student/.ansible/cp/d4775f48c9\" does not exist\r\ndebug2: resolving
\"servera.lab.exammple.com\" port 22\r\ndebug2: ssh_connect_direct\r\ndebug1:
Connecting to servera.lab.exammple.com [18.211.9.206] port 22.\r\ndebug2: fd 6
setting O_NONBLOCK\r\ndebug1: connect to address 18.211.9.206 port 22: Connection
timed out\r\nssh: connect to host servera.lab.exammple.com port 22: Connection
timed out",
"unreachable": true
}
2018-12-17 19:22:50,550 p=18287 u=student | to retry, use: --limit @/home/
student/troubleshoot-playbook/samba.retry

2018-12-17 19:22:50,550 p=18287 u=student | PLAY RECAP ******************


2018-12-17 19:22:50,550 p=18287 u=student | servera.lab.exammple.com : ok=0
changed=0 unreachable=1 failed=0

364 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

16. Investigue el archivo inventory en busca de errores. Observe que el grupo


[samba_servers] ha escrito incorrectamente servera.lab.example.com. Corrija
este error como se muestra a continuación:

...output omitted...
[samba_servers]
servera.lab.example.com
...output omitted...

17. Ejecute la guía nuevamente. La tarea debug install_state variable devuelve el mensaje The
state for the samba service is installed. Esta tarea hace uso del módulo debug y muestra
el valor de la variable install_state. Un error también se muestra en la tarea deliver samba
config, ya que no se dispone de ningún archivo samba.j2 en el directorio de trabajo, /
home/student/troubleshoot-playbook/.

[student@workstation troubleshoot-playbook]$ ansible-playbook samba.yml

PLAY [Install a samba server] **************************************************


...output omitted...
TASK [debug install_state variable] ********************************************
ok: [servera.lab.example.com] => {
"msg": "The state for the samba service is installed"
}
...output omitted...
TASK [deliver samba config] ****************************************************
fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "msg": "Could not
find or access 'samba.j2'\nSearched in:\n\t/home/student/troubleshoot-playbook/
templates/samba.j2\n\t/home/student/troubleshoot-playbook/samba.j2\n\t/home/
student/troubleshoot-playbook/templates/samba.j2\n\t/home/student/troubleshoot-
playbook/samba.j2 on the Ansible Controller.\nIf you are using a module and expect
the file to exist on the remote, see the remote_src option"}
...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=7 changed=3 unreachable=0 failed=1

18. Edite la guía y corrija el parámetro src en la tarea deliver samba config para que sea
samba.conf.j2. Al finalizar, debería verse de la siguiente manera:

...output omitted...
- name: deliver samba config
template:
src: samba.conf.j2
dest: /etc/samba/smb.conf
owner: root
...output omitted...

RH294-RHEL8.0-es-1-20200501 365
capítulo 9 | Resolución de problemas de Ansible

19. Ejecute la guía nuevamente. Ejecute la guía usando la opción --step. Debería ejecutarse
sin errores.

[student@workstation troubleshoot-playbook]$ ansible-playbook samba.yml --step

PLAY [Install a samba server] ************************************************


Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: install samba (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: install firewalld (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: debug install_state variable (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: start samba (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: start firewalld (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: configure firewall for samba (N)o/(y)es/(c)ontinue: y
...output omitted...
Perform task: TASK: deliver samba config (N)o/(y)es/(c)ontinue: y
...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=8 changed=1 unreachable=0 failed=0

Finalizar
En workstation, ejecute el script lab troubleshoot-playbook finish para limpiar este
ejercicio.

[student@workstation ~]$ lab troubleshoot-playbook finish

Esto concluye el ejercicio guiado.

366 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Solución de problemas en hosts


administrados de Ansible

Objetivos
Después de completar esta sección, debe ser capaz de solucionar las fallas en los hosts
administrados cuando ejecutan una guía.

Uso del modo de verificación como herramienta de


prueba
Puede usar el comando ansible-playbook --check para ejecutar pruebas de humo
en una guía. Esta opción ejecuta la guía sin realizar cambios en la configuración de los hosts
administrados. Si un módulo usado dentro de la guía admite check mode, se muestran los cambios
que se habrían realizado en los hosts administrados (pero que no se hicieron). Si un módulo no
admite el modo de verificación, los cambios no se muestran y el módulo aún no realiza ninguna
acción.

[student@demo ~]$ ansible-playbook --check playbook.yml

nota
El comando ansible-playbook --check podría no funcionar correctamente si
las tareas usan condicionales.

También puede controlar si las tareas individuales se ejecutan en el modo de verificación con el
ajuste check_mode. Si una tarea tiene configurado check_mode: yes, siempre se ejecuta en
modo de verificación, independientemente de que haya pasado la opción --check a ansible-
playbook. Del mismo modo, si una tarea tiene configurado check_mode: no, siempre se
ejecuta normalmente, incluso si pasa --check a ansible-playbook.

La siguiente tarea siempre se ejecuta en modo de verificación y no realiza cambios.

tasks:
- name: task always in check mode
shell: uname -a
check_mode: yes

La siguiente tarea siempre se ejecuta normalmente, incluso cuando se inicia con ansible-
playbook --check.

tasks:
- name: task always runs even in check mode
shell: uname -a
check_mode: no

Esto puede ser útil porque puede ejecutar la mayor parte de una guía normalmente mientras
prueba tareas individuales con check_mode: yes. Del mismo modo, puede hacer que las

RH294-RHEL8.0-es-1-20200501 367
capítulo 9 | Resolución de problemas de Ansible

ejecuciones de prueba en modo de verificación tengan más probabilidades de proporcionar


resultados razonables ejecutando tareas seleccionadas que recopilan datos o establecen variables
para condicionales, pero no cambian los hosts administrados con check_mode: no.

Una tarea puede determinar si la guía se está ejecutando en modo de verificación probando el
valor de la variable mágica ansible_check_mode. Esta variable booleana se establece en true
si la guía se está ejecutando en modo de verificación.

Advertencia
Las tareas que tienen configurado check_mode: no se ejecutarán incluso cuando
la guía se ejecute con ansible-playbook --check. Por lo tanto, no se puede
confiar en que la opción --check no realizará cambios en los hosts administrados,
sin confirmar que este sea el caso al inspeccionar la guía y los roles o tareas
asociados con este.

nota
Si tiene guías más antiguas que usan always_run: yes para forzar a las tareas a
ejecutarse normalmente, incluso en el modo de verificación, tendrá que reemplazar
ese código con check_mode: no en Ansible 2.6 y posteriores.

El comando ansible-playbook también proporciona una opción --diff. Esta opción informa
los cambios realizados a los archivos de plantillas en hosts administrados. Si se usan con la opción
--check, estos cambios se muestran en la salida del comando, pero no se realizan.

[student@demo ~]$ ansible-playbook --check --diff playbook.yml

Pruebas con módulos


Algunos módulos pueden brindar información adicional acerca de cuál es el estado de un host
administrado. La siguiente lista incluye algunos de los módulos de Ansible que se pueden usar para
probar y depurar problemas en hosts administrados.

• El módulo uri aporta una forma de verificar que una RESTful API esté devolviendo el contenido
requerido.

tasks:
- uri:
url: http://api.myapp.com
return_content: yes
register: apiresponse

- fail:
msg: 'version was not provided'
when: "'version' not in apiresponse.content"

• El módulo script admite la ejecución de un script en un host administrado, y falla si el código


de retorno para el script es diferente a cero. El script debe estar en el nodo de control y se
transferirá y ejecutará en el host administrado.

368 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

tasks:
- script: check_free_memory

• El módulo stat recopila datos para un archivo muy similar al comando stat. Puede usarlo
para registrar una variable y luego hacer una prueba para determinar si el archivo existe, o para
obtener otra información sobre el archivo. Si el archivo no existe, la tarea stat no fallará, pero su
variable registrada informará false para *.stat.exists.

En este ejemplo, todavía se está ejecutando una aplicación si existe /var/run/app.lock, en


cuyo caso la reproducción deberá abortar.

tasks:
- name: Check if /var/run/app.lock exists
stat:
path: /var/run/app.lock
register: lock

- name: Fail if the application is running


fail:
when: lock.stat.exists

• El módulo assert es una alternativa al módulo fail. El módulo assert es compatible con la
opción that que toma una lista de condicionales. Si alguno de esos condicionales es falso, la
tarea falla. Puedes usar las opciones success_msg y fail_msg para personalizar el mensaje
que imprime si informa éxito o fracaso.

El siguiente ejemplo repite el anterior, pero usa assert en lugar de fail.

tasks:
- name: Check if /var/run/app.lock exists
stat:
path: /var/run/app.lock
register: lock

- name: Fail if the application is running


assert:
that:
- not lock.stat.exists

Solución de problemas de conexiones


Muchos problemas comunes al usar Ansible para administrar hosts están asociados con
conexiones al host y con problemas de configuración relacionados con el usuario remoto y la
escalada de privilegios.

Si tiene problemas para autenticarse en un host administrado, asegúrese de tener remote_user


correctamente configurado en el archivo de configuración o en la reproducción. También
debe confirmar que tiene configuradas las claves SSH correctas o que está proporcionando la
contraseña correcta para ese usuario.

Asegúrese de que become esté correctamente configurado y de que está usando el


become_user correcto (que es root de forma predeterminada). Debe confirmar que está

RH294-RHEL8.0-es-1-20200501 369
capítulo 9 | Resolución de problemas de Ansible

ingresando la contraseña sudo correcta y que sudo en el host administrado esté configurado
correctamente.

Un problema más sutil tiene que ver con la configuración del inventario. Para un servidor complejo
con varias direcciones de red, es posible que deba usar una dirección particular o un nombre
DNS al conectarse a ese sistema. Es posible que no desee utilizar esa dirección como nombre de
inventario de la máquina para una mejor legibilidad. Puede configurar una variable de inventario
de host, ansible_host, que anulará el nombre del inventario con un nombre o una dirección IP
diferente y será usado por Ansible para conectarse a ese host. Esta variable podría configurarse en
el archivo o directorio host_vars para ese host o en el propio archivo de inventario.

Por ejemplo, la siguiente entrada de inventario configura Ansible para conectarse a 192.0.2.4
al procesar el host web4.phx.example.com:

web4.phx.example.com ansible_host=192.0.2.4

Esta es una forma útil de controlar cómo Ansible se conecta a los hosts administrados. Sin
embargo, también puede causar problemas si el valor de ansible_host es incorrecto.

Prueba de hosts administrados con comandos ad hoc


En los siguientes ejemplos, se ilustran algunas de las verificaciones que pueden realizarse en un
host administrado mediante el uso de comandos ad hoc.

Ha usado el módulo ping para probar si puede conectarse a hosts gestionados. Dependiendo
de las opciones que pase, también puede usarlo para probar si la escalada de privilegios y las
credenciales están configuradas correctamente.

[student@demo ~]$ ansible demohost -m ping


demohost | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
[student@demo ~]$ ansible demohost -m ping --become
demohost | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"module_stderr": "sudo: a password is required\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}

Este ejemplo devuelve el espacio actualmente disponible en los discos configurados en el host
administrado demohost. Eso puede ser útil para confirmar que el sistema de archivos en el host
administrado no está lleno.

[student@demo ~]$ ansible demohost -m command -a 'df'

370 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Este ejemplo devuelve la memoria libre actualmente disponible en el host administrado


demohost.

[student@demo ~]$ ansible demohost -m command -a 'free -m'

El nivel correcto de pruebas


Ansible está diseñado para garantizar que la configuración incluida en las guías y realizada por sus
módulos sea correcta. Monitorea todos los módulos en busca de fallas reportadas y detiene la guía
inmediatamente si se encuentran fallas. Esto garantiza que todas las tareas realizadas antes de la
falla no tengan errores.

Debido a esto, normalmente no hay necesidad de verificar si el resultado de una tarea gestionada
por Ansible se aplicó correctamente en los hosts administrados. Tiene sentido sumar algunas
verificaciones de salud a las guías, o ejecutarlas directamente como comandos ad hoc, cuando
se requiere una resolución de problemas directa. Sin embargo, debe tener cuidado de no agregar
demasiada complejidad a sus tareas y reproducciones en un esfuerzo por verificar dos veces las
pruebas realizadas por los módulos.

Referencias
Modo de verificación ("Ejecución práctica") -- Documentación Ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html

Estrategias de prueba -- Documentación Ansible


https://docs.ansible.com/ansible/latest/reference_appendices/test_strategies.html

RH294-RHEL8.0-es-1-20200501 371
capítulo 9 | Resolución de problemas de Ansible

Ejercicio Guiado

Solución de problemas en hosts


administrados de Ansible
En este ejercicio, resolverá las fallas de tareas que se produzcan en uno de sus hosts
administrados cuando ejecuta una guía.

Resultados
Debería poder solucionar problemas de los hosts administrados.

Andes De Comenzar
Iniciar sesión en workstation como student con la contraseña student.

En workstation, ejecute el script lab troubleshoot-host start.


Garantiza que Ansible se instale en workstation. También descarga los archivos
inventory, mailrelay.yml y postfix-relay-main.conf.j2 de http://
materials.example.com/troubleshoot-host/ en el directorio /home/student/
troubleshoot-host/.

[student@workstation ~]$ lab troubleshoot-host start

1. En workstation, cambie al directorio /home/student/troubleshoot-host/.

[student@workstation ~]$ cd ~/troubleshoot-host/

2. Ejecute la guía mailrelay.yml en modo de verificación.

[student@workstation troubleshoot-host]$ ansible-playbook mailrelay.yml --check


PLAY [create mail relay servers] ***********************************************
...output omitted...
TASK [check main.cf file] ******************************************************
ok: [servera.lab.example.com]

TASK [verify main.cf file exists] **********************************************


ok: [servera.lab.example.com] => {
"msg": "The main.cf file exists"
}
...output omitted...
TASK [email notification of always_bcc config] *********************************
fatal: [servera.lab.example.com]: FAILED! => {"msg": "The conditional check
'bcc_state.stdout != 'always_bcc ='' failed. The error was: error while
evaluating conditional (bcc_state.stdout != 'always_bcc ='): 'dict object'
has no attribute 'stdout'\n\nThe error appears to have been in '/home/student/
troubleshoot-host/mailrelay.yml': line 42, column 7, but may\nbe elsewhere in the
file depending on the exact syntax problem.\n\nThe offending line appears to be:
\n\n\n - name: email notification of always_bcc config\n ^ here\n"}

372 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=6 changed=3 unreachable=0 failed=1

La tarea verify main.cf file exists usa el módulo stat. Confirmó que main.cf existe en
servera.lab.example.com.
Falló la tarea email notification of always_bcc config. No recibió el resultado de la tarea
check for always_bcc porque la guía se ejecutó usando el modo de verificación.

3. Con un comando ad hoc, verifique el encabezado para el archivo /etc/postfix/


main.cf.

[student@workstation troubleshoot-host]$ ansible servera.lab.example.com \


> -u devops -b -a "head /etc/postfix/main.cf"
servera.lab.example.com | FAILED | rc=1 >>
head: cannot open ‘/etc/postfix/main.cf’ for reading: No such file or
directorynon-zero return code

El comando falló porque la guía se ejecutó en el modo de verificación. Postfix no está


instalado en servera.lab.example.com

4. Vuelva a ejecutar la guía, pero no especifique el modo de verificación. Debería aparecer el


error en la tarea email notification of always_bcc config.

[student@workstation troubleshoot-host]$ ansible-playbook mailrelay.yml


PLAY [create mail relay servers] ***********************************************
...output omitted...
TASK [check for always_bcc] ****************************************************
changed: [servera.lab.example.com]

TASK [email notification of always_bcc config] *********************************


skipping: [servera.lab.example.com]

RUNNING HANDLER [restart postfix] **********************************************


changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=8 changed=5 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

5. Usando un comando ad hoc, muestre la parte superior del archivo /etc/postfix/


main.cf.

[student@workstation troubleshoot-host]$ ansible servera.lab.example.com \


> -u devops -b -a "head /etc/postfix/main.cf"
servera.lab.example.com | SUCCESS | rc=0 >>
# Ansible managed
#
# Global Postfix configuration file. This file lists only a subset
# of all parameters. For the syntax, and for a complete parameter
# list, see the postconf(5) manual page (command: "man 5 postconf").
#

RH294-RHEL8.0-es-1-20200501 373
capítulo 9 | Resolución de problemas de Ansible

# For common configuration examples, see BASIC_CONFIGURATION_README


# and STANDARD_CONFIGURATION_README. To find these documents, use
# the command "postconf html_directory readme_directory", or go to
# http://www.postfix.org/BASIC_CONFIGURATION_README.html etc.

Ahora comienza con una línea que contiene la cadena, “Ansible managed”. El archivo se
actualizó y ahora está gestionado por Ansible.

6. Agregue una tarea para activar el servicio smtp en el firewall.

[student@workstation troubleshoot-host]$ vim mailrelay.yml


...output omitted...
- name: postfix firewalld config
firewalld:
state: enabled
permanent: true
immediate: true
service: smtp
...output omitted...

7. Ejecute la guía. La tarea postfix firewalld config debería haberse ejecutado sin
errores.

[student@workstation troubleshoot-host]$ ansible-playbook mailrelay.yml


PLAY [create mail relay servers] ***********************************************
...output omitted...
TASK [postfix firewalld config] ************************************************
changed: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=8 changed=2 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

8. Usando un comando ad hoc, verifique que ahora el servicio smtp esté configurado en el
firewall en servera.lab.example.com.

[student@workstation troubleshoot-host]$ ansible servera.lab.example.com \


> -u devops -b -a "firewall-cmd --list-services"
servera.lab.example.com | CHANGED | rc=0 >>
cockpit dhcpv6-client samba smtp ssh

9. Use telnet para probar si el servicio SMTP está escuchando en el puerto TCP/25 en
servera.lab.example.com. Desconéctese cuando haya terminado.

[student@workstation troubleshoot-host]$ telnet servera.lab.example.com 25


Trying 172.25.250.10...
Connected to servera.lab.example.com.
Escape character is '^]'.
220 servera.lab.example.com ESMTP Postfix
quit
221 2.0.0 Bye
Connection closed by foreign host.

374 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Finalizar
En workstation, ejecute el script lab troubleshoot-host finish para limpiar este
ejercicio.

[student@workstation ~]$ lab troubleshoot-host finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 375
capítulo 9 | Resolución de problemas de Ansible

Trabajo de laboratorio

Solución de problemas de Ansible


Lista de verificación de rendimiento
En esta práctica de laboratorio, resolverá los problemas que surjan cuando intente ejecutar
una guía que se le proporcionó.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Resolver problemas de guías.

• Resolver problemas de hosts administrados.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student. Ejecute el
comando lab troubleshoot-review start.

[student@workstation ~]$ lab troubleshoot-review start

Este script verifica que Ansible esté instalado en workstation y crea el


directorio ~student/troubleshoot-review/html/. Descarga los archivos
ansible.cfg, inventory-lab, secure-web.yml y vhosts.conf de http://
materials.example.com/labs/troubleshoot-review/ en el directorio /home/
student/troubleshoot-review/. También descarga el archivo index.html en el
directorio /home/student/troubleshoot-review/html/.

1. Desde el directorio ~/troubleshoot-review, verifique la sintaxis de la guía secure-


web.yml. Esta guía contiene una reproducción que configura Apache HTTPD con TLS/SSL
para los hosts en el grupo webservers . Solucione el problema que se informa.
2. Verifique la sintaxis de la guía secure-web.yml nuevamente. Solucione el problema que se
informa.
3. Verifique la sintaxis de la guía secure-web.yml por tercera vez. Solucione el problema que
se informa.
4. Verifique la sintaxis de la guía secure-web.yml por cuarta vez. No debería mostrar errores
de sintaxis.
5. Ejecute la guía secure-web.yml. Ansible no puede conectarse a
serverb.lab.example.com. Corrija este problema.
6. Ejecute la guía secure-web.yml nuevamente. Ansible debe autenticarse como usuario
remoto devops en el host administrado. Solucione este problema.
7. Ejecute la guía secure-web.yml por tercera vez. Solucione el problema que se informa.
8. Ejecute la guía secure-web.yml una vez más. Se debe completar correctamente. Use un
comando ad hoc para verificar que el servicio httpd esté funcionando.

376 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Evaluación
En workstation, ejecute el script lab troubleshoot-review grade para confirmar que ha
realizado correctamente este ejercicio.

[student@workstation ~]$ lab troubleshoot-review grade

Finalizar
En workstation, ejecute el script lab troubleshoot-review finish para limpiar este
trabajo de laboratorio.

[student@workstation ~]$ lab troubleshoot-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 377
capítulo 9 | Resolución de problemas de Ansible

Solución

Solución de problemas de Ansible


Lista de verificación de rendimiento
En esta práctica de laboratorio, resolverá los problemas que surjan cuando intente ejecutar
una guía que se le proporcionó.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Resolver problemas de guías.

• Resolver problemas de hosts administrados.

Andes De Comenzar
Inicie sesión en workstation como student con la contraseña student. Ejecute el
comando lab troubleshoot-review start.

[student@workstation ~]$ lab troubleshoot-review start

Este script verifica que Ansible esté instalado en workstation y crea el


directorio ~student/troubleshoot-review/html/. Descarga los archivos
ansible.cfg, inventory-lab, secure-web.yml y vhosts.conf de http://
materials.example.com/labs/troubleshoot-review/ en el directorio /home/
student/troubleshoot-review/. También descarga el archivo index.html en el
directorio /home/student/troubleshoot-review/html/.

1. Desde el directorio ~/troubleshoot-review, verifique la sintaxis de la guía secure-


web.yml. Esta guía contiene una reproducción que configura Apache HTTPD con TLS/SSL
para los hosts en el grupo webservers . Solucione el problema que se informa.

1.1. En workstation, cambie al directorio de proyectos /home/student/troubleshoot-


review.

[student@workstation ~]$ cd ~/troubleshoot-review/

1.2. Verifique la sintaxis de la guía secure-web.yml. Esta guía configura Apache HTTPD
con TLS/SSL para los hosts del grupo webservers cuando todo es correcto.

[student@workstation troubleshoot-review]$ ansible-playbook --syntax-check \


> secure-web.yml

ERROR! Syntax Error while loading YAML.


mapping values are not allowed in this context

The error appears to have been in '/home/student/Ansible-course/troubleshoot-


review/secure-web.yml': line 7, column 30, but may

378 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

vars:
random_var: This is colon: test
^ here

1.3. Corrija el problema de sintaxis en la definición de la variable random_var agregando


comillas dobles a la cadena This is colon: test. El cambio resultante debe
aparecer de la siguiente manera:

...output omitted...
vars:
random_var: "This is colon: test"
...output omitted...

2. Verifique la sintaxis de la guía secure-web.yml nuevamente. Solucione el problema que se


informa.

2.1. Verifique la sintaxis de secure-web.yml usando ansible-playbook --syntax-


check nuevamente.

[student@workstation troubleshoot-review]$ ansible-playbook --syntax-check \


> secure-web.yml

ERROR! Syntax Error while loading YAML.


did not find expected '-' indicator

The error appears to have been in '/home/student/Ansible-course/troubleshoot-


review/secure-web.yml': line 38, column 10, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: start and enable web services


^ here

2.2. Corrija los problemas de sintaxis en la sangría. Quite el espacio adicional al comienzo
de los elementos de la tarea start and enable web services. El cambio resultante debe
aparecer de la siguiente manera:

...output omitted...
args:
creates: /etc/pki/tls/certs/serverb.lab.example.com.crt

- name: start and enable web services


service:
name: httpd
state: started
enabled: yes

- name: deliver content

RH294-RHEL8.0-es-1-20200501 379
capítulo 9 | Resolución de problemas de Ansible

copy:
dest: /var/www/vhosts/serverb-secure
src: html/
...output omitted...

3. Verifique la sintaxis de la guía secure-web.yml por tercera vez. Solucione el problema que
se informa.

3.1. Verifique la sintaxis de la guía secure-web.yml.

[student@workstation troubleshoot-review]$ ansible-playbook --syntax-check \


> secure-web.yml

ERROR! Syntax Error while loading YAML.


found unacceptable key (unhashable type: 'AnsibleMapping')

The error appears to have been in '/home/student/Ansible-course/troubleshoot-


review/secure-web.yml': line 13, column 20, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

yum:
name: {{ item }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

with_items:
- {{ foo }}

Should be written as:

with_items:
- "{{ foo }}"

3.2. Corrija la variable item en la tarea install web server packages. Agregue
comillas dobles a {{ item }}. El cambio resultante debe aparecer de la siguiente
manera:

...output omitted...
- name: install web server packages
yum:
name: "{{ item }}"
state: latest
notify:
- restart services
loop:
- httpd
- mod_ssl
...output omitted...

380 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

4. Verifique la sintaxis de la guía secure-web.yml por cuarta vez. No debería mostrar errores
de sintaxis.

4.1. Revise la sintaxis de la guía secure-web.yml. No debería mostrar errores de sintaxis.

[student@workstation troubleshoot-review]$ ansible-playbook --syntax-check \


> secure-web.yml

playbook: secure-web.yml

5. Ejecute la guía secure-web.yml. Ansible no puede conectarse a


serverb.lab.example.com. Corrija este problema.

5.1. Ejecute la guía secure-web.yml. Fallará con un error.

[student@workstation troubleshoot-review]$ ansible-playbook secure-web.yml


PLAY [create secure web service] ***********************************************

TASK [Gathering Facts] *********************************************************


fatal: [serverb.lab.example.com]: UNREACHABLE! => {"changed": false, "msg":
"Failed to connect to the host via ssh: [email protected]:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true}

PLAY RECAP *********************************************************************


serverb.lab.example.com : ok=0 changed=0 unreachable=1 failed=0

5.2. Ejecute la guía secure-web.yml nuevamente, agregando el parámetro -vvvv para


aumentar el nivel de detalle de los resultados.
Observe que Ansible parece estar conectándose a serverc.lab.example.com en
lugar de a serverb.lab.example.com.

[student@workstation troubleshoot-review]$ ansible-playbook secure-web.yml -vvvv


...output omitted...
TASK [Gathering Facts] *********************************************************
task path: /home/student/troubleshoot-review/secure-web.yml:3
<serverc.lab.example.com> ESTABLISH SSH CONNECTION FOR USER: students
<serverc.lab.example.com> SSH: EXEC ssh -vvv -C -o ControlMaster=auto
-o ControlPersist=60s -o KbdInteractiveAuthentication=no -o
PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o
PasswordAuthentication=no -o User=students -o ConnectTimeout=10 -o ControlPath=/
home/student/.ansible/cp/bc0c05136a serverc.lab.example.com '/bin/sh -c '"'"'echo
~students && sleep 0'"'"''
...output omitted...

5.3. Corrija la línea en el archivo inventory-lab. Elimine la variable del host


ansible_host para que el archivo aparezca como se muestra a continuación:

[webservers]
serverb.lab.example.com

6. Ejecute la guía secure-web.yml nuevamente. Ansible debe autenticarse como usuario


remoto devops en el host administrado. Solucione este problema.

RH294-RHEL8.0-es-1-20200501 381
capítulo 9 | Resolución de problemas de Ansible

6.1. Ejecute la guía secure-web.yml.

[student@workstation troubleshoot-review]$ ansible-playbook secure-web.yml -vvvv


...output omitted...
TASK [Gathering Facts] *********************************************************
task path: /home/student/troubleshoot-review/secure-web.yml:3
<serverb.lab.example.com> ESTABLISH SSH CONNECTION FOR USER: students
<serverb.lab.example.com> EXEC ssh -C -vvv -o ControlMaster=auto
-o ControlPersist=60s -o Port=22 -o KbdInteractiveAuthentication=no
-o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey
-o PasswordAuthentication=no -o User=students -o ConnectTimeout=10
-o ControlPath=/home/student/.ansible/cp/ansible-ssh-%C -tt
serverb.lab.example.com '/bin/sh -c '"'"'( umask 22 && mkdir -p "`
echo $HOME/.ansible/tmp/ansible-tmp-1460241127.16-3182613343880 `" &&
echo "` echo $HOME/.ansible/tmp/ansible-tmp-1460241127.16-3182613343880
`" )'"'"''
...output omitted...
fatal: [serverb.lab.example.com]: UNREACHABLE! => {
...output omitted...

6.2. Edite la guía secure-web.yml para asegurarse de que devops sea el remote_user
para la reproducción. Las primeras líneas de la guía deberían aparecer de la siguiente
manera:

---
# start of secure web server playbook
- name: create secure web service
hosts: webservers
remote_user: devops
...output omitted...

7. Ejecute la guía secure-web.yml por tercera vez. Solucione el problema que se informa.

7.1. Ejecute la guía secure-web.yml.

[student@workstation troubleshoot-review]$ ansible-playbook secure-web.yml -vvvv


...output omitted...
failed: [serverb.lab.example.com] (item=mod_ssl) => {
"ansible_loop_var": "item",
"changed": false,
"invocation": {
"module_args": {
"allow_downgrade": false,
"autoremove": false,
...output omitted...
"validate_certs": true
}
},
"item": "mod_ssl",
"msg": "This command has to be run under the root user.",
"results": []
}
...output omitted...

382 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

7.2. Edite la reproducción para asegurarse de tener configurado become: true o


become: yes. El cambio resultante debe aparecer de la siguiente manera:

---
# start of secure web server playbook
- name: create secure web service
hosts: webservers
remote_user: devops
become: true
...output omitted...

8. Ejecute la guía secure-web.yml una vez más. Se debe completar correctamente. Use un
comando ad hoc para verificar que el servicio httpd esté funcionando.

8.1. Ejecute la guía secure-web.yml.

[student@workstation troubleshoot-review]$ ansible-playbook secure-web.yml


PLAY [create secure web service] ***********************************************
...output omitted...
TASK [install web server packages] *********************************************
changed: [serverb.lab.example.com] => (item=httpd)
changed: [serverb.lab.example.com] => (item=mod_ssl)
...output omitted...
TASK [httpd_conf_syntax variable] **********************************************
ok: [serverb.lab.example.com] => {
"msg": "The httpd_conf_syntax variable value is {'stderr_lines': [u'Syntax
OK'], u'changed': True, u'end': u'2018-12-17 23:31:53.191871', 'failed': False,
u'stdout': u'', u'cmd': [u'/sbin/httpd', u'-t'], u'rc': 0, u'start': u'2018-12-17
23:31:53.149759', u'stderr': u'Syntax OK', u'delta': u'0:00:00.042112',
'stdout_lines': [], 'failed_when_result': False}"
}
...output omitted...
RUNNING HANDLER [restart services] *********************************************
changed: [serverb.lab.example.com]

PLAY RECAP *********************************************************************


serverb.lab.example.com : ok=10 changed=7 unreachable=0 failed=0

8.2. Use un comando ad hoc para determinar el estado del servicio httpd en
serverb.lab.example.com. El servicio httpd ahora debe ejecutarse en
serverb.lab.example.com.

[student@workstation troubleshoot-review]$ ansible all -u devops -b \


> -m command -a 'systemctl status httpd'
serverb.lab.example.com | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset:
disabled)
Active: active (running) since Thu 2019-04-11 03:22:34 EDT; 28s ago
...output omitted...

RH294-RHEL8.0-es-1-20200501 383
capítulo 9 | Resolución de problemas de Ansible

Evaluación
En workstation, ejecute el script lab troubleshoot-review grade para confirmar que ha
realizado correctamente este ejercicio.

[student@workstation ~]$ lab troubleshoot-review grade

Finalizar
En workstation, ejecute el script lab troubleshoot-review finish para limpiar este
trabajo de laboratorio.

[student@workstation ~]$ lab troubleshoot-review finish

Esto concluye el trabajo de laboratorio.

384 RH294-RHEL8.0-es-1-20200501
capítulo 9 | Resolución de problemas de Ansible

Resumen
En este capítulo, aprendió lo siguiente:

• Ansible brinda un registro incorporado. Esta función no se encuentra disponible de manera


predeterminada.

• El parámetro log_path en la sección default del archivo de configuración ansible.cfg


especifica la ubicación del archivo de registro al que se redirige el resultado de Ansible.

• El módulo debug brinda información adicional de depuración al tiempo que ejecuta la guía (por
ejemplo, el valor actual para una variable).

• La opción -v del comando ansible-playbook brinda varios niveles de detalle de resultados.


Esto es útil para la depuración de las tareas de Ansible al ejecutar una guía.

• La opción --check habilita los módulos de Ansible con soporte de modo de verificación para
que se muestren los cambios que se deben realizar, en lugar de aplicar estos cambios a los hosts
administrados.

• Se pueden ejecutar verificaciones adicionales en los hosts administrados mediante comandos


ad hoc.

RH294-RHEL8.0-es-1-20200501 385
386 RH294-RHEL8.0-es-1-20200501
capítulo 10

Automatización de tareas de
administración de Linux
Meta Automatizar las tareas de administración comunes
del sistema Linux con Ansible.

Objetivos • Suscribir sistemas, configurar canales de


software y repositorios, y gestionar paquetes
RPM en hosts administrados.
• Administrar usuarios y grupos de Linux,
configurar SSH y modificar la configuración de
Sudo en hosts administrados.
• Administrar el inicio del servicio, programar
procesos con at, cron y systemd, reiniciar y
controlar el destino de inicio predeterminado
en los hosts administrados.
• Particionar los dispositivos de almacenamiento,
configurar LVM, formatear particiones o
volúmenes lógicos, montar sistemas de
archivos, y agregar espacios o archivos de
intercambio.

Secciones • Administración de software y suscripciones


(ejercicio guiado)
• Administración de usuarios y autenticación
(Ejercicio guiado)
• Administración del proceso de arranque y
procesos programados (Ejercicio guiado)
• Administración de almacenamiento (ejercicio
guiado)
• Administración de la configuración de red
(ejercicio guiado)

Trabajo de • Automatización de tareas de administración de


Linux
laboratorio

RH294-RHEL8.0-es-1-20200501 387
capítulo 10 | Automatización de tareas de administración de Linux

Administración de software y
suscripciones

Objetivos
Tras finalizar esta sección, debe poder suscribir sistemas, configurar canales de software y
repositorios, y gestionar paquetes RPM en hosts administrados.

Administración de paquetes con Ansible


El módulo yum de Ansible usa Yum Package Manager en los hosts administrados para manejar las
operaciones de paquetes. El siguiente ejemplo es una guía que instala el paquete httpd en el host
administrado servera.lab.example.com.

---
- name: Install the required packages on the web server
hosts: servera.lab.example.com
tasks:
- name: Install the httpd packages
yum:
name: httpd
state: present

La palabra clave name da el nombre del paquete para instalar.


La palabra clave state indica el estado esperado del paquete en el host administrado:

present
Ansible instala el paquete si aún no está instalado.

absent
Ansible elimina el paquete si está instalado.

latest
Ansible actualiza el paquete si aún no está en la versión más reciente disponible. Si el
paquete no está instalado, Ansible lo instala.

La tabla siguiente compara algunos usos del módulo de Ansible yum con el comando equivalente
yum.

Tarea de Ansible Comando de Yum

yum install
- name: Install httpd
httpd
yum:
name: httpd
state: present

388 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Tarea de Ansible Comando de Yum

yum update
- name: Install or update httpd
httpd o yum
yum:
install httpd si
name: httpd
el paquete aún no
state: latest
está instalado.

yum update
- name: Update all packages
yum:
name: '*'
state: latest

yum remove
- name: Remove httpd
httpd
yum:
name: httpd
state: absent

yum group
- name: Install Development Tools
install
yum:
"Development
name: '@Development Tools'
Tools"
state: present

Con el módulo de Ansible yum, debe agregar a los nombres de


grupos el prefijo @. Recuerde que puede recuperar la lista de
grupos con el comando yum group list.

yum group
- name: Remove Development Tools
remove
yum:
"Development
name: '@Development Tools'
Tools"
state: absent

yum module
- name: Inst perl AppStream module
install
yum:
perl:5.26/
name: '@perl:5.26/minimal'
minimal
state: present

Para administrar un módulo AppStream de Yum, agregue a su


nombre el prefijo @. La sintaxis es la misma que para el comando
yum. Por ejemplo, puede omitir la parte del perfil para usar el perfil
predeterminado: @perl:5.26. Recuerde que puede enumerar
los módulos AppStreamde Yum disponibles con el comando yum
module list.

Ejecute el comando ansible-doc yum para obtener ejemplos de parámetros y de guía


adicionales.

RH294-RHEL8.0-es-1-20200501 389
capítulo 10 | Automatización de tareas de administración de Linux

Optimización de la instalación de varios paquetes


Para operar en varios paquetes, la palabra clave name acepta una lista. En el siguiente ejemplo, se
muestra una guía que instala tres paquetes en servera.lab.example.com.

---
- name: Install the required packages on the web server
hosts: servera.lab.example.com
tasks:
- name: Install the packages
yum:
name:
- httpd
- mod_ssl
- httpd-tools
state: present

Con esta sintaxis, Ansible instala los paquetes en una sola transacción de Yum. Esto es equivalente
a ejecutar el comando yum install httpd mod_ssl httpd-tools.

Una versión más común pero menos eficiente y más lenta de esta tarea es usar un bucle.

---
- name: Install the required packages on the web server
hosts: servera.lab.example.com
tasks:
- name: Install the packages
yum:
name: "{{ item }}""
state: present
loop:
- httpd
- mod_ssl
- httpd-tools

Evite usar este método, ya que requiere que el módulo realice tres transacciones individuales, una
para cada paquete.

Recopilación de datos sobre paquetes instalados


El módulo de Ansible package_facts recopila los detalles del paquete instalado en los hosts
administrados. Establece la variable ansible_facts.packages con los detalles del paquete.

La guía siguiente llama al módulo package_facts, al módulo debug para visualizar el contenido
de la variable ansible_facts.packages, y al módulo debug de nuevo para ver la versión del
paquete NetworkManager instalado.

---
- name: Display installed packages
hosts: servera.lab.example.com
tasks:
- name: Gather info on installed packages
package_facts:
manager: auto

390 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

- name: List installed packages


debug:
var: ansible_facts.packages

- name: Display NetworkManager version


debug:
msg: "Version {{ansible_facts.packages['NetworkManager'][0].version}}"
when: "'NetworkManager' in ansible_facts.packages"

Cuando se ejecuta, la guía muestra la lista de paquetes y la versión del paquete NetworkManager:

[user@controlnode ~]$ ansible-playbook lspackages.yml

PLAY [Display installed packages] ******************************************

TASK [Gathering Facts] *****************************************************


ok: [servera.lab.example.com]

TASK [Gather info on installed packages] ***********************************


ok: [servera.lab.example.com]

TASK [List installed packages] *********************************************


ok: [servera.lab.example.com] => {
"ansible_facts.packages": {
"NetworkManager": [
{
"arch": "x86_64",
"epoch": 1,
"name": "NetworkManager",
"release": "14.el8",
"source": "rpm",
"version": "1.14.0"
}
],
...output omitted...
"zlib": [
{
"arch": "x86_64",
"epoch": null,
"name": "zlib",
"release": "10.el8",
"source": "rpm",
"version": "1.2.11"
}
]
}
}

TASK [Display NetworkManager version] **************************************


ok: [servera.lab.example.com] => {
"msg": "Version 1.14.0"
}

RH294-RHEL8.0-es-1-20200501 391
capítulo 10 | Automatización de tareas de administración de Linux

PLAY RECAP *****************************************************************


servera.lab.example.com : ok=4 changed=0 unreachable=0 failed=0

Revisión de módulos alternativos para administrar paquetes


El módulo de Ansible yum funciona en hosts administrados que usan el administrador de paquetes
de Yum. Para otros administradores de paquetes, Ansible generalmente proporciona un módulo
dedicado. Por ejemplo, el módulo dnf administra los paquetes en sistemas operativos como
Fedora con el administrador de paquetes DNF. El módulo apt usa la herramienta de paquetes APT
disponible en Debian o Ubuntu. El módulo win_package puede instalar software en sistemas de
Microsoft Windows.

La guía siguiente usa condicionales para seleccionar el módulo apropiado en un entorno


compuesto por sistemas de Red Hat Enterprise Linux y Fedora.

---
- name: Install the required packages on the web servers
hosts: webservers
tasks:
- name: Install httpd on RHEL
yum:
name: httpd
state: present
when: "ansible_distribution == 'RedHat'"

- name: Install httpd on Fedora


dnf:
name: httpd
state: present
when: "ansible_distribution == 'Fedora'"

Como alternativa, el módulo genérico package detecta y usa automáticamente el administrador


de paquetes disponible en los hosts administrados. Con el módulo package, puede volver a
escribir la guía anterior de la siguiente manera.

---
- name: Install the required packages on the web servers
hosts: webservers
tasks:
- name: Install httpd
package:
name: httpd
state: present

Sin embargo, tenga en cuenta que el módulo package no es compatible con todas las funciones
que proporcionan los módulos más especializados. Además, los sistemas operativos a menudo
tienen nombres diferentes para los paquetes que proporcionan. Por ejemplo, el paquete que
instala el servidor HTTP Apache es httpd en Red Hat Enterprise Linux y apache2 en Ubuntu. En
ese caso, aún necesita un condicional para seleccionar el nombre correcto del paquete en función
del sistema operativo del host administrado.

392 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Registro y administración de sistemas con la


administración de suscripciones de Red Hat
Para habilitar las suscripciones de productos en sus nuevos sistemas de Red Hat Enterprise Linux,
Ansible proporciona los módulos redhat_subscription y rhsm_repository. Estos módulos
interactúan con la herramienta Red Hat Subscription Management en los hosts administrados.

Registro y suscripción de nuevos sistemas


Las dos primeras tareas que normalmente se realizan con la herramienta Red Hat Subscription
Management son registrar el nuevo sistema y adjuntar una suscripción disponible.

Sin Ansible, estas tareas se realizan con el comando subscription-manager:

[user@host ~]$ subscription-manager register --username=yourusername \


> --password=yourpassword
[user@host ~]$ subscription-manager attach --pool=poolID

Recuerde que el comando subscription-manager list --available enumera los


conjuntos (pools) disponibles en su cuenta.

El módulo de Ansible redhat_subscription realiza el registro y la suscripción en una tarea.

- name: Register and subscribe the system


redhat_subscription:
username: yourusername
password: yourpassword
pool_ids: poolID
state: present

La palabra clave state establecida en present indica que el sistema debe registrarse y
suscribirse. Cuando se establece en absent, el módulo anula el registro del sistema.

Habilitación de repositorios de software de Red Hat


La siguiente tarea después de la suscripción es habilitar los repositorios de software de Red Hat
en el nuevo sistema.

Sin Ansible, se suele ejecutar el comando subscription-manager para ese propósito:

[user@host ~]$ subscription-manager repos \


> --enable "rhel-8-for-x86_64-baseos-rpms" \
> --enable "rhel-8-for-x86_64-baseos-debug-rpms"

Recuerde que puede enumerar los repositorios disponibles con el comando subscription-
manager repos --list.

Con Ansible, use el módulo rhsm_repository:

RH294-RHEL8.0-es-1-20200501 393
capítulo 10 | Automatización de tareas de administración de Linux

- name: Enable Red Hat repositories


rhsm_repository:
name:
- rhel-8-for-x86_64-baseos-rpms
- rhel-8-for-x86_64-baseos-debug-rpms
state: present

Configuración de un repositorio de Yum


Para habilitar el soporte para un repositorio de terceros en un host administrado, Ansible
proporciona el módulo yum_repository.

Declaración de un repositorio de Yum


Cuando se ejecuta, la guía siguiente declara un nuevo repositorio en
servera.lab.example.com.

---
- name: Configure the company Yum repositories
hosts: servera.lab.example.com
tasks:
- name: Ensure Example Repo exists
yum_repository:
file: example
name: example-internal
description: Example Inc. Internal YUM repo
baseurl: http://materials.example.com/yum/repository/
enabled: yes
gpgcheck: yes
state: present

La palabra clave file da el nombre del archivo que se creará en el directorio /etc/
yum.repos.d/. El módulo agrega automáticamente la extensión .repo a ese nombre.
Por lo general, los proveedores de software firman digitalmente paquetes RPM con claves
GPG. Al establecer la palabra clave gpgcheck en yes (sí), el sistema RPM verifica la
integridad del paquete al confirmar que el paquete fue firmado por la clave GPG apropiada.
Rechaza la instalación de un paquete si la firma GPG no coincide. Use el módulo de Ansible
rpm_key, descrito más adelante, para instalar la clave GPG pública requerida.
Al configurar la palabra clave state en present, Ansible crea o actualiza el archivo .repo.
Al configurar state en absent, Ansible elimina el archivo.

El archivo /etc/yum.repos.d/example.repo resultante en servera.lab.example.com es


como sigue.

[example-internal]
baseurl = http://materials.example.com/yum/repository/
enabled = 1
gpgcheck = 1
name = Example Inc. Internal YUM repo

El módulo yum_repository expone la mayoría de los parámetros de configuración del


repositorio de Yum como palabras clave. Ejecute el comando ansible-doc yum_repository
para obtener ejemplos de parámetros y de guía adicionales.

394 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

nota
Algunos repositorios de terceros proporcionan el archivo de configuración y la
clave pública de GPG como parte del paquete de RPM que puede descargarse e
instalarse con el comando yum install. Por ejemplo, el proyecto Extra Packages
for Enterprise Linux (EPEL) proporciona el paquete https://dl.fedoraproject.org/
pub/epel/epel-release-latest-VER.noarch.rpm que implementa el archivo de
configuración /etc/yum.repos.d/epel.repo. Para este repositorio, use
el módulo de Ansible yum para instalar el paquete EPEL en lugar del módulo
yum_repository.

Importación de una clave GPG de RPM


Cuando la palabra clave gpgcheck se establece en yes en el módulo yum_repository, también
debe instalar la clave GPG en el host administrado. El módulo rpm_key del siguiente ejemplo
implementa en servera.lab.example.com la clave pública GPG alojada en un servidor web
remoto.

---
- name: Configure the company Yum repositories
hosts: servera.lab.example.com
tasks:
- name: Deploy the GPG public key
rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present

- name: Ensure Example Repo exists


yum_repository:
file: example
name: example-internal
description: Example Inc. Internal YUM repo
baseurl: http://materials.example.com/yum/repository/
enabled: yes
gpgcheck: yes
state: present

RH294-RHEL8.0-es-1-20200501 395
capítulo 10 | Automatización de tareas de administración de Linux

Referencias
Páginas del manual: yum(8), yum.conf(5), subscription-manager(8)

yum — Administra paquetes con el administrador de paquetes de yum —


Documentación de Ansible
https://docs.ansible.com/ansible/latest/modules/yum_module.html

package_facts — Información del paquete como datos — Documentación de


Ansible
https://docs.ansible.com/ansible/latest/modules/package_facts_module.html

redhat_subscription — Administre el registro y las suscripciones a RHSM con el


comando subscription-manager — Documentación de Ansible
https://docs.ansible.com/ansible/latest/modules/redhat_subscription_module.html

rhsm_repository — Administre repositorios RHSM con el comando


subscription-manager — Documentación de Ansible
https://docs.ansible.com/ansible/latest/modules/rhsm_repository_module.html

yum_repository — Agregue o elimine repositorios de YUM — Documentación de


Ansible
https://docs.ansible.com/ansible/latest/modules/yum_repository_module.html

rpm_key: Agrega o elimina una clave gpg de la base de datos de rpm —


Documentación de Ansible
https://docs.ansible.com/ansible/latest/modules/rpm_key_module.html

396 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Ejercicio Guiado

Administración de software y
suscripciones
En este ejercicio, configurará un nuevo repositorio de Yum y, desde allí, instalará paquetes en
sus hosts administrados.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Configurar un repositorio de yum con el módulo yum_repository.

• Administrar las claves GPG de RPM con el módulo rpm_key.

• Obtener información sobre los paquetes instalados en un host con el módulo


package_facts.

Andes De Comenzar
En workstation, ejecute el script de inicio del trabajo de laboratorio a fin de confirmar que
el entorno esté listo para que comience el trabajo de laboratorio. El script crea el directorio
de trabajo, denominado system-software, y lo completa con un archivo de configuración
Ansible, un inventario de hosts y archivos de laboratorio.

[student@workstation ~]$ lab system-software start

Descripción general del escenario


Su organización requiere que todos los hosts tengan el paquete example-motd instalado. Este
paquete lo proporciona un repositorio interno de Yum que mantiene su organización para alojar
paquetes de software desarrollados internamente.

Tiene la tarea de escribir una guía para asegurarse de que el paquete example-motd esté instalado
en el host remoto. La guía debe garantizar la configuración del repositorio interno de Yum.

El repositorio se encuentra en http://materials.example.com/yum/repository. Todos


los paquetes RPM están firmados con un par de claves GPG organizativas. La clave pública de
GPG está disponible en http://materials.example.com/yum/repository/RPM-GPG-
KEY-example.

1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-software.

[student@workstation ~]$ cd ~/system-software


[student@workstation system-software]$

2. Empiece a escribir la guía repo_playbook.yml. Defina una sola reproducción en la guía


que se dirige a todos los hosts. Agregue una cláusula vars que defina una sola variable
custom_pkg con un valor de example-motd. Agregue la cláusula tasks a la guía.

RH294-RHEL8.0-es-1-20200501 397
capítulo 10 | Automatización de tareas de administración de Linux

La guía ahora contiene lo siguiente:

---
- name: Repository Configuration
hosts: all
vars:
custom_pkg: example-motd
tasks:

3. Agregue dos tareas a la guía.


Use el módulo package_facts de la primera tarea para recolectar información
sobre los paquetes instalados en el host remoto. Esta tarea completa el dato
ansible_facts.packages.
Utilice el módulo depurar en la segunda tarea para imprimir la versión instalada del
paquete al que hace referencia la variable custom_pkg. Solo ejecute esta tarea si el
paquete personalizado se encuentra en el dato ansible_facts.packages.
Ejecute la guía repo_playbook.yml.

3.1. Agregue la primera tarea a la guía. Configure la palabra clave manager del módulo
package_facts con un valor auto. La primera tarea contiene lo siguiente:

- name: Gather Package Facts


package_facts:
manager: auto

3.2. Agregue una segunda tarea a la guía que usa el módulo depurar para mostrar el
valor de la variable ansible_facts.packages[custom_pkg]. Agregue una
cláusula cuando a la tarea para comprobar si el valor de la variable custom_pkg está
contenida en la variable ansible_facts.packages. La segunda tarea contiene lo
siguiente:

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

3.3. Ejecute la guía:

[student@workstation system-software]$ ansible-playbook repo_playbook.yml

PLAY [Repository Configuration] **********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Gather Package Facts] **************************************************


ok: [servera.lab.example.com]

TASK [Show Package Facts for the custom package] *****************************


skipping: [servera.lab.example.com]

398 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

La tarea de depuración se omite porque el paquete example-motd no está instalado


en el host remoto.

4. Agregue una tercera tarea que use el módulo yum_repository para asegurar la
configuración del repositorio yum interno en el host remoto. Asegúrese de lo siguiente:

• La configuración del repositorio se almacena en el archivo /etc/yum.repos.d/


example.repo.

• El ID del repositorio es example-internal.

• La URL base es http://materials.example.com/yum/repository.

• El repositorio está configurado para verificar las firmas RPM GPG.

• La descripción del repositorio es repositorio YUM interno de Ejemplo Inc.

La tercera tarea contiene lo siguiente:

- name: Ensure Example Repo exists


yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes

5. Agregue una cuarta tarea a la guía que use el módulo rpm_key para asegurarse de que la
clave pública del repositorio esté presente en el host remoto. La URL de la clave pública del
repositorio es http://materials.example.com/yum/repository/RPM-GPG-KEY-
example.
La cuarta tarea aparece de la siguiente manera:

- name: Ensure Repo RPM Key is Installed


rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present

6. Agregue una quinta tarea para asegurarse de que el paquete al que hace referencia la
variable custom_pkg esté instalado en el host remoto.
La quinta tarea aparece de la siguiente manera:

- name: Install Example motd package


yum:
name: "{{ custom_pkg }}"
state: present

RH294-RHEL8.0-es-1-20200501 399
capítulo 10 | Automatización de tareas de administración de Linux

7. El dato ansible_facts.packages no se actualiza cuando se instala un nuevo paquete


en un host remoto.
Copie la segunda tarea y agréguela como la sexta tarea en la guía. Ejecute la guía y
verifique que el dato ansible_facts.packages no contenga información sobre el
paquete example-motd instalado en el host remoto.

7.1. La sexta tarea contiene una copia de la segunda tarea:

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

La guía completa ahora se ve de la siguiente manera:

---
- name: Repository Configuration
hosts: all
vars:
custom_pkg: example-motd
tasks:
- name: Gather Package Facts
package_facts:
manager: auto

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

- name: Ensure Example Repo exists


yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes

- name: Ensure Repo RPM Key is Installed


rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present

- name: Install Example motd package


yum:
name: "{{ custom_pkg }}"
state: present

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

7.2. Ejecute la guía.

400 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-software]$ ansible-playbook repo_playbook.yml


PLAY [Repository Configuration] **********************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Gather Package Facts] **************************************************


ok: [servera.lab.example.com]

TASK [Show Package Facts for the custom package] *****************************


skipping: [servera.lab.example.com]

TASK [Ensure Example Repo exists] ********************************************


changed: [servera.lab.example.com]

TASK [Ensure Repo RPM Key is Installed] **************************************


changed: [servera.lab.example.com]

TASK [Install Example motd package] ******************************************


changed: [servera.lab.example.com]

TASK [Show Package Facts for the custom package] *****************************


skipping: [servera.lab.example.com]

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=5 changed=3 unreachable=0 failed=0
skipped=2 rescued=0 ignored=0

La tarea Recopilar datos del paquete determina los datos contenidos en


el dato ansible_facts.packages.
La tarea se omite porque el paquete example-motd se instala después de la
tarea Recopilar datos del paquete.

8. Inserte una tarea inmediatamente después de la tarea Instalar el paquete motd


de ejemplo usando el módulo package_facts para actualizar los datos del paquete.
Establezca la palabra clave manager del módulo con un valor auto.
A continuación, se muestra la guía completa:

---
- name: Repository Configuration
hosts: all
vars:
custom_pkg: example-motd
tasks:
- name: Gather Package Facts
package_facts:
manager: auto

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

RH294-RHEL8.0-es-1-20200501 401
capítulo 10 | Automatización de tareas de administración de Linux

- name: Ensure Example Repo exists


yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes

- name: Ensure Repo RPM Key is Installed


rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present

- name: Install Example motd package


yum:
name: "{{ custom_pkg }}"
state: present

- name: Gather Package Facts


package_facts:
manager: auto

- name: Show Package Facts for the custom package


debug:
var: ansible_facts.packages[custom_pkg]
when: custom_pkg in ansible_facts.packages

9. Utilice un comando ad hoc Ansible para eliminar el paquete example-motd instalado


durante la ejecución previa de la guía. Ejecute la guía con la tarea package_facts
insertada y utilice los resultados para verificar la instalación del paquete example-motd.

9.1. Para quitar el paquete example-motd de todos los hosts, utilice el comando ansible
all con las opciones -m yum y -a 'name=example-motd state=absent'

[student@workstation system-software]$ ansible all -m yum \


> -a 'name=example-motd state=absent'
servera.lab.example.com | CHANGED => {
...output omitted...
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: example-motd-1.0-1.el7.x86_64"
]
...output omitted...

9.2. Ejecute la guía.

[student@workstation system-software]$ ansible-playbook repo_playbook.yml

PLAY [Repository Configuration] **********************************************

TASK [Gathering Facts] *******************************************************

402 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

ok: [servera.lab.example.com]

TASK [Gather Package Facts] **************************************************


ok: [servera.lab.example.com]

TASK [Show Package Facts for the custom package] *****************************


skipping: [servera.lab.example.com]

...output omitted...

TASK [Install Example motd package] ******************************************


changed: [servera.lab.example.com]

TASK [Gather Package Facts] **************************************************


ok: [servera.lab.example.com]

TASK [Show Package Facts for example-motd] ***********************************


ok: [servera.lab.example.com] => {
"ansible_facts.packages[custom_pkg]": [
{
"arch": "x86_64",
"epoch": null,
"name": "example-motd",
"release": "1.el7",
"source": "rpm",
"version": "1.0"
}
]
}

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=7 changed=1 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

No existe un dato de paquete para el paquete example-motd porque el paquete


no está instalado en el host remoto.
El paquete example-motd se instala como resultado de esta tarea, como lo
indica el estado changed.
Esta tarea actualiza los datos del paquete con información sobre el paquete
example-motd.
El dato de paquete example-motd existe e indica que solo un paquete example-
motd está instalado. El paquete instalado está en la versión 1.0.

Finalizar
En workstation, ejecute el script lab system-software finish para limpiar los recursos
creados en este ejercicio.

[student@workstation ~]$ lab system-software finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 403
capítulo 10 | Automatización de tareas de administración de Linux

Administración de usuarios y
autenticación

Objetivos
Tras finalizar esta sección, usted deberá ser capaz de realizar lo siguiente:

• Aprovisionar varias cuentas de usuario en varios servidores.

• Administrar usuarios y grupos de Linux, configurar SSH y modificar la configuración de Sudo en


hosts administrados.

El modulo user (usuario)


El módulo user de Ansible permite administrar cuentas de usuario en un host remoto. Puede
administrar una serie de parámetros que incluyen eliminar usuario, configurar directorio de inicio,
configurar el UID para las cuentas del sistema, administrar contraseñas y agrupaciones asociadas.
Para crear un usuario que pueda iniciar sesión en la máquina, debe proporcionar una contraseña
con hash para el parámetro de contraseña. Consulte la sección de referencia para obtener un
enlace a "¿Cómo generar contraseñas cifradas para el módulo user?"

Ejemplo del módulo user


- name: Add new user to the development machine and assign the appropriate groups.
user:
name: devops_user
shell: /bin/bash
groups: sys_admins, developers
append: yes

El parámetro name es el único requisito en el módulo user y suele ser la cuenta de servicio o
la cuenta de usuario.
El parámetro shell establece la shell del usuario de manera opcional. En otros sistemas
operativos, la shell predeterminada se decide por la herramienta que se usa.
El parámetro groups, junto con el parámetro append, le indica a la máquina que queremos
adjuntar los grupos sys_admins y developers con este usuario. Si no usa el parámetro append,
los grupos se sobrescribirán en su lugar.

Al crear un usuario puede especificar la función generate_ssh_key. Esto no sobrescribirá una


clave SSH existente.

Ejemplo de módulo user que genera una clave ssh


- name: Create a SSH key for user1
user:
name: user1
generate_ssh_key: yes
ssh_key_bits: 2048
ssh_key_file: .ssh/id_my_rsa

404 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

nota
El módulo user también ofrece algunos valores de retorno. Los módulos de Ansible
pueden tomar un valor de retorno y registrarlos en una variable. Obtenga más
información con ansible-doc y en el sitio principal de documentos.

Algunos parámetros de uso común

Parámetro Comentarios

comment (comentario) Opcionalmente, establece la descripción de una cuenta de


usuario.

group (grupo) Opcionalmente, establece el grupo primario del usuario.

groups (grupos) Lista de varios grupos. Cuando se establece en un valor nulo,


se eliminan todos los grupos excepto el grupo primario.

home (inicio) Opcionalmente, establece el directorio de inicio del usuario.

create_home (crear inicio) Toma un valor booleano de yes o no. Se creará un directorio
de inicio para el usuario si el valor se establece en yes.

system Al crear un estado de cuenta =present, establecer este


parámetro en yes convierte al usuario en una cuenta del
sistema. Esta configuración no se puede cambiar en los
usuarios existentes.

uid Establece el usuario od de UID.

El módulo group
El módulo group permite administrar (agregar, eliminar, modificar) grupos en los hosts
administrados. Debe tener groupadd, groupdel o groupmod. Para los objetivos de Windows,
use el módulo win_group.

Ejemplo del módulo group


- name: Verify that auditors group exists
group:
name: auditors
state: present

Parámetros para el módulo group

Parámetro Comentarios

gid GID opcional para establecer para el grupo.

local Fuerza el uso de alternativas de comandos "locales" en


plataformas que lo implementan.

name Nombre del grupo que se administrará.

RH294-RHEL8.0-es-1-20200501 405
capítulo 10 | Automatización de tareas de administración de Linux

Parámetro Comentarios

state Determina si el grupo debe estar presente o no en el host


remoto.

system Si se establece en yes, indica que el grupo creado es un grupo


del sistema.

El módulo known hosts (host conocido)


Si tiene una gran cantidad de claves de host para administrar, querrá usar el módulo
known_hosts. El módulo known_hosts permite agregar o eliminar claves de host del archivo
known_hosts en el host administrado.

Ejemplo de tareas de known_host


- name: copy host keys to remote servers
known_hosts:
path: /etc/ssh/ssh_known_hosts
name: user1
key: "{{ lookup('file', 'pubkeys/user1') }}"

El complemento (plug-in) lookup (búsqueda) permite que Ansible acceda a datos de


fuentes externas.

El módulo authorized key (clave autorizada)


El módulo authorized_key permite agregar o eliminar claves SSH autorizadas por cuenta de
usuario. Al agregar y quitar usuarios a un gran banco de servidores, debe poder administrar las
claves ssh.

Ejemplo de tareas de authorized_key

- name: Set authorized key


authorized_key:
user: user1
state: present
key: "{{ lookup('file', '/home/user1/.ssh/id_rsa.pub') }}

También se puede tomar una clave de una url: https://github.com/user1.keys.

406 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Referencias
Documentación de Ansible del módulo users
http://docs.ansible.com/ansible/latest/modules/user_module.html#user-module
¿Cómo genero contraseñas cifradas para el módulo user?
https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#how-do-i-
generate-crypted-passwords-for-the-user-module
Documentación de Ansible del módulo group
https://docs.ansible.com/ansible/latest/modules/group_module.html#group-
module
Documentación de Ansible del módulo SSH known hosts
https://docs.ansible.com/ansible/latest/modules/
known_hosts_module.html#known-hosts-module
Documentación de Ansible del módulo authorized_key
https://docs.ansible.com/ansible/latest/modules/
authorized_key_module.html#authorized-key-module
Documentación de Ansible del complemento (plug-in) lookup
https://docs.ansible.com/ansible/latest/plugins/lookup.html?highlight=lookup

RH294-RHEL8.0-es-1-20200501 407
capítulo 10 | Automatización de tareas de administración de Linux

Ejercicio Guiado

Administración de usuarios y
autenticación
En este ejercicio, creará múltiples usuarios en sus hosts administrados y llenará las claves
SSH autorizadas para ellos.

Resultados
Deberá poder realizar lo siguiente:

• Crear un nuevo grupo de usuarios.

• Administrar usuarios con el módulo user.

• Llene claves SSH autorizadas con el módulo authorized_key.

• Modifique los archivos sudoers y sshd_config con el módulo lineinfile.

Andes De Comenzar
En workstation, ejecute el script de inicio del trabajo de laboratorio a fin de confirmar que
el entorno esté listo para que comience el trabajo de laboratorio. El script crea el directorio
de trabajo, denominado system-users, y lo completa con un archivo de configuración
Ansible, un inventario de hosts y algunos archivos de laboratorio.

[student@workstation ~]$ lab system-users start

Descripción general del escenario


Su organización requiere que todos los hosts tengan los mismos usuarios locales disponibles.
Estos usuarios deben pertenecer al grupo de usuarios webadmin, que tiene la capacidad de usar
el comando sudo sin especificar una contraseña. Además, las claves públicas SSH de los usuarios
deben distribuirse en el entorno y no se debe permitir al usuario root iniciar sesión usando SSH
directamente.

Tiene la tarea de escribir una guía para asegurarse de que los usuarios y el grupo de usuarios estén
presentes en el host remoto. La guía debe garantizar que los usuarios puedan iniciar sesión con la
clave SSH autorizada, así como usar sudo sin especificar una contraseña, y que el usuario root no
pueda iniciar sesión directamente usando SSH.

1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-users.

[student@workstation ~]$ cd ~/system-users


[student@workstation system-users]$

2. Echa un vistazo al archivo de variable existente vars/users_vars.yml.

408 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-users]$ cat vars/users_vars.yml


---
users:
- username: user1
groups: webadmin
- username: user2
groups: webadmin
- username: user3
groups: webadmin
- username: user4
groups: webadmin
- username: user5
groups: webadmin

Use el nombre de variable username para establecer el nombre de usuario correcto y la


variable groups para definir grupos adicionales a los que el usuario debe pertenecer.

3. Empiece a escribir la guía users.yml. Defina una sola jugada en la guía que se dirija al
grupo de hosts webservers. Agregue una cláusula vars_files que defina la ubicación
del nombre de archivo vars/users_vars.yml, que se ha creado para usted y que
contiene todos los nombres de usuario necesarios para este ejercicio. Agregue la cláusula
tasks a la guía.
Use un editor de texto para crear la guía users.yml. La guía debe contener lo siguiente:

---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
tasks:

4. Agregue dos tareas a la guía.


Use el módulo group en la primera tarea para crear el grupo de usuarios webadmin en el
host remoto. Esta tarea crea el grupo webadmi.
Use el módulo user en la segunda tarea para crear los usuarios del archivo vars/
users_vars.yml.
Ejecute la guía users.yml.

4.1. Agregue la primera tarea a la guía. La primera tarea contiene lo siguiente:

- name: Add webadmin group


group:
name: webadmin
state: present

4.2. Agregue una segunda tarea a la guía que usa el módulo user para crear los usuarios.
Agregue una cláusula loop: "{{ users }}" a la tarea para recorrer en bucle el
archivo de variables para cada nombre de usuario encontrado en el archivo vars/
users_vars.yml. Como name: para los usuarios, use el nombre de variable
item.username. Esto permite que el archivo de variables contenga información

RH294-RHEL8.0-es-1-20200501 409
capítulo 10 | Automatización de tareas de administración de Linux

adicional que puede ser útil para crear los usuarios, como los grupos a los que
deberían pertenecer. La segunda tarea contiene lo siguiente:

- name: Create user accounts


user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"

4.3. Ejecute la guía.

[student@workstation system-users]$ ansible-playbook users.yml

PLAY [Create multiple local users] *******************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Add webadmin group] ****************************************************


changed: [servera.lab.example.com]

TASK [Create user accounts] **************************************************


changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups':
u'webadmin'})

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

5. Agregue una tercera tarea que use el módulo authorized_key para garantizar que las
claves públicas SSH se hayan distribuido correctamente en el host remoto. En el directorio
files, cada uno de los usuarios tiene un único archivo de clave pública SSH. El módulo
recorre en bucle la lista de usuarios, encuentra la clave apropiada usando la variable
username y envía la clave al host remoto.
La tercera tarea contiene lo siguiente:

- name: Add authorized keys


authorized_key:
user: "{{ item.username }}"
key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
loop: "{{ users }}"

6. Agregue una cuarta tarea a la reproducción que use el módulo copy para modificar el
archivo de configuración sudo y permitir a los miembros del grupo webadmin usar sudo
sin una contraseña en el host remoto.

410 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

La cuarta tarea aparece de la siguiente manera:

- name: Modify sudo config to allow webadmin users sudo without a password
copy:
content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
dest: /etc/sudoers.d/webadmin
mode: 0440

7. Agregue una quinta tarea para asegurarse de que el usuario root no tenga permitido
iniciar sesión usando SSH directamente. Use notify: "Restart sshd" para
desencadenar un manejador para reiniciar SSH.
La quinta tarea aparece como sigue:

- name: Disable root login via SSH


lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: Restart sshd

8. En la primera línea después de la ubicación del archivo de variables, agregue una nueva
definición de manejador. Asígnele el nombre de Restart sshd.

8.1. El manejador se debe definir de la siguiente manera:

...output omitted...
- vars/users_vars.yml
handlers:
- name: Restart sshd
service:
name: sshd
state: restarted

La guía completa ahora se ve de la siguiente manera:

---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
handlers:
- name: Restart sshd
service:
name: sshd
state: restarted

tasks:

- name: Add webadmin group


group:
name: webadmin
state: present

RH294-RHEL8.0-es-1-20200501 411
capítulo 10 | Automatización de tareas de administración de Linux

- name: Create user accounts


user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"

- name: Add authorized keys


authorized_key:
user: "{{ item.username }}"
key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
loop: "{{ users }}"

- name: Modify sudo config to allow webadmin users sudo without a password
copy:
content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
dest: /etc/sudoers.d/webadmin
mode: 0440

- name: Disable root login via SSH


lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: "Restart sshd"

8.2. Ejecute la guía.

[student@workstation system-users]$ ansible-playbook users.yml

PLAY [Create multiple local users] *******************************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Add webadmin group] ****************************************************


ok: [servera.lab.example.com]

TASK [Create user accounts] **************************************************


ok: [servera.lab.example.com] => (item={u'username': u'user1', u'groups':
u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user2', u'groups':
u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user3', u'groups':
u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user4', u'groups':
u'webadmin'})
ok: [servera.lab.example.com] => (item={u'username': u'user5', u'groups':
u'webadmin'})

TASK [Add authorized keys] ***************************************************


changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups':
u'webadmin'})

412 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups':


u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups':
u'webadmin'})
changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups':
u'webadmin'})

TASK [Modify sudo config to allow webadmin users sudo without a password] ***
changed: [servera.lab.example.com]

TASK [Disable root login via SSH] *******************************************


changed: [servera.lab.example.com]

RUNNING HANDLER [Restart sshd] **********************************************


changed: [servera.lab.example.com]

PLAY RECAP ******************************************************************


servera.lab.example.com : ok=7 changed=4 unreachable=0 failed=0

9. Como el usuario user1, inicie sesión en el servidor servera usando SSH. Una vez iniciada
la sesión, use el comando sudo su - para cambiar la identidad al usuario root .

9.1. Use SSH como usuario user1 e inicie sesión en el servidor servera.

[student@workstation system-users]$ ssh user1@servera


Activate the web console with: systemctl enable --now cockpit.socket

[user1@servera ~]$

9.2. Cambie la identidad al usuario root.

[user1@servera ~]$ sudo su -


Last login: Wed Dec 19 05:39:53 EST 2018 on pts/0
root@servera ~]#

9.3. Cierre sesión en el servidor servera.

[root@servera ~]$ exit


logout
[user1@servera ~]$ exit
logout
Connection to servera closed.
[student@workstation system-users]$

10. Intente iniciar sesión en el servidor servera, como el usuario root directamente. Este
paso debería fallar, ya que la configuración de SSH se modificó para no permitir inicios de
sesión directos del usuario root.

10.1. Desde workstation utilice SSH como root para iniciar sesión en el servidor
servera.

RH294-RHEL8.0-es-1-20200501 413
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-users]$ ssh root@servera


root@servera's password: redhat
Permission denied, please try again.
root@servera's password:

Esto confirma que la configuración SSH denegó el acceso directo al sistema para el
usuario root.

Finalizar
En workstation, ejecute el script lab system-users finish para limpiar los recursos creados
en este ejercicio.

[student@workstation ~]$ lab system-users finish

Esto concluye el ejercicio guiado.

414 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Administración del proceso de arranque y


procesos programados

Objetivos
Tras finalizar esta sección, deberá ser capaz de administrar el inicio del servicio, programar
procesos con at, cron y systemd, reiniciar y controlar el destino de inicio predeterminado en los
hosts administrados.

Programación con el módulo at


La programación rápida y de una vez se realiza con el módulo at. Se crea la tarea para que se
ejecute en una hora futura y se la retiene hasta que llegue el momento de ejecutarse. Hay seis
parámetros que vienen con este módulo. Ellos son los siguientes: command (comando), count
(cantidad), script_file (archivo de script), state (estado), unique (único) y units (unidades).

El ejemplo del módulo at:


- name: remove tempuser.
at:
command: userdel -r tempuser
count: 20
units: minutes
unique: yes

Parámetros

Parámetro Opciones Comentarios

command Nulo Un comando que está programado


para ejecutarse.

count Nulo La cantidad de unidades. (Debe


ejecutarse con unidades)

script_file Nulo Un archivo de script existente que


se ejecutará en el futuro.

state absent, present (ausente, presente) El estado agrega o elimina un


comando o script.

unique yes, no (sí, no) Si una tarea ya se está ejecutando,


no se ejecutará de nuevo.

units minutes/hours/days/weeks Las denominaciones temporales.


(minutos/horas/días/semanas)

RH294-RHEL8.0-es-1-20200501 415
capítulo 10 | Automatización de tareas de administración de Linux

Anexión de comandos con el módulo cron.


Al configurar una tarea con trabajos programados, se usa el módulo cron. El módulo cron anexará
los comandos directamente al crontab del usuario que designe.

El ejemplo del módulo cron:


- cron:
name: "Flush Bolt"
user: "root"
minute: 45
hour: 11
job: "php ./app/nut cache:clear"

Esta reproducción usa el comando cache:clear de una empresa para limpiar inmediatamente la
memoria caché de Bolt, eliminando los archivos almacenados en caché y la memoria caché de
directories.flushes del servidor de CMS todas las mañanas a las 11:45.

Ansible escribirá la reproducción en crontab con la sintaxis correcta, como lo indicó el usuario.

Al revisar crontab se verificará que se haya adjuntado.

Estos son algunos parámetros de uso común del módulo cron:

Parámetros

Parámetro Opciones Comentarios

special_time reboot, yearly, annually, monthly, Un conjunto de tiempos


weekly, daily, hourly (reinicio, anual, recurrentes.
anual, mensual, semanal, diario, por
hora)

state absent, present (ausente, presente) Si se configura en present, se creará


el comando. Si se configura en
absent, se lo quitará.

cron_file Nulo Si tiene que mantener grandes


bancos de servidores, a veces es
mejor tener un archivo crontab ya
escrito.

backup yes, no (sí, no) Realiza una copia de seguridad del


archivo crontab antes de editarlo.

Administración de servicios con los módulos systemd y


service.S
Para administrar servicios o recargar daemons, Ansible tiene los módulos systemd y service.
El módulo service ofrece un conjunto básico de opciones: iniciar, detener, reiniciar, habilitar. El
módulo systemd ofrece más opciones de configuración. Systemd permite recargar un daemon,
mientras que el módulo service no lo permite.

416 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Ejemplo del módulo service:


- name: start nginx
service:
name: nginx
state: started"

nota
El daemon init se reemplazó por systemd. Por eso, en muchos casos, systemd será
la mejor opción.

Ejemplo del módulo systemd:


- name: reload web server
systemd:
name: apache2
state: reload
daemon-reload: yes

El módulo reboot (reiniciar)


Otro módulo de sistemas Ansible muy usado es reboot. Se considera más seguro que usar el
módulo de shell para iniciar el apagado. Mientras se ejecuta una reproducción, el módulo reboot
apagará el host administrado, luego esperará hasta que vuelva a estar activo antes de continuar
con la reproducción.

Ejemplo del módulo reboot:


- name: "Reboot after patching"
reboot:
reboot_timeout: 180

- name: force a quick reboot


reboot:

Los módulos shell y command (comando)


Al igual que los módulos service y systemd, los módulos shell y command pueden intercambiar
algunas tareas. El módulo command se considera más seguro, pero algunas variables de entorno
no están disponibles. Además, los operadores de flujo no funcionan. Si necesita transmitir sus
comandos, el módulo shell lo hará.

Ejemplo del módulo shell:


- name: Run a templated variable (always use quote filter to avoid injection)
shell: cat {{ myfile|quote }}

Para sanear cualquier variable, se sugiere que use “{{ var | quote }}” en lugar de solo
“{{ var }}”

RH294-RHEL8.0-es-1-20200501 417
capítulo 10 | Automatización de tareas de administración de Linux

Ejemplo del módulo command:


- name: This command only
command: /usr/bin/scrape_logs.py arg1 arg2
args:
chdir: scripts/
creates: /path/to/script

Puede pasar argumentos al formulario para proporcionar las opciones.

nota
El módulo command se considera más seguro porque no se ve afectado por el
entorno de los usuarios.

La recopilación de datos en el host administrado le permitirá acceder a las variables del entorno.
Hay una sublista llamada ansible_env que tiene todas las variables de entorno dentro de ella.

---
- name:
hosts: webservers
vars:
local_shell: "{{ ansible_env }}"
tasks:
- name: Printing all the environment variables in Ansible
debug:
msg: "{{ local_shell }}"

Puede aislar la variable que desea devolver usando el complemento (plug-in) de búsqueda.
msg: "{{ lookup('env', 'USER', 'HOME', 'SHELL') }}"

Referencias
at: Programar la ejecución de un comando o archivo de script mediante el
comando at — Documentación de Ansible
https://docs.ansible.com/ansible/latest/modules/at_module.html

cron: Gestionar las entradas cron.d y crontab — Documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/cron_module.html

reboot: Reiniciar una maquina — Documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/reboot_module.html

service: Ejecutar servicios en una máquina — Documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/service_module.html

418 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Ejercicio Guiado

Administración del proceso de arranque y


procesos programados
En este ejercicio, administrará el proceso de inicio, programará trabajos recurrentes y
reiniciará los hosts administrados.

Resultados
Debe ser capaz de usar una guía para:

• Programar un trabajo de cron.

• Eliminar un solo trabajo específico de cron de un archivo crontab.

• Programar una tarea de at.

• Establecer el destino de arranque predeterminado en los hosts administrados.

• Reiniciar los host administrados.

Andes De Comenzar
Desde workstation, ejecute el script lab system-process start para configurar el
entorno para el ejercicio. El script crea el directorio de trabajo system-process y descarga
el archivo de configuración de Ansible y el archivo de inventario del host necesarios para el
ejercicio.

[student@workstation ~]$ lab system-process start

1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-process.

[student@workstation ~]$ cd ~/system-process


[student@workstation system-process]$

2. Cree la guía create_crontab_file.yml en el directorio de trabajo actual. Configure la


guía para usar el módulo cron para crear el archivo crontab /etc/cron.d/add-date-
time que programa un trabajo cron recurrente. El trabajo debe ejecutarse con el usuario
devops cada dos minutos entre las 09:00 y las 16:59 de lunes a viernes. El trabajo
debe agregar la fecha y hora actuales al archivo /home/devops/my_datetime_cron_job

2.1. Cree una nueva guía, create_crontab_file.yml, y agregue las líneas necesarias
para iniciar la reproducción. Debe apuntar a los hosts administrados del grupo
webservers y habilitar el escalamiento de privilegios.

RH294-RHEL8.0-es-1-20200501 419
capítulo 10 | Automatización de tareas de administración de Linux

---
- name: Recurring cron job
hosts: webservers
become: true

2.2. Defina una tarea que use el módulo cron para programar un trabajo cron recurrente.

nota
El módulo cron proporciona una opción name para describir de forma única la
entrada del archivo crontab y garantizar los resultados esperados. La descripción
se agrega al archivo crontab. Por ejemplo, se requiere la opción name para eliminar
una entrada de crontab usando state=absent. Además, la opción name evita
que se cree siempre una nueva entrada de crontab cuando se configura el estado
predeterminado, state=present.

tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file

2.3. Configure el trabajo para que se ejecute cada dos minutos entre las 09:00 y las
16:59 de lunes a viernes.

minute: "*/2"
hour: 9-16
weekday: 1-5

2.4. Use el parámetro cron_file para utilizar el archivo crontab /etc/cron.d/add-


date-time en lugar del crontab de un usuario individual en /var/spool/cron/.
Una ruta relativa colocará el archivo en el directorio /etc/cron.d. Si se usa el
parámetro cron_file, también debe especificar el parámetro user.

user: devops
job: date >> /home/devops/my_date_time_cron_job
cron_file: add-date-time
state: present

2.5. Cuando se complete, la guía debe verse de la siguiente forma. Revise la guía para
comprobar la precisión.

---
- name: Recurring cron job
hosts: webservers
become: true

tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file

420 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

minute: "*/2"
hour: 9-16
weekday: 1-5
user: devops
job: date >> /home/devops/my_date_time_cron_job
cron_file: add-date-time
state: present

2.6. Ejecute el comando ansible-playbook --syntax-check


create_crontab_file.yml para verificar la sintaxis de la guía. Corrija los errores
antes de pasar al siguiente paso.

[student@workstation system-process]$ ansible-playbook --syntax-check \


> create_crontab_file.yml

playbook: create_crontab_file.yml

2.7. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook create_crontab_file.yml

PLAY [Recurring cron job] *************************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Crontab file exists] ************************************************


changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

2.8. Ejecute un comando ad hoc para verificar que el archivo cron /etc/cron.d/add-
date-time existe y su contenido es correcto.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "cat /etc/cron.d/add-date-time"
servera.lab.example.com | CHANGED | rc=0 >>
#Ansible: Add date and time to a file
*/2 9-16 * * 1-5 devops date >> /home/devops/my_date_time_cron_job

3. Cree la guía remove_cron_job.yml en el directorio de trabajo actual. Configure la guía


para usar el módulo cron para eliminar el trabajo cron Add date and time to a file
del archivo crontab /etc/cron.d/add-date-time.

3.1. Cree una guía nueva remove_cron_job.yml y agregue las siguientes líneas:

---
- name: Remove scheduled cron job
hosts: webservers
become: true

RH294-RHEL8.0-es-1-20200501 421
capítulo 10 | Automatización de tareas de administración de Linux

tasks:
- name: Cron job removed
cron:
name: Add date and time to a file
user: devops
cron_file: add-date-time
state: absent

3.2. Ejecute el comando ansible-playbook --syntax-check


remove_cron_job.yml para verificar la sintaxis de la guía. Corrija los errores antes
de pasar al siguiente paso.

[student@workstation system-process]$ ansible-playbook --syntax-check \


> remove_cron_job.yml

playbook: remove_cron_job.yml

3.3. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook remove_cron_job.yml

PLAY [Remove scheduled cron job] ******************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Cron job removed] ***************************************************


changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

3.4. Ejecute un comando ad hoc para verificar que el archivo cron /etc/cron.d/add-
date-time siga existiendo, pero que el trabajo cron se haya eliminado.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "cat /etc/cron.d/add-date-time"
servera.lab.example.com | CHANGED | rc=0 >>

4. Cree la guía schedule_at_task.yml en el directorio de trabajo actual. Configure la guía


para usar el módulo at para programar una tarea que se ejecute un minuto en el futuro.
La tarea debe ejecutar el comando date y redirigir la salida al archivo /home/devops/
my_at_date_time. Use la opción unique: yes para asegurarse de que si el comando ya
existe en la cola at, no se agregue una nueva tarea.

4.1. Cree una guía nueva schedule_at_task.yml y agregue las siguientes líneas:

---
- name: Schedule at task
hosts: webservers
become: true
become_user: devops

422 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

tasks:
- name: Create date and time file
at:
command: "date > ~/my_at_date_time\n"
count: 1
units: minutes
unique: yes
state: present

4.2. Ejecute el comando ansible-playbook -syntax-check


schedule_at_task.yml para verificar la sintaxis de la guía. Corrija los errores
antes de pasar al siguiente paso.

[student@workstation system-process]$ ansible-playbook --syntax-check \


> schedule_at_task.yml

playbook: schedule_at_task.yml

4.3. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook schedule_at_task.yml

PLAY [Schedule at task] ***************************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Create date and time file] ******************************************


changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

4.4. Después de esperar un minuto hasta que se complete el comando at, ejecute
comandos ad hoc para verificar que el archivo /home/devops/my_at_date_time
existe y tiene el contenido correcto.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "ls -l my_at_date_time"
servera.lab.example.com | CHANGED | rc=0 >>
-rw-rw-r--. 1 devops devops 30 abr 17 06:15 my_at_date_time

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "cat my_at_date_time"
servera.lab.example.com | CHANGED | rc=0 >>
mié abr 17 06:15:00 EDT 2019

5. Cree la guía set_default_boot_target_graphical.yml en el directorio de trabajo


actual. Configure la guía para usar el módulo file para cambiar el vínculo simbólico de
los hosts administrados para que hagan referencia al destino de arranque graphical-
target.

RH294-RHEL8.0-es-1-20200501 423
capítulo 10 | Automatización de tareas de administración de Linux

nota
En el siguiente módulo file, el vínculo simbólico hace referencia al valor del
parámetro src. El valor del parámetro dest es el vínculo simbólico.

5.1. Cree una guía nueva set_default_boot_target_graphical.yml y agregue las


siguientes líneas:

---
- name: Change default boot target
hosts: webservers
become: true

tasks:
- name: Default boot target is graphical
file:
src: /usr/lib/systemd/system/graphical.target
dest: /etc/systemd/system/default.target
state: link

5.2. Ejecute el comando ansible-playbook --syntax-check


set_default_boot_target_graphical.yml para verificar la sintaxis de la guía.
Corrija los errores antes de pasar al siguiente paso.

[student@workstation system-process]$ ansible-playbook --syntax-check \


> set_default_boot_target_graphical.yml

playbook: set_default_boot_target_graphical.yml

5.3. Antes de ejecutar la guía, ejecute un comando ad hoc para verificar que el destino de
arranque predeterminado actual sea multi-user.target:

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
multi-user.target

5.4. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook \


> set_default_boot_target_graphical.yml

PLAY [Change default boot target] *****************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Default boot target is graphical] ***********************************


changed: [servera.lab.example.com]

424 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

5.5. Ejecute un comando ad hoc para verificar que el destino de arranque predeterminado
ahora sea graphical.target.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
graphical.target

6. Cree la guía reboot_hosts.yml en el directorio de trabajo actual que reinicia los


hosts administrados. No es necesario reiniciar un servidor después de cambiar el destino
predeterminado. Sin embargo, puede resultar útil saber cómo crear una guía que reinicie los
hosts administrados.

6.1. Cree una guía nueva reboot_hosts.yml y agregue las siguientes líneas:

---
- name: Reboot hosts
hosts: webservers
become: true

tasks:
- name: Hosts are rebooted
reboot:

6.2. Ejecute el comando ansible-playbook --syntax-check reboot_hosts.yml


para verificar la sintaxis de la guía. Corrija los errores antes de pasar al siguiente paso.

[student@workstation system-process]$ ansible-playbook --syntax-check \


> reboot_hosts.yml

playbook: reboot_hosts.yml

6.3. Antes de ejecutar la guía, ejecute un comando ad hoc para determinar el sello de hora
del último reinicio del sistema.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "who -b"
servera.lab.example.com | CHANGED | rc=0 >>
system boot 2019-04-12 06:01

6.4. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook reboot_hosts.yml

PLAY [Reboot hosts] *******************************************************

TASK [Gathering Facts] ****************************************************

RH294-RHEL8.0-es-1-20200501 425
capítulo 10 | Automatización de tareas de administración de Linux

ok: [servera.lab.example.com]

TASK [Hosts are rebooted] *************************************************


changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

6.5. Ejecute un comando ad hoc para determinar el sello de hora del último reinicio del
sistema. El sello de hora que se muestra después de que se ejecuta la guía debe ser
posterior.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "who -b"
servera.lab.example.com | CHANGED | rc=0 >>
system boot 2019-04-12 06:20

6.6. Ejecute un segundo comando ad hoc para determinar que el destino de arranque
graphical.target haya sobrevivido al reinicio.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
graphical.target

7. Para mantener la coherencia a lo largo de los ejercicios restantes, revierta el destino


de arranque predeterminado a la configuración anterior, multi-user.target. Cree
la guía set_default_boot_target_multi-user.yml en el directorio de trabajo
actual. Configure la guía para usar el módulo file a fin de cambiar el vínculo simbólico
de los hosts administrados para que hagan referencia al destino de arranque multi-
user.target.

7.1. Cree una guía nueva set_default_boot_target_multi-user.yml y agregue


las siguientes líneas:

---
- name: Change default runlevel target
hosts: webservers
become: true

tasks:
- name: Default runlevel is multi-user target
file:
src: /usr/lib/systemd/system/multi-user.target
dest: /etc/systemd/system/default.target
state: link

7.2. Ejecute el comando ansible-playbook --syntax-check


set_default_boot_target_multi-user.yml para verificar la sintaxis de la
guía. Corrija los errores antes de pasar al siguiente paso.

426 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-process]$ ansible-playbook --syntax-check \


> set_default_boot_target_multi-user.yml

playbook: set_default_boot_target_multi-user.yml

7.3. Ejecute la guía.

[student@workstation system-process]$ ansible-playbook \


> set_default_boot_target_multi-user.yml

PLAY [Change default runlevel target] *************************************

TASK [Gathering Facts] ****************************************************


ok: [servera.lab.example.com]

TASK [Default runlevel is multi-user target] ******************************


changed: [servera.lab.example.com]

PLAY RECAP ****************************************************************


servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

7.4. Ejecute un comando ad hoc para verificar que el destino de arranque predeterminado
ahora sea multi-user.target.

[student@workstation system-process]$ ansible webservers -u devops -b \


> -a "systemctl get-default"
servera.lab.example.com | CHANGED | rc=0 >>
multi-user.target

Finalizar
En workstation, ejecute el script lab system-process finish para limpiar este ejercicio.

[student@workstation ~]$ lab system-process finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 427
capítulo 10 | Automatización de tareas de administración de Linux

Administración del almacenamiento

Objetivos
Tras finalizar esta sección, deberá poder particionar los dispositivos de almacenamiento,
configurar LVM, formatear particiones o volúmenes lógicos, montar sistemas de archivos, y
agregar espacios o archivos de intercambio.

Configuración del almacenamiento con módulos de


Ansible
Red Hat Ansible Engine proporciona una colección de módulos para configurar dispositivos de
almacenamiento en hosts administrados. Esos módulos admiten la partición de dispositivos, la
creación de volúmenes lógicos, y la creación y el montaje de sistemas de archivos.

El módulo parted (particionado)


El módulo parted admite la partición de dispositivos de bloque. Este módulo incluye la
funcionalidad del comando parted, y permite crear particiones con un tamaño, un indicador y
una alineación específicos. La tabla siguiente enumera algunos de los parámetros para el módulo
parted.

Nombre del Descripción


parámetro

align Configura la alineación de particiones.

device Dispositivo de bloque.

flags Indicadores para la partición.

number El número de partición.

part_end Tamaño de partición desde el principio del disco especificado en


unidades admitidas parted.

state Crea o elimina la partición.

unit Unidades de tamaño para la información de partición.

En el siguiente ejemplo, se crea una nueva partición de 10 GB.

- name: New 10GB partition


parted:
device: /dev/vdb
number: 1
state: present
part_end: 10GB

Usa vdb como dispositivo de bloque para particionar.

428 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Crea la partición número uno.


Garantiza que la partición esté disponible.
Establece el tamaño de la partición en 10 GB.

Los módulos lvg y lvol


Los módulos lvg y lvol admiten la creación de volúmenes lógicos, incluida la configuración de
volúmenes físicos y grupos de volúmenes. lvg toma como parámetros los dispositivos de bloque
para configurar como los volúmenes físicos de backend para el grupo de volúmenes. La tabla
siguiente enumera algunos de los parámetros para el módulo lvg.

Nombre del Descripción


parámetro

pesize El tamaño de la extensión física. Debe ser una potencia de 2 o múltiplo


de 128 KiB.

pvs Lista de dispositivos separados por coma que se configurarán como


volúmenes físicos para el grupo de volúmenes.

vg El nombre del grupo de volúmenes.

state Crea o elimina el volumen.

La siguiente tarea crea un grupo de volúmenes con un tamaño de extensión física específico
usando un dispositivo de bloque como backend.

- name: Creates a volume group


lvg:
vg: vg1
pvs: /dev/vda1
pesize: 32

El nombre del grupo de volúmenes es vg1.


Usa /dev/vda1 como el volumen físico de backend para el grupo de volúmenes.
Establece el tamaño de la extensión física en 32.
En el siguiente ejemplo, si el grupo de volúmenes vg1 ya está disponible con /dev/vdb1 como
volumen físico, el volumen se agranda agregando un nuevo volumen físico con /dev/vdc1.

- name: Resize a volume group


lvg:
vg: vg1
pvs: /dev/vdb1,/dev/vdc1

El módulo lvol crea volúmenes lógicos, y admite el cambio de tamaño y la reducción de esos
volúmenes, y de los sistemas de archivos que están encima de ellos. Este módulo también admite
la creación de instantáneas para los volúmenes lógicos. La tabla siguiente enumera algunos de los
parámetros para el módulo lvol.

Nombre del Descripción


parámetro

lv El nombre del volumen lógico.

RH294-RHEL8.0-es-1-20200501 429
capítulo 10 | Automatización de tareas de administración de Linux

Nombre del Descripción


parámetro

resizefs Redimensiona el sistema de archivos con el volumen lógico.

shrink Habilita la reducción de volúmenes lógicos.

size El tamaño del volumen lógico.

snapshot El nombre de la instantánea del volumen lógico.

state Crea o elimina el volumen lógico.

vg El grupo de volúmenes principal para el volumen lógico.

La siguiente tarea crea un volumen lógico de 2 GB.

- name: Create a logical volume of 2GB


lvol:
vg: vg1
lv: lv1
size: 2g

El nombre del grupo de volúmenes principal es vg1.


El nombre del volumen lógico es lv1.
El tamaño del volumen lógico es 2 GB.

El módulo filesystem (sistema de archivos)


El módulo filesystem admite tanto la creación como el redimensionamiento de un sistema de
archivos. Este módulo admite el redimensionamiento del sistema de archivos para ext2, ext3,
ext4, ext4dev, f2fs, lvm, xfs y vfat. La tabla siguiente enumera algunos de los parámetros
para el módulo filesystem.

Nombre del Descripción


parámetro

dev Nombre del dispositivo de bloque.

fstype Tipo de sistema de archivos.

resizefs Aumenta el tamaño del sistema de archivos al tamaño del dispositivo


de bloque.

En el siguiente ejemplo, se crea un sistema de archivos en una partición.

- name: Create an XFS filesystem


filesystem:
fstype: xfs
dev: /dev/vdb1

Usa el sistema de archivos XFS.


Usa el dispositivo /dev/vdb1.

430 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

El módulo mount (montar)


El módulo mount admite la configuración de puntos de montaje en /etc/fstab. La tabla
siguiente enumera algunos de los parámetros para el módulo mount.

Nombre del Descripción


parámetro

fstype Tipo de sistema de archivos.

opts Opciones de montaje.

path Ruta del punto de montaje.

src Dispositivo que se montará.

state Especifica el estado de montaje. Si se establece en mounted, el


sistema monta el dispositivo y configura /etc/fstab con esa
información de montaje. Para desmontar el dispositivo y quitarlo de /
etc/fstab, use absent.

En el siguiente ejemplo, se monta un dispositivo con un ID específico.

- name: Mount device with ID


mount:
path: /data
src: UUID=a8063676-44dd-409a-b584-68be2c9f5570
fstype: xfs
state: present

Usa /data como la ruta del punto de montaje.


Se monta el dispositivo con el ID a8063676-44dd-409a-b584-68be2c9f5570.
Usa el sistema de archivos XFS.
Monta el dispositivo y configura /etc/fstab en consecuencia.
El siguiente ejemplo monta el recurso compartido de NFS disponible en 172.25.250.100:/
share en el directorio /nfsshare del host administrado.

- name: Mount NFS share


mount: name=/nfsshare src=172.25.250.100:/share fstype=nfs
opts=defaults,nobootwait dump=0 passno=2 state=mounted

Configuración de intercambio con módulos


En la actualidad, Red Hat Ansible Engine no incluye módulos para administrar la memoria de
intercambio. Para agregar memoria de intercambio a un sistema con Ansible con volúmenes
lógicos, debe crear un grupo de volúmenes y un volumen lógico nuevos con los módulos lvg
y lvol. Cuando esté listo, debe formatear como intercambio el nuevo volumen lógico con
el módulo command y el comando mkswap. Por último, debe activar el nuevo dispositivo de
intercambio con el módulo command y el comando swapon. Red Hat Ansible Engine incluye la
variable ansible_swaptotal_mb que incluye la memoria total de intercambio. Puede usar esta
variable para desencadenar la configuración de intercambio y la habilitación cuando la memoria de
intercambio es baja. Las siguientes tareas, crear un grupo de volúmenes y un volumen lógico para
la memoria de intercambio, formatean ese volumen lógico como intercambio y lo activan.

RH294-RHEL8.0-es-1-20200501 431
capítulo 10 | Automatización de tareas de administración de Linux

- name: Create new swap VG


lvg: vg=vgswap pvs=/dev/vda1 state=present

- name: Create new swap LV


lvol: vg=vgswap lv=lvswap size=10g

- name: Format swap LV


command: mkswap /dev/vgswap/lvswap
when: ansible_swaptotal_mb < 128

- name: Activate swap LV


command: swapon /dev/vgswap/lvswap
when: ansible_swaptotal_mb < 128

Datos de Ansible para la configuración de


almacenamiento
Ansible usa datos para recuperar información del nodo de control sobre la configuración de los
hosts administrados. Puede usar el módulo de Ansible setup (configuración) para recuperar
todos los datos de Ansible para un host administrado.

[user@controlnode ~]$ ansible webservers -m setup


host.lab.example.com | SUCCESS => {
"ansible_facts": {
...output omitted...
}

La opción filter (filtrar) para el módulo setup admite filtrado detallado basado en comodines
de tipo shell.

El elemento ansible_devices incluye todos los dispositivos de almacenamiento disponibles en


el host administrado. El elemento para cada dispositivo de almacenamiento incluye información
adicional como particiones o tamaño total. En el siguiente ejemplo, se muestra el elemento
ansible_devices para un host administrado con tres dispositivos de almacenamiento: sr0, vda
y vdb.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_devices'


host.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_devices": {
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371SB PIIX3 IDE
[Natoma/Triton II]",
"links": {
"ids": [
"ata-QEMU_DVD-ROM_QM00003"
],
"labels": [],
"masters": [],
"uuids": []
},
"model": "QEMU DVD-ROM",

432 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

"partitions": {},
"removable": "1",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "2097151",
"sectorsize": "512",
"size": "1024.00 MB",
"support_discard": "0",
"vendor": "QEMU",
"virtual": 1
},
"vda": {
"holders": [],
"host": "SCSI storage controller: Red Hat, Inc. Virtio block
device",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {
"vda1": {
"holders": [],
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": [
"a8063676-44dd-409a-b584-68be2c9f5570"
]
},
"sectors": "20969439",
"sectorsize": 512,
"size": "10.00 GB",
"start": "2048",
"uuid": "a8063676-44dd-409a-b584-68be2c9f5570"
}
},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "20971520",
"sectorsize": "512",
"size": "10.00 GB",
"support_discard": "0",
"vendor": "0x1af4",
"virtual": 1
},
"vdb": {

RH294-RHEL8.0-es-1-20200501 433
capítulo 10 | Automatización de tareas de administración de Linux

"holders": [],
"host": "SCSI storage controller: Red Hat, Inc. Virtio block
device",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "10485760",
"sectorsize": "512",
"size": "5.00 GB",
"support_discard": "0",
"vendor": "0x1af4",
"virtual": 1
}
}
},
"changed": false
}

El elemento ansible_device_links incluye todos los vínculos disponibles para


cada dispositivo de almacenamiento. En el siguiente ejemplo, se muestra el elemento
ansible_device_links para un host administrado con dos dispositivos de almacenamiento,
sr0 y vda1, que tienen un ID asociado.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_device_links'


host.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_device_links": {
"ids": {
"sr0": [
"ata-QEMU_DVD-ROM_QM00003"
]
},
"labels": {},
"masters": {},
"uuids": {
"vda1": [
"a8063676-44dd-409a-b584-68be2c9f5570"
]
}
}
},
"changed": false
}

434 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

El elemento ansible_mounts incluye información sobre los dispositivos montados actualmente


en el host administrado, como el dispositivo montado, el punto de montaje y las opciones. En la
siguiente salida, se muestra el elemento ansible_mounts para un host administrado con un
montaje activo, /dev/vda1 en el directorio /.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_mounts'


host.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_mounts": [
{
"block_available": 2225732,
"block_size": 4096,
"block_total": 2618619,
"block_used": 392887,
"device": "/dev/vda1",
"fstype": "xfs",
"inode_available": 5196602,
"inode_total": 5242304,
"inode_used": 45702,
"mount": "/",
"options": "rw,seclabel,relatime,attr2,inode64,noquota",
"size_available": 9116598272,
"size_total": 10725863424,
"uuid": "a8063676-44dd-409a-b584-68be2c9f5570"
}
]
},
"changed": false
}

Referencias
parted: Configurar particiones de dispositivo de bloque; documentación de
Ansible
https://docs.ansible.com/ansible/latest/modules/parted_module.html

lvg: Configurar grupos de volúmenes LVM; documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/lvg_module.html

lvol: Configurar volúmenes lógicos LVM; documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/lvol_module.html

filesystem: Crear un sistema de archivos; documentación de Ansible


https://docs.ansible.com/ansible/latest/modules/filesystem_module.html

mount: Controlar puntos de montaje activos y configurados; documentación


de Ansible
https://docs.ansible.com/ansible/latest/modules/mount_module.html

RH294-RHEL8.0-es-1-20200501 435
capítulo 10 | Automatización de tareas de administración de Linux

Ejercicio Guiado

Administración del almacenamiento


En este ejercicio, particionará un nuevo disco, creará volúmenes lógicos y los formateará con
sistemas de archivos XFS, y los montará de forma inmediata y automática en el momento del
arranque en sus hosts administrados.

Resultados
Deberá poder realizar lo siguiente:

• Usar el módulo parted para configurar particiones de dispositivos de bloque

• Usar el módulo lvg para gestionar volúmenes de LVM

• Usar el módulo lvol para gestionar volúmenes lógicos de LVM

• Usar el módulo filesystem para crear sistemas de archivos

• Usar el módulo mount para controlar y configurar puntos de montaje en /etc/fstab

Andes De Comenzar
Desde workstation, ejecute el script lab system-storage start para configurar
el entorno para el ejercicio. El script crea el directorio del proyecto system-storage y
descarga el archivo de configuración Ansible y el archivo del inventario del host necesarios
para el ejercicio.

[student@workstation ~]$ lab system-storage start

Descripción general de la situación


Usted es responsable de administrar un conjunto de servidores web. Una práctica recomendada
para la configuración de servidores web es almacenar los datos del servidor web en una partición
separada o un volumen lógico.

Escribirá una guía para lo siguiente:

• Administrar particiones del dispositivo /dev/vdb

• Administrar un grupo de volúmenes llamado apache-vg para datos del servidor web

• Crear dos volúmenes lógicos denominados content-lv y logs-lv, ambos respaldados por el
grupo de volumen apache-vg

• Crear un sistema de archivos XFS en ambos volúmenes lógicos

• Montar el volumen lógico content-lv en /var/www

• Montar el volumen lógico logs-lv en /var/log/httpd

Si los requisitos de almacenamiento para el servidor web cambian, actualice las variables
correspondientes de la guía y vuelva a ejecutarla. La guía debe ser idempotente.

436 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-storage.

[student@workstation ~]$ cd ~/system-storage


[student@workstation system-storage]$

2. Revise el archivo de guía de esqueleto storage.yml y el archivo de variables asociadas


storage_vars.yml en el directorio del proyecto. Ejecute la guía.

2.1. Revise la guía storage.yml.

---
- name: Ensure Apache Storage Configuration
hosts: webservers
vars_files:
- storage_vars.yml
tasks:
- name: Correct partitions exist on /dev/vdb
debug:
msg: TODO
loop: "{{ partitions }}"

- name: Ensure Volume Groups Exist


debug:
msg: TODO
loop: "{{ volume_groups }}"

- name: Create each Logical Volume (LV) if needed


debug:
msg: TODO
loop: "{{ logical_volumes }}"
when: true

- name: Ensure XFS Filesystem exists on each LV


debug:
msg: TODO
loop: "{{ logical_volumes }}"

- name: Ensure the correct capacity for each LV


debug:
msg: TODO
loop: "{{ logical_volumes }}"

- name: Each Logical Volume is mounted


debug:
msg: TODO
loop: "{{ logical_volumes }}"

El nombre de cada tarea actúa como un resumen del procedimiento que se pretende
implementar. En pasos posteriores, actualizará y cambiará estas seis tareas.

2.2. Revise el archivo de variables storage_vars.yml.

RH294-RHEL8.0-es-1-20200501 437
capítulo 10 | Automatización de tareas de administración de Linux

---

partitions:
- number: 1
start: 1MiB
end: 257MiB

volume_groups:
- name: apache-vg
devices: /dev/vdb1

logical_volumes:
- name: content-lv
size: 64M
vgroup: apache-vg
mount_path: /var/www

- name: logs-lv
size: 128M
vgroup: apache-vg
mount_path: /var/log/httpd

En este archivo se describe la estructura prevista de particiones, grupos de


volúmenes y volúmenes lógicos en cada servidor web. La primera partición comienza
en un desplazamiento de 1 MiB desde el principio del dispositivo /dev/vdb y termina
en un desplazamiento de 257 MiB, lo que resulta en un tamaño total de 256 MiB.
Cada servidor web tiene un grupo de volúmenes, llamado apache-vg, que contiene
la primera partición del dispositivo /dev/vdb.
Cada servidor web tiene dos volúmenes lógicos. El primer volumen lógico se llama
content-lv, con un tamaño de 64 MiB, está adjuntado al grupo de volumen
apache-vg y montado en /var/www. El segundo volumen lógico se llama
content-lv, con un tamaño de 128 MiB, está adjuntado al grupo de volumen
apache-vg y montado en /var/log/httpd.

nota
El grupo de volumen apache-vg tiene una capacidad de 256 MiB, porque está
respaldado por la partición /dev/vdb1. Proporciona suficiente capacidad para
ambos volúmenes lógicos.

2.3. Ejecute la guía storage.yml.

[student@workstation system-storage]$ ansible-playbook storage.yml

PLAY [Ensure Apache Storage Configuration] ***********************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Correct partitions exist on /dev/vdb] **********************************


ok: [servera.lab.example.com] => (item={u'start': u'1MiB', u'end': u'257MiB',
u'number': 1}) => {

438 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

"msg": "TODO"
}

...output omitted...

TASK [Each Logical Volume is mounted] ****************************************


ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'64M',
u'mount_path': u'/var/www', u'name': u'content-lv'}) => {
"msg": "TODO"
}
ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M',
u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'}) => {
"msg": "TODO"
}

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=7 changed=0 unreachable=0 failed=0

3. Cambie la primera tarea para usar el módulo parted para configurar una partición para
cada elemento de bucle. Cada elemento describe una partición deseada del dispositivo /
dev/vdb en cada servidor web:

number
El número de partición. Use esto como el valor de la palabra clave number para el
módulo parted.

start
El inicio de la partición, como un desplazamiento desde el principio del dispositivo
de bloque. Use esto como el valor de la palabra clave part_start para el módulo
parted.

end
El fin de la partición, como un desplazamiento desde el principio del dispositivo de
bloque. Use esto como el valor de la palabra clave part_end para el módulo parted.

El contenido de la primera tarea debe ser el siguiente:

- name: Correct partitions exist on /dev/vdb


parted:
device: /dev/vdb
state: present
number: "{{ item.number }}"
part_start: "{{ item.start }}"
part_end: "{{ item.end }}"
loop: "{{ partitions }}"

RH294-RHEL8.0-es-1-20200501 439
capítulo 10 | Automatización de tareas de administración de Linux

4. Cambie la segunda tarea de la guía para usar el módulo lvg para configurar un grupo de
volúmenes para cada elemento de bucle. Cada elemento de la variable volume_groups
describe un grupo de volúmenes que debería existir en cada servidor web:

name
El nombre del grupo de volúmenes. Use esto como el valor de la palabra clave vg para
el módulo lvg.

devices
Lista de dispositivos o particiones separados por coma que forman el grupo de
volúmenes. Use esto como el valor de la palabra clave pvs para el módulo lvg.

El contenido de la segunda tarea debe ser el siguiente:

- name: Ensure Volume Groups Exist


lvg:
vg: "{{ item.name }}"
pvs: "{{ item.devices }}"
loop: "{{ volume_groups }}"

5. Cambie la tercera tarea de la guía para usar el módulo lvol para crear un volumen lógico
para cada elemento. Utilice las palabras clave del elemento para crear el nuevo volumen
lógico:

name
El nombre del volumen lógico. Use esto como el valor de la palabra clave lv para el
módulo lvol.

vgroup
El nombre del grupo de volúmenes que proporciona almacenamiento para el volumen
lógico.

size
El tamaño del volumen lógico. El valor de esta palabra clave es cualquier valor
aceptable para la opción -L del comando lvcreate.

Solo ejecute la tarea si todavía no existe un volumen lógico. Actualice la afirmación when
para comprobar que no existe un volumen lógico con un nombre que coincida con el valor
de la palabra clave name del elemento.

5.1. Cambie la tercera tarea para usar el módulo lvol. Configure el nombre del grupo de
volúmenes, el nombre del volumen lógico y el tamaño del volumen lógico utilizando
las palabras clave de cada elemento. El contenido de la tercera tarea ahora es el
siguiente:

- name: Create each Logical Volume (LV) if needed


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"
when: true

440 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

5.2. El dato Ansible ansible_lvm contiene información sobre los objetos de Logical
Volume Management en cada host. Utilice un comando ad hoc para ver el conjunto
actual de volúmenes lógicos en el host remoto:

[student@workstation system-storage]$ ansible all -m setup -a \


> "filter=ansible_lvm"
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_lvm": {
"lvs": {},
"pvs": {},
"vgs": {}
},
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false
}

El valor de la palabra clave lvs indica que no hay volúmenes lógicos en el host
remoto.

5.3. Ejecute la guía para crear los volúmenes lógicos en el host remoto.

[student@workstation system-storage]$ ansible-playbook storage.yml

PLAY [Ensure Apache Storage Configuration] ***********************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Correct partitions exist on /dev/vdb] **********************************


changed: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure Volume Groups Exist] ********************************************


changed: [servera.lab.example.com] => (item={...output omitted...})

TASK [Create each Logical Volume (LV) if needed] *****************************


changed: [servera.lab.example.com] => (item={...output omitted...})
changed: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure XFS Filesystem exists on each LV] *******************************


ok: [servera.lab.example.com] => (item={...output omitted...}) => {
"msg": "TODO"
}
...output omitted...
PLAY RECAP *******************************************************************
servera.lab.example.com : ok=7 changed=3 unreachable=0 failed=0

5.4. Ejecute otro comando ad hoc para ver la estructura de la variable ansible_lvm
cuando existen volúmenes lógicos en el host remoto.

[student@workstation system-storage]$ ansible all -m setup -a \


> "filter=ansible_lvm"
servera.lab.example.com | SUCCESS => {

RH294-RHEL8.0-es-1-20200501 441
capítulo 10 | Automatización de tareas de administración de Linux

"ansible_facts": {
"ansible_lvm": {
"lvs": {
"content-lv": {
"size_g": "0.06",
"vg": "apache-vg"
},
"logs-lv": {
"size_g": "0.12",
"vg": "apache-vg"
}
},
"pvs": {
"/dev/vdb1": {
"free_g": "0.06",
"size_g": "0.25",
"vg": "apache-vg"
}
},
"vgs": {
"apache-vg": {
"free_g": "0.06",
"num_lvs": "2",
"num_pvs": "1",
"size_g": "0.25"
}
}
}
},
"changed": false
}

El valor de la palabra clave lvs es una estructura de datos de par de valor clave.
Las claves de esta estructura son los nombres de cualquier volumen lógico en
el host. Esto indica que existen tanto el volumen lógico content-lv como
logs-lv. Para cada volumen lógico, la palabra clave vg proporciona el grupo de
volúmenes correspondiente.
La palabra clave pvs contiene información sobre volúmenes físicos en el host.
La información indica que la partición /dev/vdb1 pertenece al grupo de
volúmenes apache-vg.
La palabra clave vgs contiene información sobre grupos de volúmenes en el
host.

5.5. Actualice la afirmación when para comprobar que no existe un volumen lógico con un
nombre que coincida con el valor de la palabra clave name del elemento. El contenido
de la tercera tarea ahora es el siguiente:

- name: Create each Logical Volume (LV) if needed


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"
when: item.name not in ansible_lvm["lvs"]

442 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

6. Cambie la cuarta tarea para usar el módulo filesystem. Configure la tarea para
asegurarse de que cada volumen lógico esté formateado como un sistema de archivos XFS.
Recuerde que un volumen lógico está asociado con el dispositivo lógico /dev/<volume
group name>/<logical volume name> .
El contenido de la cuarta tarea debe ser el siguiente:

- name: Ensure XFS Filesystem exists on each LV


filesystem:
dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
loop: "{{ logical_volumes }}"

7. Configure la quinta tarea para asegurarse de que cada volumen lógico tenga la capacidad
de almacenamiento correcta. Si el volumen lógico aumenta en capacidad, asegúrese de
forzar la expansión del sistema de archivos del volumen.

Advertencia
Si un volumen lógico necesita disminuir su capacidad, esta tarea fallará porque un
sistema de archivos XFS no admite la reducción de la capacidad.

El contenido de la quinta tarea debe ser el siguiente:

- name: Ensure the correct capacity for each LV


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
resizefs: yes
force: yes
loop: "{{ logical_volumes }}"

8. Use el módulo mount en la sexta tarea para garantizar que cada volumen lógico se monte
en la ruta de montaje correspondiente y persista después de un reinicio.
El contenido de la sexta tarea debe ser el siguiente:

- name: Each Logical Volume is mounted


mount:
path: "{{ item.mount_path }}"
src: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
opts: noatime
state: mounted
loop: "{{ logical_volumes }}"

9. Revise la guía storage.yml completada. Ejecute la guía y verifique que cada volumen
lógico esté montado.

9.1. Revise la guía:

RH294-RHEL8.0-es-1-20200501 443
capítulo 10 | Automatización de tareas de administración de Linux

---
- name: Ensure Apache Storage Configuration
hosts: webservers
vars_files:
- storage_vars.yml
tasks:
- name: Correct partitions exist on /dev/vdb
parted:
device: /dev/vdb
state: present
number: "{{ item.number }}"
part_start: "{{ item.start }}"
part_end: "{{ item.end }}"
loop: "{{ partitions }}"

- name: Ensure Volume Groups Exist


lvg:
vg: "{{ item.name }}"
pvs: "{{ item.devices }}"
loop: "{{ volume_groups }}"

- name: Create each Logical Volume (LV) if needed


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"
when: item.name not in ansible_lvm["lvs"]

- name: Ensure XFS Filesystem exists on each LV


filesystem:
dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
loop: "{{ logical_volumes }}"

- name: Ensure the correct capacity for each LV


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
resizefs: yes
force: yes
loop: "{{ logical_volumes }}"

- name: Each Logical Volume is mounted


mount:
path: "{{ item.mount_path }}"
src: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
opts: noatime
state: mounted
loop: "{{ logical_volumes }}"

444 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

9.2. Ejecute la guía.

[student@workstation system-storage]$ ansible-playbook storage.yml

PLAY [Ensure Apache Storage Configuration] ***********************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Correct partitions exist on /dev/vdb] **********************************


ok: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure Volume Groups Exist] ********************************************


ok: [servera.lab.example.com] => (item={...output omitted...})
...output omitted...

TASK [Create each Logical Volume (LV) if needed] *****************************


skipping: [servera.lab.example.com] => (item={...output omitted...})
skipping: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure XFS Filesystem exists on each LV] *******************************


changed: [servera.lab.example.com] => (item={...output omitted...})
changed: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure the correct capacity for each LV] *******************************


ok: [servera.lab.example.com] => (item={...output omitted...})
ok: [servera.lab.example.com] => (item={...output omitted...})

TASK [Each Logical Volume is mounted] ****************************************


changed: [servera.lab.example.com] => (item={...output omitted...})
changed: [servera.lab.example.com] => (item={...output omitted...})

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=2 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

Una tarea se omite durante la ejecución porque la guía se ejecutó previamente con
los mismos valores de variable. No necesitaban crearse los volúmenes.

9.3. Use un comando ad hoc Ansible para ejecutar el comando lsblk en el host remoto.
La salida indica los puntos de montaje de los volúmenes lógicos.

[student@workstation system-storage]$ ansible all -a lsblk


servera.lab.example.com | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 10G 0 disk
└─vda1 252:1 0 10G 0 part /
vdb 252:16 0 1G 0 disk
└─vdb1 252:17 0 256M 0 part
├─apache--vg-content--lv 253:0 0 64M 0 lvm /var/www
└─apache--vg-logs--lv 253:1 0 128M 0 lvm /var/log/httpd

RH294-RHEL8.0-es-1-20200501 445
capítulo 10 | Automatización de tareas de administración de Linux

10. Aumente la capacidad del volumen lógico content-lv a 128 MiB y del volumen lógico
logs-lv a 256 MiB. Esto requiere aumentar la capacidad del grupo de volúmenes
apache-vg.
Cree una nueva partición con una capacidad de 256 MiB y agréguela al grupo de
volúmenes apache-vg.

10.1. Edite el definición de la variable partitions en el archivo storage_vars.yml


para agregar una segunda partición al dispositivo /dev/vdb. El contenido de la
variable partitions debe ser el siguiente:

partitions:
- number: 1
start: 1MiB
end: 257MiB
- number: 2
start: 257MiB
end: 513MiB

10.2. Edite la definición de la variable volume_groups en el archivo storage_vars.yml.


Agregue la segunda partición a la lista de dispositivos que respaldan el grupo de
volúmenes. El contenido de la variable volume_groups debe ser el siguiente:

volume_groups:
- name: apache-vg
devices: /dev/vdb1,/dev/vdb2

10.3. Doble la capacidad de cada volumen lógico definido en el archivo


storage_vars.yml. El contenido de la variable logical_volumes debe ser el
siguiente:

logical_volumes:
- name: content-lv
size: 128M
vgroup: apache-vg
mount_path: /var/www

- name: logs-lv
size: 256M
vgroup: apache-vg
mount_path: /var/log/httpd

10.4. Ejecute la guía. Verifique la nueva capacidad de cada volumen lógico.

[student@workstation system-storage]$ ansible-playbook storage.yml

PLAY [Ensure Apache Storage Configuration] ***********************************

TASK [Gathering Facts] *******************************************************


ok: [servera.lab.example.com]

TASK [Correct partitions exist on /dev/vdb] **********************************


ok: [servera.lab.example.com] => (item={...output omitted...})

446 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

changed: [servera.lab.example.com] => (item={u'start': u'257MiB', u'end':


u'513MiB', u'number': 2})

TASK [Ensure Volume Groups Exist] ********************************************


changed: [servera.lab.example.com] => (item={u'name': u'apache-vg', u'devices':
u'/dev/vdb1,/dev/vdb2'})
...output omitted...

TASK [Create each Logical Volume (LV) if needed] *****************************


skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size':
u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'})
skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size':
u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'})

TASK [Ensure XFS Filesystem exists on each LV] *******************************


ok: [servera.lab.example.com] => (item={...output omitted...})
ok: [servera.lab.example.com] => (item={...output omitted...})

TASK [Ensure the correct capacity for each LV] *******************************


changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size':
u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'})
changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size':
u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'})

TASK [Each Logical Volume is mounted] ****************************************


ok: [servera.lab.example.com] => (item={...output omitted...})
ok: [servera.lab.example.com] => (item={...output omitted...})

PLAY RECAP *******************************************************************


servera.lab.example.com : ok=6 changed=3 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

La salida indica cambios en las particiones y el grupo de volúmenes en el host remoto,


y que ambos volúmenes lógicos fueron redimensionados.

10.5. Use un comando ad hoc Ansible para ejecutar el comando lsblk en el host remoto.

[student@workstation system-storage]$ ansible all -a lsblk


servera.lab.example.com | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 10G 0 disk
└─vda1 252:1 0 10G 0 part /
vdb 252:16 0 1G 0 disk
├─vdb1 252:17 0 256M 0 part
│ ├─apache--vg-content--lv 253:0 0 128M 0 lvm /var/www
│ └─apache--vg-logs--lv 253:1 0 256M 0 lvm /var/log/httpd
└─vdb2 252:18 0 256M 0 part
├─apache--vg-content--lv 253:0 0 128M 0 lvm /var/www
└─apache--vg-logs--lv 253:1 0 256M 0 lvm /var/log/httpd

La salida indica que cada volumen lógico es del tamaño correcto y está montado
en el directorio correcto. Existen dos entradas para cada volumen lógico porque los
archivos almacenados en el volumen lógico pueden estar ubicados físicamente en
cualquier partición (/dev/vdb1 o /dev/vdb2).

RH294-RHEL8.0-es-1-20200501 447
capítulo 10 | Automatización de tareas de administración de Linux

Finalizar
Ejecute el comando lab system-storage finish para limpiar el host administrado.

[student@workstation ~]$ lab system-storage finish

Esto concluye el ejercicio guiado.

448 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Administración de la configuración de red

Objetivos
Tras completar esta sección, deberá ser capaz de configurar los ajustes de red y la resolución de
nombres en los hosts administrados y recopilar datos de Ansible relacionados con la red.

Configuración de redes con el rol de sistema de red


Red Hat Enterprise Linux 8 incluye una colección de roles de sistema Ansible para configurar
sistemas basados en RHEL. El paquete rhel-system-roles instala los roles de sistema que, por
ejemplo, admiten la configuración de sincronización de tiempo o redes. Puede enumerar los roles
de sistema instalados actualmente con el comando ansible-galaxy list.

[user@controlnode ~]$ ansible-galaxy list


- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)

Los roles están ubicados en el directorio /usr/share/ansible/roles. Un rol que comience


con linux-system-roles es un vínculo simbólico al rol rhel-system-roles correspondiente.

El rol de sistema de red admite la configuración de redes en hosts administrados. Este rol admite
la configuración de interfaces Ethernet, interfaces de puente, interfaces enlazadas, interfaces
VLAN, interfaces MacVLAN e interfaces Infiniband. El rol de red se configura con dos variables,
network_provider y network_connections.

---
network_provider: nm
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.30/24

La variable network_provider configura el proveedor de backend, ya sea nm


(NetworkManager) o initscripts. En Red Hat Enterprise Linux 8, el rol de red usa nm
(NetworkManager) como proveedor de red predeterminado. El proveedor initscripts se
usa para los sistemas RHEL 6 y requiere que el servicio network esté disponible. La variable
network_connections configura las diferentes conexiones, especificadas como una lista de
diccionarios, usando el nombre de la interfaz como el nombre de la conexión.

RH294-RHEL8.0-es-1-20200501 449
capítulo 10 | Automatización de tareas de administración de Linux

En la siguiente tabla, se enumeran las opciones para la variable network_connections.

Nombre de la opción Descripción

name Identifica el perfil de conexión.

state El estado de tiempo de ejecución de un perfil


de conexión. Puede ser up (activo), si el perfil
de conexión está activo, o down (inactivo), si
no lo está.

persistent_state Identifica si un perfil de conexión es


persistente. Puede ser present (presente) si
el perfil de conexión es persistente, o absent
(ausente) si no lo es.

type Identifica el tipo de conexión. Los valores


válidos son ethernet, bridge (puente),
bond (enlace), team (equipo), vlan,
macvlan e infiniband.

autoconnect Determina si la conexión se inicia


automáticamente.

mac Restringe la conexión que se usará en


dispositivos con una dirección MAC
específica.

interface_name Restringe el perfil de conexión que usará una


interfaz específica.

zone Configura la zona de FirewallD para la interfaz.

ip Determina la configuración de IP para


la conexión. Admite opciones como,
por ejemplo, address (dirección), para
especificar una dirección IP estática, o dns
para configurar un servidor DNS.

En el siguiente ejemplo, se usan algunas de las opciones anteriores:

network_connections:
- name: eth0
persistent_state: present
type: ethernet
autoconnect: yes
mac: 00:00:5e:00:53:5d
ip:
address:
- 172.25.250.40/24
zone: external

Usa eth0 como nombre de conexión.


Hace que la conexión sea persistente. Este es el valor predeterminado.
Establece el tipo de conexión en ethernet.

450 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Inicia automáticamente la conexión durante el arranque. Este es el valor predeterminado.


Restringe el uso de la conexión a un dispositivo con esa dirección MAC.
Configura la dirección IP 172.25.250.40/24 para la conexión.
Configura la zona external (externa) como la zona FirewallD de la conexión.

Para usar el rol de sistema de red, debe especificar el nombre del rol en la cláusula roles de la
guía, dela siguiente manera:

- name: NIC Configuration


hosts: webservers
vars:
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.30/24
roles:
- rhel-system-roles.network

Puede especificar variables para el rol de red con la cláusula vars, como en el ejemplo anterior, o
crear un archivo YAML con esas variables en los directorios group_vars o host_vars, según el
caso de uso.

Configuración de redes con módulos


Como alternativa al rol de sistema network (red), Red Hat Ansible Engine incluye una colección
de módulos que admiten la configuración de red en un sistema. El módulo nmcli admite la
administración de conexiones y dispositivos de red. Este módulo admite la configuración de
equipos y enlaces para las interfaces de red, así como el direccionamiento IPv4 e IPv6.

La tabla siguiente enumera algunos de los parámetros para el módulo nmcli.

Nombre del parámetro Descripción

conn_name Configura el nombre de la conexión.

autoconnect Permite la activación automática de la


conexión en el arranque.

dns4 Configura los servidores DNS para IPv4


(hasta 3).

gw4 Configura la puerta de enlace IPv4 para la


interfaz.

ifname Interfaz que estará ligada a la conexión.

ip4 Dirección IP (IPv4) para la interfaz.

state Habilita o deshabilita la interfaz de red.

type Tipo de dispositivo o conexión de red.

En el siguiente ejemplo, se establece una configuración de IP estático para una conexión y un


dispositivo de red.

RH294-RHEL8.0-es-1-20200501 451
capítulo 10 | Automatización de tareas de administración de Linux

- name: NIC configuration


nmcli:
conn_name: ens4-conn
ifname: ens4
type: ethernet
ip4: 172.25.250.30/24
gw4: 172.25.250.1
state: present

Configura ens4-conn como nombre de la conexión.


Enlaza la conexión ens4-conn con la interfaz de red ens4.
Configura la interfaz de red como ethernet.
Configura la dirección IP 172.25.250.30/24 en la interfaz.
Establece la puerta de enlace en 172.25.250.1.
Se asegura de que la conexión esté disponible.

El módulo hostname (nombre de host) establece el nombre de host para un host administrado sin
modificar el archivo /etc/hosts. Este módulo usa el parámetro name (nombre) para especificar
el nuevo nombre de host, como en la tarea que se muestra a continuación:

- name: Change hostname


hostname:
name: managedhost1

El módulo firewalld admite la administración de FirewallD en hosts administrados. Estos


módulos admiten la configuración de las reglas de FirewallD para servicios y puertos. También
admite la administración de zona, incluida la asociación de interfaces y reglas de red a una zona
específica.

La siguiente tarea muestra cómo crear una regla de FirewallD para el servicio http en la zona
predeterminada (public [pública]). La tarea configura la regla como permanente y se asegura de
que esté activa.

- name: Enabling http rule


firewalld:
service: http
permanent: yes
state: enabled

Esta tarea configura eth0 en la zona de FirewallD external (externa).

- name: Moving eth0 to external


firewalld:
zone: external
interface: eth0
permanent: yes
state: enabled

La tabla siguiente enumera algunos de los parámetros para el módulo firewalld.

452 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Nombre del parámetro Descripción

interface El nombre de la interfaz que se administrará


con FirewallD.

port Puerto o intervalo de puerto. Usa el formato


puerto/protocolo o puerto-puerto/protocolo.

rich_rule Regla enriquecida para FirewallD.

service El nombre del servicio que se administrará


con FirewallD.

source Red de origen que se administrará con


FirewallD.

zone La zona de FirewallD.

state Habilita o deshabilita una configuración de


FirewallD.

type Tipo de dispositivo o conexión de red.

Datos de Ansible para la configuración de red


Ansible usa datos para recuperar información del nodo de control sobre la configuración de los
hosts administrados. Puede usar el módulo de Ansible setup (configuración) para recuperar
todos los datos de Ansible para un host administrado.

[user@controlnode ~]$ ansible webservers -m setup


host.lab.example.com | SUCCESS => {
"ansible_facts": {
...output omitted...
}

Todas las interfaces de red para un host administrado están disponibles en el elemento
ansible_interfaces. Puede usar el parámetro gather_subset=network para el módulo
setup a fin de restringir los hechos a los incluidos en el subconjunto network (red). La opción
filter (filtrar) para el módulo setup admite filtrado detallado basado en comodines de tipo
shell.

[user@controlnode ~]$ ansible webservers -m setup \


> -a 'gather_subset=network filter=ansible_interfaces'
host.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_interfaces": [
"ens4",
"lo",
"ens3"
]
},
"changed": false
}

RH294-RHEL8.0-es-1-20200501 453
capítulo 10 | Automatización de tareas de administración de Linux

El comando anterior muestra que hay tres interfaces de red disponibles en el host administrado,
host.lab.example.com: lo, ens3 y ens4.

Puede recuperar información adicional sobre la configuración de una interfaz de red con el filtro
ansible_NIC_name para el módulo setup. Por ejemplo, para recuperar la configuración de la
interfaz de red ens4, use el filtro ansible_ens4.

[user@controlnode ~]$ ansible webservers -m setup \


> -a 'gather_subset=network filter=ansible_ens4'
host.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_ens4": {
"active": true,
"device": "ens4",
"features": {
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "172.25.250.30",
"broadcast": "172.25.250.255",
"netmask": "255.255.255.0",
"network": "172.25.250.0"
},
"ipv6": [
{
"address": "fe80::5b42:8c94:1fc7:40ae",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "52:54:00:01:fa:0a",
"module": "virtio_net",
"mtu": 1500,
"pciid": "virtio1",
"promisc": false,
"speed": -1,
"timestamping": [
"tx_software",
"rx_software",
"software"
],
"type": "ether"
}
},
"changed": false
}

El comando anterior muestra detalles de configuración adicionales, como la configuración de


dirección IP para IPv4 e IPv6, el dispositivo asociado y el tipo.

En la siguiente tabla, se enumeran algunos de los datos disponibles para el subconjunto network.

454 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

Nombre del dato Descripción

ansible_dns Incluye la dirección IP de los servidores DNS y


los dominios de búsqueda.

ansible_domain Incluye el subdominio para el host


administrado.

ansible_all_ipv4_addresses Incluye todas las direcciones IPv4


configuradas en el host administrado.

ansible_all_ipv6_addresses Incluye todas las direcciones IPv6


configuradas en el host administrado.

ansible_fqdn Incluye el FQDN para el host administrado.

ansible_hostname Incluye el nombre de host no calificado, la


cadena del FQDN antes del primer punto.

ansible_nodename Incluye el nombre de host para el host


administrado según lo informado por el
sistema.

nota
Ansible también proporciona la variable inventory_hostname que incluye el
nombre de host como está configurado en el archivo de inventario de Ansible.

Referencias
Base de conocimiento: Roles de sistema de Red Hat Enterprise Linux (RHEL)
https://access.redhat.com/articles/3050101

Roles de sistema de Linux


https://linux-system-roles.github.io/

Documentación de módulo nmcli


https://docs.ansible.com/ansible/latest/modules/nmcli_module.html/

Documentación de módulo hostname


https://docs.ansible.com/ansible/latest/modules/hostname_module.html/

Documentación de módulo firewalld


https://docs.ansible.com/ansible/latest/modules/firewalld_module.html/

RH294-RHEL8.0-es-1-20200501 455
capítulo 10 | Automatización de tareas de administración de Linux

Ejercicio Guiado

Administración de la configuración de red


En este ejercicio, ajustará la configuración de red de un host administrado y recopilará
información sobre él en un archivo creado por una plantilla.

Resultados
Deberá ser capaz de configurar los ajustes de red y la resolución de nombres en los hosts
administrados y recopilar datos de Ansible relacionados con la red.

Andes De Comenzar
Desde workstation, ejecute el script lab system-network start para configurar el
entorno para el ejercicio. El script crea el directorio de trabajo system-network y descarga
el archivo de configuración de Ansible y el archivo de inventario del host necesarios para el
ejercicio.

[student@workstation ~]$ lab system-network start

1. Revise el archivo de inventario del directorio /home/student/system-network.

1.1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-network.

[student@workstation ~]$ cd ~/system-network


[student@workstation system-network]$

1.2. Verifique que servera.lab.example.com sea parte del grupo de hosts


webservers (servidores web). Este servidor tiene una interfaz de red de repuesto.

[student@workstation system-network]$ cat inventory


[webservers]
servera.lab.example.com

2. Use el comando ansible-galaxy para verificar que los roles del sistema estén
disponibles. Si no hay roles disponibles, debe instalar el paquete rhel-system-roles.

[student@workstation system-network]$ ansible-galaxy list


# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)

456 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

- rhel-system-roles.selinux, (unknown version)


- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.

3. Cree una guía que use el rol linux-system-roles.network para configurar la interfaz de red de
repuesto, ens4, en servera.lab.example.com con la dirección IP 172.25.250.30.

3.1. Cree una guía, playbook.yml, con una reproducción orientada al grupo de hosts
webservers. Incluya el rol rhel-system-roles.network en la sección roles de
la reproducción.

---
- name: NIC Configuration
hosts: webservers

roles:
- rhel-system-roles.network

3.2. Consulte la sección Variables de rol del archivo README.md para conocer el rol rhel-
system-roles.network. Determine las variables de rol para configurar la interfaz
de red ens4 con la dirección IP 172.25.250.30.

[student@workstation system-network]$ cat \


> /usr/share/doc/rhel-system-roles/network/README.md
...output omitted...
Setting the IP configuration:
...output omitted...

3.3. Cree el subdirectorio group_vars/webservers.

[student@workstation system-network]$ mkdir -pv group_vars/webservers


mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/webservers'

3.4. Cree un archivo nuevo network.yml para definir variables de rol. Como estos
valores de variable se aplican a los hosts del grupo de hosts webservers, debe crear
ese archivo en el directorio group_vars/webservers. Agregue definiciones de
variables para admitir la configuración de la interfaz de red ens4. El archivo ahora
contiene lo siguiente:

---
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.30/24

3.5. Ejecute la guía para configurar la interfaz de red secundaria en servera.

RH294-RHEL8.0-es-1-20200501 457
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-network]$ ansible-playbook playbook.yml

PLAY [NIC Configuration] *******************************************************

TASK [Gathering Facts] *********************************************************


ok: [servera.lab.example.com]

TASK [rhel-system-roles.network : Check which services are running] ************


ok: [servera.lab.example.com]

TASK [rhel-system-roles.network : Check which packages are installed] **********


ok: [servera.lab.example.com]

TASK [rhel-system-roles.network : Print network provider] **********************


ok: [servera.lab.example.com] => {
"msg": "Using network provider: nm"
}

TASK [rhel-system-roles.network : Install packages] ****************************


skipping: [servera.lab.example.com]

TASK [rhel-system-roles.network : Enable network service] **********************


ok: [servera.lab.example.com]

TASK [rhel-system-roles.network : Configure networking connection profiles] ****


...output omitted...

changed: [servera.lab.example.com]

TASK [rhel-system-roles.network : Re-test connectivity] ************************


ok: [servera.lab.example.com]

PLAY RECAP *********************************************************************


servera.lab.example.com : ok=7 changed=1 unreachable=0 failed=0
skipped=1 rescued=0 ignored=0

4. Use el módulo setup de Ansible en un comando adhoc de Ansible para verificar que la
configuración de la interfaz de red ens4 en servera sea correcta.

4.1. Use el módulo de Ansible setup para enumerar todos los datos de Ansible
disponibles para servera. Filtre los resultados para la interfaz de red ens4 con la
opción -a 'filter=filter_string'. Verifique que la interfaz de red ens4 use
la dirección IP 172.25.250.30. La configuración de la dirección IP puede demorar
hasta un minuto.

[student@workstation system-network]$ ansible webservers -m setup \


> -a 'filter=ansible_ens4'
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_ens4": {
...output omitted...
"ipv4": {
"address": "172.25.250.30",

458 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

"broadcast": "172.25.250.255",
"netmask": "255.255.255.0",
"network": "172.25.250.0"
},
...output omitted...

Finalizar
En workstation, ejecute el script lab system-network finish para limpiar los recursos
creados en este ejercicio.

[student@workstation ~]$ lab system-network finish

Esto concluye el ejercicio guiado.

RH294-RHEL8.0-es-1-20200501 459
capítulo 10 | Automatización de tareas de administración de Linux

Trabajo de laboratorio

Automatización de tareas de
administración de Linux
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará y realizará tareas administrativas en hosts
administrados usando una guía.

Resultados
Debe ser capaz de crear guías para configurar en un host administrado un repositorio
de software, usuarios y grupos, volúmenes lógicos, trabajos de cron e interfaces de red
adicionales.

Andes De Comenzar
En workstation, ejecute el script de inicio del trabajo de laboratorio a fin de confirmar que
el entorno esté listo para que comience el trabajo de laboratorio. El script crea el directorio
de trabajo, denominado system-review, y lo completa con un archivo de configuración
Ansible, un inventario de hosts y archivos de laboratorio.

[student@workstation ~]$ lab system-review start

1. Cree y ejecute en el grupo de hosts webservers una guía que configure el repositorio
interno de Yum ubicado en http://materials.example.com/yum/repository, e
instale el paquete example-motd disponible en ese repositorio. Todos los paquetes RPM
están firmados con un par de claves GPG organizativas. La clave pública de GPG está
disponible en http://materials.example.com/yum/repository/RPM-GPG-KEY-
example.
2. Cree y ejecute en el grupo de hosts webservers una guía que cree el grupo de usuarios
webadmin, y agregue dos usuarios a ese grupo, ops1 y ops2.
3. Cree y ejecute en el grupo de hosts webservers una guía que use el dispositivo /dev/
vdb para crear un grupo de volúmenes llamado apache-vg. Esta guía también crea dos
volúmenes lógicos denominados content-lv y logs-lv, ambos respaldados por el grupo
de volúmenes apache-vg. Finalmente, crea un sistema de archivos XFS en cada volumen
lógico y monta el volumen lógico content-lv en /var/www, y el volumen lógico logs-lv
en /var/log/httpd. El script de laboratorio completa dos archivos en ~/system-review,
storage.yml que proporciona un esqueleto inicial para la guía, y storage_vars.xml que
proporciona valores para todas las variables requeridas por los diferentes módulos.
4. Cree y ejecute en el grupo de hosts webservers una guía que use el módulo cron para
crear el archivo crontab /etc/cron.d/disk_usage que programa un trabajo cron
recurrente. El trabajo debe ejecutarse con el usuario devops cada dos minutos entre las
09:00 y las 16:59 de lunes a viernes. El trabajo debe adjuntar el uso de disco actual al
archivo /home/devops/disk_usage.

460 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

5. Cree y ejecute en el grupo de hosts webservers una guía que use el rol linux-system-
roles.network para configurar con la dirección IP 172.25.250.40/24 la interfaz de red
de repuesto, ens4.
6. Ejecute lab system-review grade en workstation para calificar su trabajo.

[student@workstation ~]$ lab system-review grade

Finalizar
En workstation, ejecute el script lab system-review finish para "limpiar" los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab system-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 461
capítulo 10 | Automatización de tareas de administración de Linux

Solución

Automatización de tareas de
administración de Linux
Lista de verificación de rendimiento
En este trabajo de laboratorio, configurará y realizará tareas administrativas en hosts
administrados usando una guía.

Resultados
Debe ser capaz de crear guías para configurar en un host administrado un repositorio
de software, usuarios y grupos, volúmenes lógicos, trabajos de cron e interfaces de red
adicionales.

Andes De Comenzar
En workstation, ejecute el script de inicio del trabajo de laboratorio a fin de confirmar que
el entorno esté listo para que comience el trabajo de laboratorio. El script crea el directorio
de trabajo, denominado system-review, y lo completa con un archivo de configuración
Ansible, un inventario de hosts y archivos de laboratorio.

[student@workstation ~]$ lab system-review start

1. Cree y ejecute en el grupo de hosts webservers una guía que configure el repositorio
interno de Yum ubicado en http://materials.example.com/yum/repository, e
instale el paquete example-motd disponible en ese repositorio. Todos los paquetes RPM
están firmados con un par de claves GPG organizativas. La clave pública de GPG está
disponible en http://materials.example.com/yum/repository/RPM-GPG-KEY-
example.

1.1. Con el usuario student en workstation, cambie al directorio de trabajo /home/


student/system-review.

[student@workstation ~]$ cd ~/system-review


[student@workstation system-review]$

1.2. Cree la guía repo_playbook.yml que se ejecuta en los hosts administrados en el


grupo de hosts webservers. Agregue una tarea que use el módulo yum_repository
para asegurar la configuración del repositorio yum interno en el host remoto.
Asegúrese de lo siguiente:

• La configuración del repositorio se almacena en el archivo /etc/yum.repos.d/


example.repo.

• El ID del repositorio es example-internal.

• La URL base es http://materials.example.com/yum/repository.

• El repositorio está configurado para verificar las firmas RPM GPG.

462 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

• La descripción del repositorio es repositorio YUM interno de Ejemplo Inc.

La guía contiene lo siguiente:

---
- name: Repository Configuration
hosts: webservers
tasks:
- name: Ensure Example Repo exists
yum_repository:
name: example-internal
description: Example Inc. Internal YUM repo
file: example
baseurl: http://materials.example.com/yum/repository/
gpgcheck: yes

1.3. Agregue una segunda tarea a la reproducción que use el módulo rpm_key para
asegurarse de que la clave pública del repositorio esté presente en el host remoto. La
URL de la clave pública del repositorio es http://materials.example.com/yum/
repository/RPM-GPG-KEY-example.
La segunda tarea aparece de la siguiente manera:

- name: Ensure Repo RPM Key is Installed


rpm_key:
key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
state: present

1.4. Agregue una tercera tarea para instalar el paquete example-motd disponible en el
repositorio interno de Yum.
La tercera tarea aparece de la siguiente manera:

- name: Install Example motd package


yum:
name: example-motd
state: present

1.5. Ejecute la guía:

[student@workstation system-review]$ ansible-playbook repo_playbook.yml

PLAY [Repository Configuration] ************************************************

TASK [Gathering Facts] *********************************************************


ok: [serverb.lab.example.com]

TASK [Ensure Example Repo exists] **********************************************


changed: [serverb.lab.example.com]

TASK [Ensure Repo RPM Key is Installed] ****************************************


changed: [serverb.lab.example.com]

RH294-RHEL8.0-es-1-20200501 463
capítulo 10 | Automatización de tareas de administración de Linux

TASK [Install Example motd package] ********************************************


changed: [serverb.lab.example.com]

PLAY RECAP *********************************************************************


serverb.lab.example.com : ok=4 changed=3 unreachable=0 failed=0

2. Cree y ejecute en el grupo de hosts webservers una guía que cree el grupo de usuarios
webadmin, y agregue dos usuarios a ese grupo, ops1 y ops2.

2.1. Cree un archivo de variables vars/users_vars.yml, que define a dos usuarios,


ops1 y ops2, que pertenecen al grupo de usuarios webadmin. Es posible que deba
crear el subdirectorio vars.

[student@workstation system-review]$ mkdir vars


[student@workstation system-review]$ vi vars/users_vars.yml
---
users:
- username: ops1
groups: webadmin
- username: ops2
groups: webadmin

2.2. Cree la guía users.yml. Defina una sola reproducción en la guía que se dirija al grupo
de hosts webservers. Agregue una cláusula vars_files que defina la ubicación del
nombre de archivo vars/users_vars.yml. Agregue una tarea que use el módulo
group para crear el grupo de usuarios webadmin en el host remoto.

---
- name: Create multiple local users
hosts: webservers
vars_files:
- vars/users_vars.yml
tasks:
- name: Add webadmin group
group:
name: webadmin
state: present

2.3. Agregue una segunda tarea a la guía que usa el módulo user para crear los usuarios.
Agregue una cláusula loop: "{{ users }}" a la tarea para recorrer en bucle el
archivo de variables para cada nombre de usuario encontrado en el archivo vars/
users_vars.yml. Como name: para los usuarios, use el nombre de variable
item.username. De esta manera, el archivo de variables puede contener información
adicional que puede ser útil para crear los usuarios, como los grupos a los que deberían
pertenecer. La segunda tarea contiene lo siguiente:

- name: Create user accounts


user:
name: "{{ item.username }}"
groups: webadmin
loop: "{{ users }}"

2.4. Ejecute la guía:

464 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

[student@workstation system-review]$ ansible-playbook users.yml

PLAY [Create multiple local users]


****************************************************

TASK [Gathering Facts]


****************************************************************
ok: [serverb.lab.example.com]

TASK [Add webadmin group]


*************************************************************
changed: [serverb.lab.example.com]

TASK [Create user accounts]


***********************************************************
changed: [serverb.lab.example.com] => (item={'username': 'ops1', 'groups':
'webadmin'})
changed: [serverb.lab.example.com] => (item={'username': 'ops2', 'groups':
'webadmin'})

PLAY RECAP
****************************************************************************
serverb.lab.example.com : ok=3 changed=2 unreachable=0 failed=0

3. Cree y ejecute en el grupo de hosts webservers una guía que use el dispositivo /dev/
vdb para crear un grupo de volúmenes llamado apache-vg. Esta guía también crea dos
volúmenes lógicos denominados content-lv y logs-lv, ambos respaldados por el grupo
de volúmenes apache-vg. Finalmente, crea un sistema de archivos XFS en cada volumen
lógico y monta el volumen lógico content-lv en /var/www, y el volumen lógico logs-lv
en /var/log/httpd. El script de laboratorio completa dos archivos en ~/system-review,
storage.yml que proporciona un esqueleto inicial para la guía, y storage_vars.xml que
proporciona valores para todas las variables requeridas por los diferentes módulos.

3.1. Revise el archivo de variables storage_vars.yml.

[student@workstation system-review]$ cat storage_vars.yml


---

partitions:
- number: 1
start: 1MiB
end: 257MiB

volume_groups:
- name: apache-vg
devices: /dev/vdb1

logical_volumes:
- name: content-lv
size: 64M
vgroup: apache-vg
mount_path: /var/www

RH294-RHEL8.0-es-1-20200501 465
capítulo 10 | Automatización de tareas de administración de Linux

- name: logs-lv
size: 128M
vgroup: apache-vg
mount_path: /var/log/httpd

En este archivo se describe la estructura prevista de particiones, grupos de volúmenes


y volúmenes lógicos en cada servidor web. La primera partición comienza en un
desplazamiento de 1 MiB desde el principio del dispositivo /dev/vdb y termina en un
desplazamiento de 257 MiB, lo que resulta en un tamaño total de 256 MiB.
Cada servidor web tiene un grupo de volúmenes, llamado apache-vg, que contiene la
primera partición del dispositivo /dev/vdb.
Cada servidor web tiene dos volúmenes lógicos. El primer volumen lógico se llama
content-lv, con un tamaño de 64 MiB, está adjuntado al grupo de volumen apache-
vg y montado en /var/www. El segundo volumen lógico se llama content-lv, con un
tamaño de 128 MiB, está adjuntado al grupo de volumen apache-vg y montado en /
var/log/httpd.

nota
El grupo de volumen apache-vg tiene una capacidad de 256 MiB, porque está
respaldado por la partición /dev/vdb1. Proporciona suficiente capacidad para
ambos volúmenes lógicos.

3.2. Cambie la primera tarea de la guía storage.yml para usar el módulo parted para
configurar una partición para cada ítem de bucle. Cada ítem describe una partición
deseada del dispositivo /dev/vdb en cada servidor web:

number
El número de partición. Use esto como el valor de la palabra clave number para el
módulo parted.

start
El inicio de la partición, como un desplazamiento desde el principio del dispositivo
de bloque. Use esto como el valor de la palabra clave part_start para el módulo
parted.

end
El fin de la partición, como un desplazamiento desde el principio del dispositivo
de bloque. Use esto como el valor de la palabra clave part_end para el módulo
parted.

El contenido de la primera tarea debe ser el siguiente:

- name: Correct partitions exist on /dev/vdb


parted:
device: /dev/vdb
state: present
number: "{{ item.number }}"
part_start: "{{ item.start }}"
part_end: "{{ item.end }}"
loop: "{{ partitions }}"

3.3. Cambie la segunda tarea de la guía para usar el módulo lvg para configurar un
grupo de volúmenes para cada elemento de bucle. Cada elemento de la variable

466 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

volume_groups describe un grupo de volúmenes que debería existir en cada servidor


web:

name
El nombre del grupo de volúmenes. Use esto como el valor de la palabra clave vg
para el módulo lvg.

devices
Lista de dispositivos o particiones separados por coma que forman el grupo de
volúmenes. Use esto como el valor de la palabra clave pvs para el módulo lvg.

El contenido de la segunda tarea debe ser el siguiente:

- name: Ensure Volume Groups Exist


lvg:
vg: "{{ item.name }}"
pvs: "{{ item.devices }}"
loop: "{{ volume_groups }}"

3.4. Cambie la tercera tarea para usar el módulo lvol. Configure el nombre del grupo de
volúmenes, el nombre del volumen lógico y el tamaño del volumen lógico utilizando las
palabras clave de cada elemento. El contenido de la tercera tarea ahora es el siguiente:

- name: Create each Logical Volume (LV) if needed


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
loop: "{{ logical_volumes }}"

3.5. Cambie la cuarta tarea para usar el módulo filesystem. Configure la tarea para
asegurarse de que cada volumen lógico esté formateado como un sistema de archivos
XFS. Recuerde que un volumen lógico está asociado con el dispositivo lógico /
dev/<volume group name>/<logical volume name> .
El contenido de la cuarta tarea debe ser el siguiente:

- name: Ensure XFS Filesystem exists on each LV


filesystem:
dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
loop: "{{ logical_volumes }}"

3.6. Configure la quinta tarea para asegurarse de que cada volumen lógico tenga la
capacidad de almacenamiento correcta. Si el volumen lógico aumenta en capacidad,
asegúrese de forzar la expansión del sistema de archivos del volumen.

Advertencia
Si un volumen lógico necesita disminuir su capacidad, esta tarea fallará porque un
sistema de archivos XFS no admite la reducción de la capacidad.

El contenido de la quinta tarea debe ser el siguiente:

RH294-RHEL8.0-es-1-20200501 467
capítulo 10 | Automatización de tareas de administración de Linux

- name: Ensure the correct capacity for each LV


lvol:
vg: "{{ item.vgroup }}"
lv: "{{ item.name }}"
size: "{{ item.size }}"
resizefs: yes
force: yes
loop: "{{ logical_volumes }}"

3.7. Use el módulo mount en la sexta tarea para garantizar que cada volumen lógico se
monte en la ruta de montaje correspondiente y persista después de un reinicio.
El contenido de la sexta tarea debe ser el siguiente:

- name: Each Logical Volume is mounted


mount:
path: "{{ item.mount_path }}"
src: "/dev/{{ item.vgroup }}/{{ item.name }}"
fstype: xfs
state: mounted
loop: "{{ logical_volumes }}"

3.8. Ejecute la guía para crear los volúmenes lógicos en el host remoto.

[student@workstation system-review]$ ansible-playbook storage.yml


PLAY [Ensure Apache Storage Configuration]
*************************************************

TASK [Gathering Facts]


*********************************************************************
ok: [serverb.lab.example.com]

TASK [Correct partitions exist on /dev/vdb]


************************************************
changed: [serverb.lab.example.com] => (item={'number': 1, 'start': '1MiB', 'end':
'257MiB'})

TASK [Ensure Volume Groups Exist]


**********************************************************
changed: [serverb.lab.example.com] => (item={'name': 'apache-vg', 'devices': '/
dev/vdb1'})
...output omitted...

TASK [Create each Logical Volume (LV) if needed]


*******************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M',
'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M',
'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Ensure XFS Filesystem exists on each LV]


*********************************************

468 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M',


'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M',
'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Ensure the correct capacity for each LV]


*********************************************
ok: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M',
'vgroup': 'apache-vg', 'mount_path': '/var/www'})
ok: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M',
'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Each Logical Volume is mounted]


******************************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M',
'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M',
'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

PLAY RECAP
*********************************************************************************
serverb.lab.example.com : ok=7 changed=5 unreachable=0 failed=0

4. Cree y ejecute en el grupo de hosts webservers una guía que use el módulo cron para
crear el archivo crontab /etc/cron.d/disk_usage que programa un trabajo cron
recurrente. El trabajo debe ejecutarse con el usuario devops cada dos minutos entre las
09:00 y las 16:59 de lunes a viernes. El trabajo debe adjuntar el uso de disco actual al
archivo /home/devops/disk_usage.

4.1. Cree una nueva guía, create_crontab_file.yml, y agregue las líneas necesarias
para iniciar la reproducción. Debe apuntar a los hosts administrados del grupo
webservers y habilitar el escalamiento de privilegios.

---
- name: Recurring cron job
hosts: webservers
become: true

4.2. Defina una tarea que use el módulo cron para programar un trabajo cron recurrente.

nota
El módulo cron proporciona una opción name para describir de forma única la
entrada del archivo crontab y garantizar los resultados esperados. La descripción
se agrega al archivo crontab. Por ejemplo, se requiere la opción name para eliminar
una entrada de crontab usando state=absent. Además, al configurar el estado
predeterminado state=present, la opción name evita que se cree siempre una
nueva entrada de crontab, independientemente de las existentes.

RH294-RHEL8.0-es-1-20200501 469
capítulo 10 | Automatización de tareas de administración de Linux

tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file

4.3. Configure el trabajo para que se ejecute cada dos minutos entre las 09:00 y las 16:59
de lunes a viernes.

minute: "*/2"
hour: 9-16
weekday: 1-5

4.4. Use el parámetro cron_file para utilizar el archivo crontab /etc/cron.d/


disk_usage en lugar del crontab de un usuario individual en /var/spool/cron/.
Una ruta relativa colocará el archivo en el directorio /etc/cron.d. Si se usa el
parámetro cron_file, también debe especificar el parámetro user.

user: devops
job: df >> /home/devops/disk_usage
cron_file: disk_usage
state: present

4.5. Cuando se complete, la guía debe verse de la siguiente forma. Revise la guía para
comprobar la precisión.

---
- name: Recurring cron job
hosts: webservers
become: true

tasks:
- name: Crontab file exists
cron:
name: Add date and time to a file
minute: "*/2"
hour: 9-16
weekday: 1-5
user: devops
job: df >> /home/devops/disk_usage
cron_file: disk_usage
state: present

4.6. Ejecute la guía.

[student@workstation system-review]$ ansible-playbook create_crontab_file.yml


PLAY [Recurring cron job]
*********************************************************************

TASK [Gathering Facts]


************************************************************************

470 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

ok: [serverb.lab.example.com]

TASK [Crontab file exists]


********************************************************************
changed: [serverb.lab.example.com]

PLAY RECAP
*********************************************************************************
***
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0

5. Cree y ejecute en el grupo de hosts webservers una guía que use el rol linux-system-
roles.network para configurar con la dirección IP 172.25.250.40/24 la interfaz de red
de repuesto, ens4.

5.1. Use ansible-galaxy para verificar que los roles del sistema estén disponibles. Si no
lo están, debe instalar el paquete rhel-system-roles.

[student@workstation system-review]$ ansible-galaxy list


# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.

5.2. Cree una guía, network_playbook.yml, con una reproducción orientada al grupo
de hosts webservers. Incluya el rol rhel-system-roles.network en la sección
roles de la reproducción.

---
- name: NIC Configuration
hosts: webservers

roles:
- rhel-system-roles.network

5.3. Cree el subdirectorio group_vars/webservers.

[student@workstation system-review]$ mkdir -pv group_vars/webservers


mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/webservers'

5.4. Cree un archivo nuevo network.yml para definir variables de rol. Como estos valores
de variable se aplican a los hosts del grupo de hosts webservers, debe crear ese
archivo en el directorio group_vars/webservers. Agregue definiciones de variables

RH294-RHEL8.0-es-1-20200501 471
capítulo 10 | Automatización de tareas de administración de Linux

para admitir la configuración de la interfaz de red ens4. El archivo ahora contiene lo


siguiente:

[student@workstation system-review]$ vi group_vars/webservers/network.yml


---
network_connections:
- name: ens4
type: ethernet
ip:
address:
- 172.25.250.40/24

5.5. Ejecute la guía para configurar la interfaz de red secundaria.

[student@workstation system-review]$ ansible-playbook network_playbook.yml

PLAY [NIC Configuration]


*******************************************************************

TASK [Gathering Facts]


*********************************************************************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Check which services are running]


************************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Check which packages are installed]


**********************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Print network provider]


**********************************
ok: [serverb.lab.example.com] => {
"msg": "Using network provider: nm"
}

TASK [rhel-system-roles.network : Install packages]


****************************************
skipping: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Enable network service]


**********************************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Configure networking connection profiles]


****************
[WARNING]: [002] <info> #0, state:None persistent_state:present, 'ens4': add
connection
ens4, 38d63afd-e610-4929-ba1b-1d38413219fb

changed: [serverb.lab.example.com]

472 RH294-RHEL8.0-es-1-20200501
capítulo 10 | Automatización de tareas de administración de Linux

TASK [rhel-system-roles.network : Re-test connectivity]


************************************
ok: [serverb.lab.example.com]

PLAY RECAP
*********************************************************************************
serverb.lab.example.com : ok=7 changed=1 unreachable=0 failed=0

5.6. Verifique que la interfaz de red ens4 use la dirección IP 172.25.250.40. La


configuración de la dirección IP puede demorar hasta un minuto.

[student@workstation system-review]$ ansible webservers -m setup \


> -a 'filter=ansible_ens4'
serverb.lab.example.com | SUCCESS => {
"ansible_facts": {
"ansible_ens4": {
...output omitted...
"ipv4": {
"address": "172.25.250.40",
"broadcast": "172.25.250.255",
"netmask": "255.255.255.0",
"network": "172.25.250.0"
},
...output omitted...

6. Ejecute lab system-review grade en workstation para calificar su trabajo.

[student@workstation ~]$ lab system-review grade

Finalizar
En workstation, ejecute el script lab system-review finish para "limpiar" los recursos
creados en este trabajo de laboratorio.

[student@workstation ~]$ lab system-review finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 473
capítulo 10 | Automatización de tareas de administración de Linux

Resumen
En este capítulo, aprendió lo siguiente:

• El módulo yum_repository configura un repositorio de Yum en un host administrado. Para los


repositorios que usan claves públicas, puede verificar que la clave esté disponible con el módulo
rpm_key.

• Los módulos user y group crean usuarios y grupos respectivamente en un host administrado.
Puede configurar claves autorizadas para un usuario con el módulo authorized_key.

• Los trabajos de Cron se pueden configurar en hosts administrados con el módulo cron.

• Ansible admite la configuración de volúmenes lógicos con los módulos lvg y lvol. Los módulos
parted y filesystem admiten respectivamente la partición de dispositivos y la creación de
sistemas de archivos.

• Red Hat Enterprise Linux 8 incluye el rol de sistema de red que admite la configuración de
interfaces de red en hosts administrados.

474 RH294-RHEL8.0-es-1-20200501
capítulo 11

Revisión completa: Automation


with Ansible
Meta Demuestre las habilidades aprendidas en este
curso mediante la instalación, optimización y
configuración de Ansible para la administración de
hosts administrados.

Secciones • Revisión completa

Trabajos de • Trabajo de laboratorio: Implementación de


Ansible
laboratorio
• Trabajo de laboratorio: Creación de guías
• Trabajo de laboratorio: Creación de roles y uso
de inventarios dinámicos

RH294-RHEL8.0-es-1-20200501 475
capítulo 11 | Revisión completa: Automation with Ansible

Revisión completa

Objetivos
Tras finalizar esta sección, deberá ser capaz de demostrar competencia con las habilidades y los
conocimientos aprendidos en Red Hat Enterprise Linux Automation with Ansible.

Revisión de Administración de sistemas Red Hat III:


automatización de Linux
Antes de comenzar la revisión completa de este curso, debe sentirse cómodo con los temas que
se abordaron en cada capítulo.

Consulte las secciones anteriores del libro de texto para lecturas complementarias.

Capítulo 1, Presentación de Ansible


Describir los conceptos fundamentales de Ansible y la forma de usarlo, e instalar Red Hat Ansible
Engine.

• Describir la motivación para automatizar las tareas de administración de Linux con Ansible, los
conceptos fundamentales de Ansible y la arquitectura básica de Ansible.

• Instalar Ansible en un nodo de control y describir la distinción entre la comunidad Ansible y


Red Hat Ansible Engine.

Capítulo 2, Implementación de Ansible


Configurar Ansible para administrar hosts y ejecutar comandos ad hoc Ansible.

• Describir los conceptos de inventario de Ansible y administrar un archivo de inventario estático.

• Describir dónde se encuentran los archivos de configuración de Ansible, cómo los selecciona
Ansible y editarlos para aplicar los cambios a la configuración predeterminada.

• Ejecutar una única tarea de automatización Ansible utilizando un comando ad hoc y explicar
algunos casos de uso de comandos ad hoc.

Capítulo 3, Implementación de guías


Escribir un Ansible Playbook simple y ejecutarlo para automatizar tareas en varios hosts.

• Escribir una guía de Ansible básica y ejecutarla con el comando ansible-playbook.

• Escribir una guía que use varias reproducciones y escalamiento de privilegios por reproducción.

• Usar con eficacia ansible-doc para aprender a usar nuevos módulos a fin de implementar
tareas para una reproducción.

Capítulo 4, Administración de variables y hechos


Escribir guías que usen variables para simplificar la administración de la guía y datos para hacer
referencia a información sobre los hosts administrados.

476 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

• Crear variables que afecten a hosts particulares o grupos de hosts, la reproducción o el entorno
global, y hacer referencia a ellas, y describir cómo funciona la prioridad de variables.

• Cifrar las variables confidenciales utilizando Ansible Vault y ejecutar guías que hagan referencia
a archivos de variables cifradas por Vault.

• Hacer referencia a los datos sobre hosts administrados que utilizan datos de Ansible y configurar
hechos personalizados en hosts administrados.

Capítulo 5, Implementación del control de tareas


Administrar el control de tareas, los manejadores y los errores de tareas en Ansible Playbooks.

• Implementar bucles para escribir tareas eficientes a fin de controlar cuándo ejecutar tareas.

• Implementar una tarea que se ejecute solo cuando otra tarea cambie el host administrado.

• Controlar lo que sucede cuando falla una tarea y qué condiciones hacen que falle una tarea.

Capítulo 6, Implementación de archivos en hosts


administrados
Implementar, administrar y ajustar archivos en hosts administrados por Ansible.

• Crear, instalar, editar y eliminar archivos en hosts administrados, y gestionar permisos,


propiedad, contexto de SELinux y otras características de esos archivos.

• Personalizar archivos mediante el uso de plantillas Jinja2 e implementarlas en hosts


administrados.

Capítulo 7, Administración de proyectos grandes


Escribir guías que estén optimizadas para proyectos más grandes y complejos.

• Escribir patrones de host sofisticados para seleccionar hosts de manera eficiente para un
comando de reproducción o ad hoc.

• Describir las características y el propósito de los inventarios dinámicos, e instalar y usar un script
existente como fuente de inventario dinámico de Ansible.

• Ajustar la cantidad de conexiones simultáneas que Ansible abre a los hosts administrados, y
cómo Ansible procesa grupos de hosts administrados a través de las tareas de la reproducción.

• Administrar guías grandes importando o incluyendo otras guías o tareas desde archivos
externos, ya sea sin condiciones o sobre la base de una prueba condicional.

Capítulo 8, Simplificación de guías con roles


Usar los roles de Ansible para desarrollar guías más rápidamente y reutilizar el código de Ansible.

• Describir qué es un rol, cómo está estructurado y cómo puede usarlo en una guía.

• Crear un rol en el directorio de proyectos de una guía y ejecutarlo como parte de una de las
reproducciones de la guía.

• Seleccionar y recuperar roles de Ansible Galaxy u otras fuentes, como un repositorio Git, y
utilizarlos en sus guías.

• Escribir guías que aprovechen los roles del sistema de Red Hat Enterprise Linux para realizar
operaciones estándares.

RH294-RHEL8.0-es-1-20200501 477
capítulo 11 | Revisión completa: Automation with Ansible

Capítulo 9, Resolución de problemas de Ansible


Resolver problemas de guías y hosts administrados.

• Solucionar problemas genéricos con una nueva guía y repararlos

• Solucionar fallas en hosts administrados cuando se ejecuta una guía

Capítulo 10, Automatización de tareas de administración de


Linux
Automatizar las tareas de administración comunes del sistema Linux con Ansible.

• Suscribir sistemas, configurar canales de software y repositorios, y gestionar paquetes RPM en


hosts administrados.

• Administrar usuarios y grupos de Linux, configurar SSH y modificar la configuración de Sudo en


hosts administrados.

• Administrar el inicio del servicio, programar procesos con at, cron y systemd, reiniciar y controlar
el destino de inicio predeterminado en los hosts administrados.

• Particionar los dispositivos de almacenamiento, configurar LVM, formatear particiones o


volúmenes lógicos, montar sistemas de archivos, y agregar espacios o archivos de intercambio.

478 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Trabajo de laboratorio

Implementación de Ansible
En esta revisión, instalará Ansible en workstation, lo usará como nodo de control y lo
configurará para las conexiones con los hosts administrados servera y serverb. Usar
comandos ad hoc para realizar acciones en hosts administrados.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Instalar Ansible.

• Usar comandos ad hoc para realizar acciones en hosts administrados.

Instrucciones
Instale y configure Ansible en workstation. Demuestre que puede construir los comandos
ad hoc especificados en la lista de criterios para modificar los hosts administrados y verifique
que las modificaciones funcionen según lo esperado:

• Instale Ansible en workstation de modo que se pueda usar como nodo de control.

• En el nodo de control, cree un archivo de inventario, /home/student/review-


deploy/inventory, que contenga un grupo denominado dev. Este grupo debe
estar compuesto por los hosts administrados servera.lab.example.com y
serverb.lab.example.com.

• Cree el archivo de configuración de Ansible en /home/student/review-deploy/


ansible.cfg. El archivo de configuración debe apuntar al archivo de inventario /home/
student/review-deploy/inventory.

• Ejecute un comando ad hoc con escalamiento de privilegios para modificar el contenido


del archivo /etc/motd en servera y serverb de modo que contengan la cadena
Managed by Ansible\n. Use devops como usuario remoto.

• Ejecute un comando ad hoc para verificar que el contenido del archivo /etc/motd en
servera y serverb sea idéntico.

Evaluación
En workstation, ejecute el comando lab review-deploy grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el
comando hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab review-deploy grade

Finalizar
En workstation, ejecute el comando lab review-deploy finish para limpiar este ejercicio.

RH294-RHEL8.0-es-1-20200501 479
capítulo 11 | Revisión completa: Automation with Ansible

[student@workstation ~]$ lab review-deploy finish

Esto concluye el trabajo de laboratorio.

480 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Solución

Implementación de Ansible
En esta revisión, instalará Ansible en workstation, lo usará como nodo de control y lo
configurará para las conexiones con los hosts administrados servera y serverb. Usar
comandos ad hoc para realizar acciones en hosts administrados.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Instalar Ansible.

• Usar comandos ad hoc para realizar acciones en hosts administrados.

Instrucciones
Instale y configure Ansible en workstation. Demuestre que puede construir los comandos
ad hoc especificados en la lista de criterios para modificar los hosts administrados y verifique
que las modificaciones funcionen según lo esperado:

• Instale Ansible en workstation de modo que se pueda usar como nodo de control.

• En el nodo de control, cree un archivo de inventario, /home/student/review-


deploy/inventory, que contenga un grupo denominado dev. Este grupo debe
estar compuesto por los hosts administrados servera.lab.example.com y
serverb.lab.example.com.

• Cree el archivo de configuración de Ansible en /home/student/review-deploy/


ansible.cfg. El archivo de configuración debe apuntar al archivo de inventario /home/
student/review-deploy/inventory.

• Ejecute un comando ad hoc con escalamiento de privilegios para modificar el contenido


del archivo /etc/motd en servera y serverb de modo que contengan la cadena
Managed by Ansible\n. Use devops como usuario remoto.

• Ejecute un comando ad hoc para verificar que el contenido del archivo /etc/motd en
servera y serverb sea idéntico.

1. Inicie sesión en workstation como student con la contraseña student.


En workstation, ejecute el comando lab review-deploy start. Este script garantiza
que se pueda acceder a los hosts administrados, servera y serverb, en la red. El script
crea un subdirectorio para el trabajo de laboratorio con el nombre review-deploy en el
directorio de inicio del estudiante.

[student@workstation ~]$ lab review-deploy start

2. Instale Ansible en workstation de modo que se pueda usar como nodo de control.

RH294-RHEL8.0-es-1-20200501 481
capítulo 11 | Revisión completa: Automation with Ansible

[student@workstation ~]$ sudo yum install ansible


[sudo] password for student:
Loaded plugins: langpacks, search-disabled-repos
Resolving Dependencies
--> Running transaction check
...output omitted...
Is this ok [y/d/N]: y
...output omitted...

3. En el nodo de control, cree un archivo de inventario, /home/student/review-deploy/


inventory, que contenga un grupo denominado dev. Este grupo debe estar compuesto
por los hosts administrados servera.lab.example.com y serverb.lab.example.com.

[dev]
servera.lab.example.com
serverb.lab.example.com

4. Cree el archivo de configuración de Ansible en /home/student/review-deploy/


ansible.cfg. El archivo de configuración debe hacer referencia al archivo de inventario /
home/student/review-deploy/inventory.
Agregue las siguientes entradas para configurar el archivo de inventario ./inventory como
la fuente de inventario. Guarde los cambios y salga del editor de texto.

[defaults]
inventory=./inventory

5. Ejecute un comando ad hoc con aumento de privilegios para modificar el contenido del
archivo /etc/motd en servera y serverb para que contengan la cadena Managed by
Ansible\n. Use devops como usuario remoto.

[student@workstation review-deploy]$ ansible dev -m copy \


> -a 'content="Managed by Ansible\n" dest=/etc/motd' -b -u devops
servera.lab.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:etc_t:s0",
"size": 19,
"src": "/home/devops/.ansible/tmp/...output omitted...",
"state": "file",
"uid": 0
}
serverb.lab.example.com | CHANGED => {
"ansible_facts": {

482 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
"dest": "/etc/motd",
"gid": 0,
"group": "root",
"md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:etc_t:s0",
"size": 19,
"src": "/home/devops/.ansible/tmp/...output omitted...",
"state": "file",
"uid": 0
}

6. Ejecute un comando ad hoc para verificar que el contenido del archivo /etc/motd en
servera y serverb sean idénticos.

[student@workstation review-deploy]$ ansible dev -m command -a "cat /etc/motd"


servera.lab.example.com | CHANGED | rc=0 >>
Managed by Ansible

serverb.lab.example.com | CHANGED | rc=0 >>


Managed by Ansible

Evaluación
En workstation, ejecute el comando lab review-deploy grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el
comando hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab review-deploy grade

Finalizar
En workstation, ejecute el comando lab review-deploy finish para limpiar este ejercicio.

[student@workstation ~]$ lab review-deploy finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 483
capítulo 11 | Revisión completa: Automation with Ansible

Trabajo de laboratorio

Creación de guías
En esta revisión, creará tres guías en el directorio de proyecto de Ansible, /home/student/
review-playbooks. Una guía garantizará que lftp se instale en sistemas que deberían
ser clientes FTP, una guía garantizará que vsftpd se instale y se configure en sistemas que
deberían ser servidores FTP, y otra guía (site.yml) ejecutará las otras dos guías.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Crear y ejecutar guías para realizar tareas en hosts administrados.

• Usar plantillas, variables y manejadores Jinja2 en las guías.

Instrucciones
Cree un inventario estático en review-playbooks/inventory con
serverc.lab.example.com en el grupo ftpclients, y serverb.lab.example.com
y serverd.lab.example.com en el grupo ftpservers. Cree un archivo review-
playbooks/ansible.cfg que configure su proyecto de Ansible para usar este inventario.
Tal vez le sea útil consultar el archivo /etc/ansible/ansible.cfg del sistema para
obtener ayuda con la sintaxis.

Configure su proyecto de Ansible para conectarse con hosts en el inventario con el usuario
remoto, devops, y el método sudo para el método de escalamiento de privilegios. Tiene
claves SSH para iniciar sesión como devops ya configuradas. El usuario devops no necesita
una contraseña para el escalamiento de privilegios con sudo.

Cree una guía denominada ftpclients.yml en el directorio review-playbooks que


contenga una reproducción que apunte a los hosts en el grupo de inventario ftpclients.
La guía debe garantizar que el paquete lftp esté instalado.

Cree una segunda guía denominada ansible-vsftpd.yml en el directorio review-


playbooks que contenga una reproducción que apunte a los hosts en el grupo de
inventario ftpservers. Debe cumplir los siguientes requisitos:

• Tiene un archivo de configuración para vsftpd generado desde una plantilla Jinja2. Cree
un directorio para las plantillas, review-playbooks/templates, y copie el archivo
vsftpd.conf.j2 provisto. Cree el directorio review-playbooks/vars. Copie el
archivo defaults-template.yml, que contiene la configuración predeterminada de
las variables usadas para completar esa plantilla cuando se implementa, en el directorio
review-playbooks/vars.

• Cree un archivo de variables, review-playbooks/vars/vars.yml, que establezca tres


variables:

Variable Valor

vsftpd_package vsftpd

vsftpd_service vsftpd

484 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Variable Valor

vsftpd_config_file /etc/vsftpd/vsftpd.conf

• En su guía ansible-vsftpd.yml, use vars_files para incluir los archivos de variables


de su reproducción en el directorio review-playbooks/vars.

• En la reproducción ansible-vsftpd.yml, cree tareas que:

1. Garanticen que el paquete detallado por la variable {{ vsftpd_package }} esté


instalado.

2. Garanticen que el servicio detallado por la variable {{ vsftpd_service }} esté


iniciado y habilitado para iniciarse en el momento del arranque.

3. Usen el módulo template para implementar la plantilla templates/


vsftpd.conf.j2 en la ubicación definida por la variable
{{ vsftpd_config_file }}. El archivo debe ser propiedad del usuario root,
el grupo root, tener permisos de archivos octales 0600 y un tipo de SELinux de
etc_t. Notifiquen a un manejador que reinicie vsftpd si esta tarea provoca un
cambio.

4. Garanticen que el paquete firewalld esté instalado y que el servicio esté iniciado
y habilitado. Garanticen que firewalld se haya configurado para permitir las
conexiones de forma inmediata y permanente con el servicio ftp. El intervalo de
puertos temporales para las conexiones pasivas de datos de FTP se ha establecido en
21000-21020 TCP. También deberá permitir este intervalo a través del cortafuegos.

• En su guía ansible-vsftpd.yml, cree un manejador para reiniciar los servicios


detallados por la variable {{ vsftpd_service }} cuando se le notifica.

Cree una tercera guía denominada site.yml en el directorio review-playbooks. Esta


guía solo debe importar las otras dos guías.

Siga las prácticas recomendadas sobre guías al asignar nombres a todas sus reproducciones
y tareas. Escriba guías con los módulos adecuados y asegúrese de que se puedan volver a
ejecutar de forma segura. Las guías no deberían realizar cambios innecesarios a los sistemas.

Use el comando ansible-doc para ayudarlo a buscar módulos e información sobre cómo
usarlos.

Cuando termine, use ansible-playbook site.yml para verificar su trabajo antes de


ejecutar el script de calificación. También puede ejecutar las guías individuales de forma
separada para asegurarse de que funcionen.

Importante
Si tiene problemas con su guía site.yml, asegúrese de que ansible-
vsftpd.yml y ftpclients.yml tengan una sangría uniforme.

RH294-RHEL8.0-es-1-20200501 485
capítulo 11 | Revisión completa: Automation with Ansible

Evaluación
Como usuario student en workstation, ejecute el comando lab review-playbooks
grade para confirmar que ha realizado correctamente este ejercicio. Corrija los errores
informados y vuelva a ejecutar el script hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab review-playbooks grade

Finalizar
Ejecute el comando lab review-playbooks finish para limpiar las tareas del trabajo de
laboratorio en serverb, serverc y serverd.

[student@workstation ~]$ lab review-playbooks finish

Esto concluye el trabajo de laboratorio.

486 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Solución

Creación de guías
En esta revisión, creará tres guías en el directorio de proyecto de Ansible, /home/student/
review-playbooks. Una guía garantizará que lftp se instale en sistemas que deberían
ser clientes FTP, una guía garantizará que vsftpd se instale y se configure en sistemas que
deberían ser servidores FTP, y otra guía (site.yml) ejecutará las otras dos guías.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Crear y ejecutar guías para realizar tareas en hosts administrados.

• Usar plantillas, variables y manejadores Jinja2 en las guías.

Instrucciones
Cree un inventario estático en review-playbooks/inventory con
serverc.lab.example.com en el grupo ftpclients, y serverb.lab.example.com
y serverd.lab.example.com en el grupo ftpservers. Cree un archivo review-
playbooks/ansible.cfg que configure su proyecto de Ansible para usar este inventario.
Tal vez le sea útil consultar el archivo /etc/ansible/ansible.cfg del sistema para
obtener ayuda con la sintaxis.

Configure su proyecto de Ansible para conectarse con hosts en el inventario con el usuario
remoto, devops, y el método sudo para el método de escalamiento de privilegios. Tiene
claves SSH para iniciar sesión como devops ya configuradas. El usuario devops no necesita
una contraseña para el escalamiento de privilegios con sudo.

Cree una guía denominada ftpclients.yml en el directorio review-playbooks que


contenga una reproducción que apunte a los hosts en el grupo de inventario ftpclients.
La guía debe garantizar que el paquete lftp esté instalado.

Cree una segunda guía denominada ansible-vsftpd.yml en el directorio review-


playbooks que contenga una reproducción que apunte a los hosts en el grupo de
inventario ftpservers. Debe cumplir los siguientes requisitos:

• Tiene un archivo de configuración para vsftpd generado desde una plantilla Jinja2. Cree
un directorio para las plantillas, review-playbooks/templates, y copie el archivo
vsftpd.conf.j2 provisto. Cree el directorio review-playbooks/vars. Copie el
archivo defaults-template.yml, que contiene la configuración predeterminada de
las variables usadas para completar esa plantilla cuando se implementa, en el directorio
review-playbooks/vars.

• Cree un archivo de variables, review-playbooks/vars/vars.yml, que establezca tres


variables:

Variable Valor

vsftpd_package vsftpd

vsftpd_service vsftpd

RH294-RHEL8.0-es-1-20200501 487
capítulo 11 | Revisión completa: Automation with Ansible

Variable Valor

vsftpd_config_file /etc/vsftpd/vsftpd.conf

• En su guía ansible-vsftpd.yml, use vars_files para incluir los archivos de variables


de su reproducción en el directorio review-playbooks/vars.

• En la reproducción ansible-vsftpd.yml, cree tareas que:

1. Garanticen que el paquete detallado por la variable {{ vsftpd_package }} esté


instalado.

2. Garanticen que el servicio detallado por la variable {{ vsftpd_service }} esté


iniciado y habilitado para iniciarse en el momento del arranque.

3. Usen el módulo template para implementar la plantilla templates/


vsftpd.conf.j2 en la ubicación definida por la variable
{{ vsftpd_config_file }}. El archivo debe ser propiedad del usuario root,
el grupo root, tener permisos de archivos octales 0600 y un tipo de SELinux de
etc_t. Notifiquen a un manejador que reinicie vsftpd si esta tarea provoca un
cambio.

4. Garanticen que el paquete firewalld esté instalado y que el servicio esté iniciado
y habilitado. Garanticen que firewalld se haya configurado para permitir las
conexiones de forma inmediata y permanente con el servicio ftp. El intervalo de
puertos temporales para las conexiones pasivas de datos de FTP se ha establecido en
21000-21020 TCP. También deberá permitir este intervalo a través del cortafuegos.

• En su guía ansible-vsftpd.yml, cree un manejador para reiniciar los servicios


detallados por la variable {{ vsftpd_service }} cuando se le notifica.

Cree una tercera guía denominada site.yml en el directorio review-playbooks. Esta


guía solo debe importar las otras dos guías.

Siga las prácticas recomendadas sobre guías al asignar nombres a todas sus reproducciones
y tareas. Escriba guías con los módulos adecuados y asegúrese de que se puedan volver a
ejecutar de forma segura. Las guías no deberían realizar cambios innecesarios a los sistemas.

Use el comando ansible-doc para ayudarlo a buscar módulos e información sobre cómo
usarlos.

Cuando termine, use ansible-playbook site.yml para verificar su trabajo antes de


ejecutar el script de calificación. También puede ejecutar las guías individuales de forma
separada para asegurarse de que funcionen.

Importante
Si tiene problemas con su guía site.yml, asegúrese de que ansible-
vsftpd.yml y ftpclients.yml tengan una sangría uniforme.

1. Inicie sesión en workstation como student con la contraseña student.


En workstation, ejecute el comando lab review-playbooks start.

488 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

[student@workstation ~]$ lab review-playbooks start

2. Como usuario student en workstation, cree el archivo de inventario /home/student/


review-playbooks/inventory, que contenga serverc.lab.example.com en el
grupo ftpclients, y serverb.lab.example.com y serverd.lab.example.com en el
grupo ftpservers.

2.1. Cambie el directorio al directorio del proyecto de Ansible, /home/student/review-


playbooks, creado por el script de configuración.

[student@workstation ~]$ cd ~/review-playbooks

2.2. Complete el archivo inventory con las siguientes entradas; luego, guárdelo y salga.

[ftpservers]
serverb.lab.example.com
serverd.lab.example.com

[ftpclients]
serverc.lab.example.com

3. Cree el archivo de configuración Ansible, /home/student/review-playbooks/


ansible.cfg, y complételo con las entradas necesarias para cumplir con estos requisitos:

• Configure el proyecto Ansible para usar el inventario recién creado

• Conéctese con hosts administrados con el usuario devops

• Utilice el escalamiento de privilegios usando sudo como el usuario root

• Escalar privilegios para cada tarea de manera predeterminada

[defaults]
remote_user = devops
inventory = ./inventory

[privilege_escalation]
become_user = root
become_method = sudo
become = true

4. Cree la guía, /home/student/review-playbooks/ftpclients.yml, que contenga una


reproducción que apunte a los hosts en el grupo de inventario ftpclients y asegúrese de
que el paquete lftp esté instalado.

---
- name: Ensure FTP Client Configuration
hosts: ftpclients

tasks:
- name: latest version of lftp is installed

RH294-RHEL8.0-es-1-20200501 489
capítulo 11 | Revisión completa: Automation with Ansible

yum:
name: lftp
state: latest

5. Coloque el archivo de configuración vsftpd proporcionado, vsftpd.conf.j2, en el


subdirectorio templates.

5.1. Cree el subdirectorio templates.

[student@workstation review-playbooks]$ mkdir -v templates


mkdir: created directory 'templates'

5.2. Mueva el archivo vsftpd.conf.j2 al subdirectorio templates creado


recientemente.

[student@workstation review-playbooks]$ mv -v vsftpd.conf.j2 templates/


renamed 'vsftpd.conf.j2' -> 'templates/vsftpd.conf.j2'

6. Coloque el archivo defaults-template.yml provisto en el subdirectorio vars.

6.1. Cree el subdirectorio vars.

[student@workstation review-playbooks]$ mkdir -v vars


mkdir: created directory 'vars'

6.2. Mueva el archivo defaults-template.yml al subdirectorio vars creado


recientemente.

[student@workstation review-playbooks]$ mv -v defaults-template.yml vars/


renamed 'defaults-template.yml' -> 'vars/defaults-template.yml'

7. Cree un archivo de definición de variables vars.yml en el subdirectorio vars para definir


las siguientes tres variables y sus valores.

Variable Valor

vsftpd_package vsftpd

vsftpd_service vsftpd

vsftpd_config_file /etc/vsftpd/vsftpd.conf

vsftpd_package: vsftpd
vsftpd_service: vsftpd
vsftpd_config_file: /etc/vsftpd/vsftpd.conf

8. Con la plantilla Jinja2 y los archivos de definición de variables creados anteriormente, cree
una segunda guía, /home/student/review-playbooks/ansible-vsftpd.yml, para
configurar el servicio vsftpd en los hosts dentro del grupo de inventario ftpservers.

490 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

---
- name: FTP server is installed
hosts:
- ftpservers
vars_files:
- vars/defaults-template.yml
- vars/vars.yml

tasks:
- name: Packages are installed
yum:
name: "{{ vsftpd_package }}"
state: present

- name: Ensure service is started


service:
name: "{{ vsftpd_service }}"
state: started
enabled: true

- name: Configuration file is installed


template:
src: templates/vsftpd.conf.j2
dest: "{{ vsftpd_config_file }}"
owner: root
group: root
mode: 0600
setype: etc_t
notify: restart vsftpd

- name: firewalld is installed


yum:
name: firewalld
state: present

- name: firewalld is started and enabled


service:
name: firewalld
state: started
enabled: yes

- name: FTP port is open


firewalld:
service: ftp
permanent: true
state: enabled
immediate: yes

- name: FTP passive data ports are open


firewalld:
port: 21000-21020/tcp
permanent: yes
state: enabled

RH294-RHEL8.0-es-1-20200501 491
capítulo 11 | Revisión completa: Automation with Ansible

immediate: yes

handlers:
- name: restart vsftpd
service:
name: "{{ vsftpd_service }}"
state: restarted

9. Cree una tercera guía, /home/student/review-playbooks/site.yml, e incluya las


reproducciones de las dos guías creadas previamente, ftpclients.yml y ansible-
vsftpd.yml.

---
# FTP Servers playbook
- import_playbook: ansible-vsftpd.yml

# FTP Clients playbook


- import_playbook: ftpclients.yml

10. Ejecute la guía /home/student/review-playbooks/site.yml para verificar que realice


las tareas deseadas en los hosts administrados.

[student@workstation review-playbooks]$ ansible-playbook site.yml

Evaluación
Como usuario student en workstation, ejecute el comando lab review-playbooks
grade para confirmar que ha realizado correctamente este ejercicio. Corrija los errores
informados y vuelva a ejecutar el script hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab review-playbooks grade

Finalizar
Ejecute el comando lab review-playbooks finish para limpiar las tareas del trabajo de
laboratorio en serverb, serverc y serverd.

[student@workstation ~]$ lab review-playbooks finish

Esto concluye el trabajo de laboratorio.

492 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Trabajo de laboratorio

Creación de roles y uso de inventario


dinámico
En esta revisión, convertirá la guía ansible-vsftpd.yml en un rol y, luego, usará ese rol
en una nueva guía que también ejecutará algunas tareas adicionales. Además, instalará y
utilizará un script de inventario dinámico, que se le proporcionará.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Crear un rol para configurar el servicio vsftpd mediante tareas de una guía existente.

• Incluir un rol en una guía y ejecutar la guía.

• Usar un inventario dinámico cuando se ejecuta una guía.

Instrucciones
Configure su proyecto de Ansible para usar el script de inventario dinámico
crinventory.py y el archivo de inventario estático inventory.

Convierta la guía ansible-vsftpd.yml en el rol ansible-vsftpd, como se especifica a


continuación:

• Use el comando ansible-galaxy para crear la estructura del directorio para el rol
ansible-vsftpd en el directorio review-roles/roles de su proyecto de Ansible.

• El archivo defaults-template.yml contiene variables predeterminadas para el rol.


Mueva este archivo a una ubicación adecuada en la estructura de directorios del rol.

• El archivo vars.yml contiene variables regulares para el rol. Mueva este archivo a una
ubicación adecuada en la estructura de directorios del rol.

• Mueva la plantilla vsftpd.conf.j2 a una ubicación adecuada en la estructura de


directorios del rol.

• Asegúrese de que las tareas y los manejadores en la guía ansible-vsftpd.yml se


instalen correctamente en el rol.

• Edite el archivo meta/main.yml del rol para establecer los campos autor, descripción y
licencia (use BSD para la licencia). Edite el archivo README.md según sea necesario para
alcanzar la integridad.

• Elimine los subdirectorios en el rol que no esté usando.

Cree una nueva guía, vsftpd-configure.yml, en el directorio review-roles de la


siguiente manera.

• La guía debería contener una reproducción que apunte a los hosts en el grupo de
inventario ftpservers.

• La reproducción debería establecer las siguientes variables:

RH294-RHEL8.0-es-1-20200501 493
capítulo 11 | Revisión completa: Automation with Ansible

Variable Valor

vsftpd_anon_root /mnt/share

vsftpd_local_root /mnt/share

• La reproducción debería aplicar el rol ansible-vsftpd.

• La reproducción debe incluir las siguientes tareas en el orden especificado:

1. Use el módulo command para crear una etiqueta de disco GPT en /dev/vdb, que
comience a 1 MiB del inicio del dispositivo y finalice al final del dispositivo. Use el
comando ansible-doc para obtener información sobre cómo usar el argumento
creates a fin de omitir esta tarea si ya se ha creado /dev/vdb1. Esto evita la
repartición destructiva del dispositivo. Use el siguiente comando para crear la
partición: parted --script /dev/vdb mklabel gpt mkpart primary 1MiB
100%

2. Asegúrese de que el directorio /mnt/share exista para usar como punto de montaje.

3. Use ansible-doc -l para encontrar un módulo que pueda crear un sistema de


archivos en un dispositivo de bloque. Use ansible-doc para obtener información
sobre cómo usar este módulo. Agregue una tarea a la guía que usa este módulo
para crear un sistema de archivos XFS en /dev/vdb1. No fuerce la creación de ese
sistema de archivos si ya existe uno.

4. Agregue una tarea para asegurarse de que /etc/fstab monte el dispositivo /dev/
vdb1 en /mnt/share, en el arranque, y que esté actualmente montado. Use el
comando ansible-doc para encontrar un módulo que pueda montar el dispositivo.
Si esta tarea tiene un resultado cambiado, notifique al manejador del rol ansible-
vsftpd que reinicia vsftpd.

5. Agregue una tarea que garantice que el directorio /mnt/share sea propiedad
del usuario root y del grupo root, que tenga un tipo de SELinux definido en la
variable {{ vsftpd_setype }} desde el rol y que tenga permisos octales de 0755.
Esta tarea debe ejecutarse después de que se monte el sistema de archivos para
establecer los permisos en el sistema de archivos montado y no en el directorio del
punto de montaje del marcador de posición.

6. Asegúrese de que exista un archivo con el nombre README en el directorio


especificado por {{ vsftpd_anon_root }} que contenga la cadena Welcome
to the FTP server at serverX.lab.example.com (Bienvenido al servidor
FTP en serverX.lab.example.com), donde serverX.lab.example.com es el
nombre de host plenamente calificado real para ese servidor. Este archivo debe
tener permisos octales de 0644 y el tipo de SELinux especificado por la variable
{{ vsftpd_setype }}. (Consejo: observe los módulos copy o template y los
datos de Ansible disponibles para resolver este problema).

494 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Importante
Tal vez le resulte útil depurar su rol probándolo en una guía que no contenga
las tareas o variables adicionales de la guía detalladas anteriormente, sino que
en su lugar contenga una reproducción que apunte a los hosts en el grupo
ftpservers, y aplique el rol.

Una vez que haya confirmado que una guía simplificada que usa solo el rol
funciona igual que la guía ansible-vsftpd.yml original, podrá crear la
guía vsftpd-configure.yml completa mediante la adición de variables y
tareas adicionales especificadas anteriormente.

Cambie la guía review-roles/site.yml para usar la nueva guía vsftpd-


configure.yml en lugar de ansible-vsftpd.yml.

Siga las prácticas recomendadas sobre guías al asignar nombres a todas sus reproducciones
y tareas. Escriba guías con los módulos adecuados y asegúrese de que se puedan volver a
ejecutar de forma segura. Las guías no deberían realizar cambios innecesarios a los sistemas.

Cuando termine, use ansible-playbook site.yml para verificar su trabajo antes de


ejecutar el script de calificación. También puede ejecutar las guías individuales de forma
separada para asegurarse de que funcionen.

Importante
Si tiene problemas con su guía site.yml, asegúrese de que vsftpd-
configure.yml y ftpclients.yml tengan una sangría uniforme.

Evaluación
En workstation, ejecute el comando lab review-roles grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

[student@workstation ~]$ lab review-roles grade

Finalizar
Ejecute el comando lab review-roles finish para limpiar las tareas del trabajo de
laboratorio en servera y serverb.

[student@workstation ~]$ lab review-roles finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 495
capítulo 11 | Revisión completa: Automation with Ansible

Solución

Creación de roles y uso de inventario


dinámico
En esta revisión, convertirá la guía ansible-vsftpd.yml en un rol y, luego, usará ese rol
en una nueva guía que también ejecutará algunas tareas adicionales. Además, instalará y
utilizará un script de inventario dinámico, que se le proporcionará.

Resultados
Usted deberá ser capaz de realizar lo siguiente:

• Crear un rol para configurar el servicio vsftpd mediante tareas de una guía existente.

• Incluir un rol en una guía y ejecutar la guía.

• Usar un inventario dinámico cuando se ejecuta una guía.

Instrucciones
Configure su proyecto de Ansible para usar el script de inventario dinámico
crinventory.py y el archivo de inventario estático inventory.

Convierta la guía ansible-vsftpd.yml en el rol ansible-vsftpd, como se especifica a


continuación:

• Use el comando ansible-galaxy para crear la estructura del directorio para el rol
ansible-vsftpd en el directorio review-roles/roles de su proyecto de Ansible.

• El archivo defaults-template.yml contiene variables predeterminadas para el rol.


Mueva este archivo a una ubicación adecuada en la estructura de directorios del rol.

• El archivo vars.yml contiene variables regulares para el rol. Mueva este archivo a una
ubicación adecuada en la estructura de directorios del rol.

• Mueva la plantilla vsftpd.conf.j2 a una ubicación adecuada en la estructura de


directorios del rol.

• Asegúrese de que las tareas y los manejadores en la guía ansible-vsftpd.yml se


instalen correctamente en el rol.

• Edite el archivo meta/main.yml del rol para establecer los campos autor, descripción y
licencia (use BSD para la licencia). Edite el archivo README.md según sea necesario para
alcanzar la integridad.

• Elimine los subdirectorios en el rol que no esté usando.

Cree una nueva guía, vsftpd-configure.yml, en el directorio review-roles de la


siguiente manera.

• La guía debería contener una reproducción que apunte a los hosts en el grupo de
inventario ftpservers.

• La reproducción debería establecer las siguientes variables:

496 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Variable Valor

vsftpd_anon_root /mnt/share

vsftpd_local_root /mnt/share

• La reproducción debería aplicar el rol ansible-vsftpd.

• La reproducción debe incluir las siguientes tareas en el orden especificado:

1. Use el módulo command para crear una etiqueta de disco GPT en /dev/vdb, que
comience a 1 MiB del inicio del dispositivo y finalice al final del dispositivo. Use el
comando ansible-doc para obtener información sobre cómo usar el argumento
creates a fin de omitir esta tarea si ya se ha creado /dev/vdb1. Esto evita la
repartición destructiva del dispositivo. Use el siguiente comando para crear la
partición: parted --script /dev/vdb mklabel gpt mkpart primary 1MiB
100%

2. Asegúrese de que el directorio /mnt/share exista para usar como punto de montaje.

3. Use ansible-doc -l para encontrar un módulo que pueda crear un sistema de


archivos en un dispositivo de bloque. Use ansible-doc para obtener información
sobre cómo usar este módulo. Agregue una tarea a la guía que usa este módulo
para crear un sistema de archivos XFS en /dev/vdb1. No fuerce la creación de ese
sistema de archivos si ya existe uno.

4. Agregue una tarea para asegurarse de que /etc/fstab monte el dispositivo /dev/
vdb1 en /mnt/share, en el arranque, y que esté actualmente montado. Use el
comando ansible-doc para encontrar un módulo que pueda montar el dispositivo.
Si esta tarea tiene un resultado cambiado, notifique al manejador del rol ansible-
vsftpd que reinicia vsftpd.

5. Agregue una tarea que garantice que el directorio /mnt/share sea propiedad
del usuario root y del grupo root, que tenga un tipo de SELinux definido en la
variable {{ vsftpd_setype }} desde el rol y que tenga permisos octales de 0755.
Esta tarea debe ejecutarse después de que se monte el sistema de archivos para
establecer los permisos en el sistema de archivos montado y no en el directorio del
punto de montaje del marcador de posición.

6. Asegúrese de que exista un archivo con el nombre README en el directorio


especificado por {{ vsftpd_anon_root }} que contenga la cadena Welcome
to the FTP server at serverX.lab.example.com (Bienvenido al servidor
FTP en serverX.lab.example.com), donde serverX.lab.example.com es el
nombre de host plenamente calificado real para ese servidor. Este archivo debe
tener permisos octales de 0644 y el tipo de SELinux especificado por la variable
{{ vsftpd_setype }}. (Consejo: observe los módulos copy o template y los
datos de Ansible disponibles para resolver este problema).

RH294-RHEL8.0-es-1-20200501 497
capítulo 11 | Revisión completa: Automation with Ansible

Importante
Tal vez le resulte útil depurar su rol probándolo en una guía que no contenga
las tareas o variables adicionales de la guía detalladas anteriormente, sino que
en su lugar contenga una reproducción que apunte a los hosts en el grupo
ftpservers, y aplique el rol.

Una vez que haya confirmado que una guía simplificada que usa solo el rol
funciona igual que la guía ansible-vsftpd.yml original, podrá crear la
guía vsftpd-configure.yml completa mediante la adición de variables y
tareas adicionales especificadas anteriormente.

Cambie la guía review-roles/site.yml para usar la nueva guía vsftpd-


configure.yml en lugar de ansible-vsftpd.yml.

Siga las prácticas recomendadas sobre guías al asignar nombres a todas sus reproducciones
y tareas. Escriba guías con los módulos adecuados y asegúrese de que se puedan volver a
ejecutar de forma segura. Las guías no deberían realizar cambios innecesarios a los sistemas.

Cuando termine, use ansible-playbook site.yml para verificar su trabajo antes de


ejecutar el script de calificación. También puede ejecutar las guías individuales de forma
separada para asegurarse de que funcionen.

Importante
Si tiene problemas con su guía site.yml, asegúrese de que vsftpd-
configure.yml y ftpclients.yml tengan una sangría uniforme.

1. Inicie sesión en workstation como student con la contraseña student.


En workstation, ejecute el comando lab review-roles start. Este script garantiza
que se pueda acceder a los hosts remotos en la red. Este script también verifica que Ansible
esté instalado en workstation, crea una estructura de directorio para el entorno de
laboratorio e instala los archivos de laboratorio necesarios.

[student@workstation ~]$ lab review-roles start

2. Cambie al directorio de trabajo review-roles. Configure el proyecto de Ansible para


usar el archivo de inventario dinámico crinventory.py y el archivo de inventario estático
inventory. Verifique la configuración del inventario usando el comando ansible-
inventory.

2.1. Coloque el archivo de inventario estático en un directorio llamado inventory.

[student@workstation ~]$ cd ~/review-roles


[student@workstation review-roles]$ mv -v inventory inventory.tmp
renamed 'inventory' -> 'inventory.tmp'
[student@workstation review-roles]$ mkdir -v inventory
mkdir: created directory 'inventory'
[student@workstation review-roles]$ mv -v inventory.tmp inventory/inventory
renamed 'inventory.tmp' -> 'inventory/inventory'

498 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

2.2. Agregue el script de inventario dinámico al directorio de inventario. Asegúrese de que


el script sea ejecutable.

[student@workstation review-roles]$ chmod 755 -v crinventory.py


mode of 'crinventory.py' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)
[student@workstation review-roles]$ mv -v crinventory.py inventory/
renamed 'crinventory.py' -> 'inventory/crinventory.py'

2.3. Configure el directorio inventory como la fuente de archivos de inventario para el


proyecto.
La sección [defaults] del archivo ansible.cfg se ve así:

[defaults]
remote_user=devops
inventory=./inventory

2.4. Use el comando ansible-inventory para verificar la configuración del inventario


del proyecto:

[student@workstation review-roles]$ ansible-inventory --list all


{
"_meta": {
"hostvars": {
"servera.lab.example.com": {},
"serverb.lab.example.com": {},
"serverc.lab.example.com": {},
"serverd.lab.example.com": {}
}
},
"all": {
"children": [
"ftpclients",
"ftpservers",
"ungrouped"
]
},
"ftpclients": {
"hosts": [
"servera.lab.example.com",
"serverc.lab.example.com"
]
},
"ftpservers": {
"hosts": [
"serverb.lab.example.com",
"serverd.lab.example.com"
]
}
}

3. Convierta la guía ansible-vsftpd.yml en el rol ansible-vsftpd.

3.1. Cree el subdirectorio roles.

RH294-RHEL8.0-es-1-20200501 499
capítulo 11 | Revisión completa: Automation with Ansible

[student@workstation review-roles]$ mkdir -v roles


mkdir: created directory 'roles'

3.2. Con ansible-galaxy, cree la estructura del directorio para el nuevo rol ansible-
vsftpd en el subdirectorio roles.

[student@workstation review-roles]$ cd roles


[student@workstation roles]$ ansible-galaxy init ansible-vsftpd
- ansible-vsftpd was created successfully
[student@workstation roles]$ cd ..
[student@workstation review-roles]$

3.3. Con tree, verifique la estructura del directorio creada para el nuevo rol.

[student@workstation review-roles]$ tree roles


roles
└── ansible-vsftpd
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

9 directories, 8 files

3.4. Reemplace el archivo roles/ansible-vsftpd/defaults/main.yml con las


definiciones de variable en el archivo defaults-template.yml.

[student@workstation review-roles]$ mv -v defaults-template.yml \


> roles/ansible-vsftpd/defaults/main.yml
renamed 'defaults-template.yml' -> 'roles/ansible-vsftpd/defaults/main.yml'

3.5. Reemplace el archivo roles/ansible-vsftpd/vars/main.yml con las


definiciones de variable en el archivo vars.yml.

[student@workstation review-roles]$ mv -v vars.yml \


> roles/ansible-vsftpd/vars/main.yml
renamed 'vars.yml' -> 'roles/ansible-vsftpd/vars/main.yml'

500 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

3.6. Use el archivo templates/vsftpd.conf.j2 como plantilla para el rol ansible-


vsftpd.

[student@workstation review-roles]$ mv -v vsftpd.conf.j2 \


> roles/ansible-vsftpd/templates/
renamed 'vsftpd.conf.j2' -> 'roles/ansible-vsftpd/templates/vsftpd.conf.j2'

3.7. Copie las tareas de la guía ansible-vsftpd.yml al archivo roles/ansible-


vsftpd/tasks/main.yml. El valor de la palabra clave src en la tarea del módulo
template ya no necesita hacer referencia al subdirectorio templates. El archivo
roles/ansible-vsftpd/tasks/main.yml debe contener lo siguiente cuando
termine.

---
# tasks file for ansible-vsftpd
- name: Packages are installed
yum:
name: '{{ vsftpd_package }}'
state: present

- name: Ensure service is started


service:
name: '{{ vsftpd_service }}'
state: started
enabled: true

- name: Configuration file is installed


template:
src: vsftpd.conf.j2
dest: '{{ vsftpd_config_file }}'
owner: root
group: root
mode: '0600'
setype: etc_t
notify: restart vsftpd

- name: firewalld is installed


yum:
name: firewalld
state: present

- name: firewalld is started and enabled


service:
name: firewalld
state: started
enabled: yes

- name: FTP port is open


firewalld:
service: ftp
permanent: true
state: enabled
immediate: yes

RH294-RHEL8.0-es-1-20200501 501
capítulo 11 | Revisión completa: Automation with Ansible

- name: Passive FTP data ports allowed through the firewall


firewalld:
port: 21000-21020/tcp
permanent: yes
state: enabled
immediate: yes

3.8. Copie los manejadores de la guía ansible-vsftpd.yml al archivo roles/ansible-


vsftpd/handlers/main.yml. El archivo roles/ansible-vsftpd/handlers/
main.yml debe contener lo siguiente cuando termine.

---
# handlers file for ansible-vsftpd
- name: restart vsftpd
service:
name: "{{ vsftpd_service }}"
state: restarted

4. Actualice el contenido del archivo roles/ansible-vsftpd/meta/main.yml.

4.1. Cambie el valor de la entrada author (autor) a Red Hat Training.

author: Red Hat Training

4.2. Cambie el valor de la entrada description (descripción) a "example role for


RH294".

description: example role for RH294

4.3. Cambie el valor de la entrada company (empresa) a "Red Hat".

company: Red Hat

4.4. Cambie el valor de la entrada license: (licencia:) a "BSD".

license: BSD

5. Modifique el contenido del archivo roles/ansible-vsftpd/README.md de modo que


proporcione información pertinente relacionada con el rol. Después de la modificación, el
archivo deberá contener lo siguiente.

ansible-vsftpd
=========
Example ansible-vsftpd role from Red Hat's "Linux Automation" (RH294)
course.

Role Variables
--------------

* defaults/main.yml contains variables used to configure the vsftpd.conf template


* vars/main.yml contains the name of the vsftpd service, the name of the RPM
package, and the location of the service's configuration file

502 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

Dependencies
------------

None.

Example Playbook
----------------

- hosts: servers
roles:
- ansible-vsftpd

License
-------

BSD

Author Information
------------------

Red Hat ([email protected])

6. Elimine los directorios que no use del nuevo rol.

[student@workstation review-roles]$ rm -rvf roles/ansible-vsftpd/tests


removed 'roles/ansible-vsftpd/tests/inventory'
removed 'roles/ansible-vsftpd/tests/test.yml'
removed directory: 'roles/ansible-vsftpd/tests/'

7. Cree la nueva guía vsftpd-configure.yml. Debe contener lo siguiente.

---
- name: Install and configure vsftpd
hosts: ftpservers
vars:
vsftpd_anon_root: /mnt/share/
vsftpd_local_root: /mnt/share/

roles:
- ansible-vsftpd

tasks:

- name: /dev/vdb1 is partitioned


command: >
parted --script /dev/vdb mklabel gpt mkpart primary 1MiB 100%
args:
creates: /dev/vdb1

- name: XFS file system exists on /dev/vdb1


filesystem:
dev: /dev/vdb1

RH294-RHEL8.0-es-1-20200501 503
capítulo 11 | Revisión completa: Automation with Ansible

fstype: xfs
force: yes

- name: anon_root mount point exists


file:
path: '{{ vsftpd_anon_root }}'
state: directory

- name: /dev/vdb1 is mounted on anon_root


mount:
name: '{{ vsftpd_anon_root }}'
src: /dev/vdb1
fstype: xfs
state: mounted
dump: '1'
passno: '2'
notify: restart vsftpd

- name: Make sure permissions on mounted fs are correct


file:
path: '{{ vsftpd_anon_root }}'
owner: root
group: root
mode: '0755'
setype: "{{ vsftpd_setype }}"
state: directory

- name: Copy README to the ftp anon_root


copy:
dest: '{{ vsftpd_anon_root }}/README'
content: "Welcome to the FTP server at {{ ansible_fqdn }}\n"
setype: '{{ vsftpd_setype }}'

8. Cambie la guía site.yml para usar la guía vsftpd-configure.yml creada recientemente


en lugar de la guía ansible-vsftpd.yml.

---
# FTP Servers playbook
- import_playbook: vsftpd-configure.yml

# FTP Clients playbook


- import_playbook: ftpclients.yml

9. Ejecute la guía con ansible-playbook para verificar que la guía site.yml funcione
según lo planificado.

[student@workstation review-roles]$ ansible-playbook site.yml

Evaluación
En workstation, ejecute el comando lab review-roles grade para confirmar que ha
realizado correctamente este ejercicio. Corrija los errores informados y vuelva a ejecutar el script
hasta obtener un resultado satisfactorio.

504 RH294-RHEL8.0-es-1-20200501
capítulo 11 | Revisión completa: Automation with Ansible

[student@workstation ~]$ lab review-roles grade

Finalizar
Ejecute el comando lab review-roles finish para limpiar las tareas del trabajo de
laboratorio en servera y serverb.

[student@workstation ~]$ lab review-roles finish

Esto concluye el trabajo de laboratorio.

RH294-RHEL8.0-es-1-20200501 505
506 RH294-RHEL8.0-es-1-20200501
apéndice A

Temas suplementarios
Meta Investigar temas complementarios no incluidos
en el curso oficial.

RH294-RHEL8.0-es-1-20200501 507
apéndice A | Temas suplementarios

Examen de las opciones de configuración


de Ansible

Objetivos
Después de completar esta sección, debe poder usar ansible-config para descubrir e
investigar las opciones de configuración y para determinar qué opciones se han modificado desde
la configuración predeterminada.

Visualización de las opciones de configuración


Si desea averiguar qué opciones están disponibles en el archivo de configuración, use el comando
ansible-config list. Mostrará una lista exhaustiva de las opciones de configuración
disponibles y sus configuraciones predeterminadas. Esta lista puede variar según la versión de
Ansible que haya instalado y si tiene complementos de Ansible adicionales en su nodo de control.

Cada opción mostrada por ansible-config list tendrá un número de pares de claves/
valores asociado a ella. Estos pares de claves/valores proporcionan información sobre cómo
funciona esa opción. Por ejemplo, la opción ACTION_WARNINGS muestra los siguientes pares de
claves/valores:

Clave Valor Propósito

description [De manera predeterminada, Ansible Describe para qué


(descripción) emitirá una advertencia cuando es esta opción de
la reciba de una acción de tarea configuración.
(complemento de acción o módulo).
Para silenciar estas advertencias,
puede establecer esta configuración
en Falso].

type (tipo) boolean (booleano) Cuál es el tipo para


la opción: boolean
se refiere a un valor
verdadero-falso.

default true (verdadero) El valor predeterminado


(predeterminado) para esta opción.

version_added 2.5 La versión de Ansible


que agregó esta opción,
para compatibilidad con
versiones anteriores.

ini { key: action_warnings, ¿Qué sección del


section: defaults } archivo de inventario
tipo INI contiene esta
opción, y el nombre
de la opción en el
archivo de configuración
(action_warnings, en
la sección defaults)?

508 RH294-RHEL8.0-es-1-20200501
apéndice A | Temas suplementarios

Clave Valor Propósito

env ANSIBLE_ACTION_WARNINGS Si se establece esta


variable de entorno,
anulará cualquier
configuración de la
opción realizada en el
archivo de configuración.

Determinación de las opciones de configuración modificadas


Cuando trabaje con archivos de configuración, es posible que desee averiguar qué opciones se
han establecido en valores que son diferentes de los valores predeterminados incorporados.

Puedes hacer esto ejecutando el comando ansible-config dump -v -\-only-changed.


La opción -v muestra la ubicación del archivo ansible.cfg utilizado al procesar el comando. El
comando ansible-config sigue el mismo orden de precedencia mencionado anteriormente
para el comando ansible. La salida variará según la ubicación del archivo ansible.cfg y según
el directorio desde donde se ejecuta el comando ansible-config.

En el siguiente ejemplo, hay un solo archivo de configuración Ansible ubicado en /etc/ansible/


ansible.cfg. El comando ansible-config se ejecuta primero desde el directorio de inicio del
estudiante; luego, desde un directorio de trabajo con los mismos resultados:

[user@controlnode ~]$ ansible-config dump -v -\-only-changed Con/etc/ansible/


ansible.cfg como archivo config DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) =
[u'/etc/ansible/roles', u'/usr/share/ansible/roles'] [user@controlnode ~]$ cd /
home/student/workingdirectory [user@controlnode workingdirectory]$ ansible-
config dump -v -\-only-changed Con /etc/ansible/ansible.cfg como archivo config
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = [u'/etc/ansible/roles', u'/usr/
share/ansible/roles']

Sin embargo, si tiene un archivo ansible.cfg personalizado en su directorio de trabajo, el


mismo comando mostrará información basada en la ubicación desde donde se ejecuta y el archivo
ansible.cfg relacionado.

[user@controlnode ~]$ ansible-config dump -v -\-only-changed Con /etc/ansible/


ansible.cfg como archivo config DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) =
[u'/etc/ansible/roles', u'/usr/share/ansible/roles'] [user@controlnode ~]$ cd /
home/student/workingdirectory [user@controlnode workingdirectory]$ cat ansible.cfg
[defaults] inventory = ./inventory remote_user = devops [user@controlnode
workingdirectory]$ ansible-config dump -v -\-only-changed Con /home/student/
workingdirectory/ansible.cfg como archivo config DEFAULT_HOST_LIST(/home/student/
workingdirectory/ansible.cfg) = [u'/home/student/workingdirectory/inventory']
DEFAULT_REMOTE_USER(/home/student/workingdirectory/ansible.cfg) = devops

Referencias
Página del manual ansible-config(1)

Archivo de configuración: Documentación Ansible


https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html

RH294-RHEL8.0-es-1-20200501 509
510 RH294-RHEL8.0-es-1-20200501
apéndice B

Licencias de Ansible Lightbulb

RH294-RHEL8.0-es-1-20200501 511
apéndice B | Licencias de Ansible Lightbulb

Licencia de Ansible Lightbulb


Algunas partes de este curso se adaptaron del proyecto Ansible Lightbulb. El material original de
ese proyecto está disponible en https://github.com/ansible/lightbulb con la siguiente Licencia de
MIT:

Copyright 2017 Red Hat, Inc.

El aviso de copyright anterior y este aviso de permiso deberían incluirse en todas las copias o
partes sustanciales del software.

Por el presente, se otorga permiso gratuito a cualquier persona que obtenga una copia de este
software y los archivos de documentación asociados (el "Software") para trabajar en el software
sin restricciones, que incluyen, entre otras, el derecho de usar, copiar, modificar, fusionar, publicar,
distribuir, sublicenciar o vender copias del software, y permitir a personas a quienes se entrega el
software para esto, sujeto a las siguiente condiciones:

El aviso de copyright anterior y este aviso de permiso deberían incluirse en todas las copias o
partes sustanciales del software.

EL SOFTWARE SE PROPORCIONA "EN EL ESTADO EN EL QUE SE ENCUENTRA", SIN


GARANTÍA DE NINGÚN TIPO, NI EXPRESA NI IMPLÍCITA, INCLUIDAS, ENTRE OTRAS, LAS
GARANTÍAS DE COMERCIALIZACIÓN O CONVENIENCIA PARA UN PROPÓSITO PARTICULAR
Y DE NO INFRACCIÓN. EN NINGÚN CASO, LOS AUTORES O LOS TITULARES DEL
COPYRIGHT SERÁN RESPONSABLES POR RECLAMOS, DAÑOS U OTRA RESPONSABILIDAD,
YA SEA EN UNA ACCIÓN CONTRACTUAL, EXTRACONTRACTUAL O DE OTRO MODO, QUE
SURJAN DEL SOFTWARE O DE SU USO, O DE OTRAS OPERACIONES LLEVADAS A CABO
CON ÉL O EN CONEXIÓN CON ESTOS.

512 RH294-RHEL8.0-es-1-20200501

You might also like