Do417 2.8 Student Guide
Do417 2.8 Student Guide
The contents of this course and all its modules and related materials, including handouts to
audience members, are Copyright © 2019 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 e-mail training@redhat.com or phone toll-free (USA) +1 (866) 626-2994
or +1 (919) 754-3700.
Red Hat, Red Hat Enterprise Linux, the Shadowman 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.
The OpenStack® Word Mark and OpenStack Logo are either registered trademarks/service
marks or trademarks/service marks of the OpenStack Foundation, in the United States
and other countries and are used with the OpenStack Foundation's permission. We are not
affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack
community.
Introduction xi
Microsoft Windows Automation with Red Hat Ansible ................................................... xi
Orientation to the Classroom Environment ................................................................. xii
DO417-RHAE2.8-en-1-20200106 v
Guided Exercise: Implementing Handlers ................................................................. 267
Handling Task Failure ............................................................................................. 271
Guided Exercise: Handling Task Failure .................................................................... 276
Lab: Implementing Task Control .............................................................................. 281
Summary ............................................................................................................. 288
7. Deploying Files to Managed Hosts 289
Modifying and Transferring Files on Hosts ............................................................... 290
Guided Exercise: Modifying and Transferring Files on Hosts ....................................... 296
Templating Files with Jinja2 .................................................................................... 313
Guided Exercise: Templating Files with Jinja2 ........................................................... 318
Lab: Deploying Files to Managed Hosts .................................................................. 326
Summary ............................................................................................................. 336
8. Interacting with Users and Domains 337
Managing Local User Accounts .............................................................................. 338
Guided Exercise: Managing Local User Accounts ...................................................... 343
Managing Active Directory Domains ....................................................................... 346
Guided Exercise: Managing Active Directory Domains ............................................... 353
Generating Dynamic Inventories from Active Directory ............................................... 361
Guided Exercise: Generating Dynamic Inventories from Active Directory ..................... 368
Lab: Interacting with Users and Domains ................................................................. 373
Summary .............................................................................................................. 381
9. Automating Windows Administration Tasks 383
Running Commands and Scheduling Tasks on Hosts ................................................. 384
Guided Exercise: Running Commands and Scheduling Tasks on Hosts ......................... 399
Configuring and Managing Storage ......................................................................... 416
Guided Exercise: Configuring and Managing Storage ................................................ 420
Lab: Automating Windows Administration Tasks ....................................................... 425
Summary ............................................................................................................. 433
10. Managing Large Projects 435
Including and Importing Files ................................................................................. 436
Guided Exercise: Including and Importing Files .......................................................... 441
Creating Roles ..................................................................................................... 446
Guided Exercise: Creating Roles ............................................................................. 456
Deploying Roles with Ansible Galaxy ....................................................................... 462
Guided Exercise: Deploying Roles with Ansible Galaxy .............................................. 466
Integrating Ansible with Desired State Configuration Resources ................................. 474
Guided Exercise: Integrating Ansible with Desired State Configuration Resources ......... 478
Lab: Managing Large Projects ................................................................................ 481
Summary ............................................................................................................. 489
11. Constructing Ansible Tower Workflows 491
Creating and Managing Ansible Tower Users ............................................................ 492
Guided Exercise: Managing Users and Teams ........................................................... 502
Creating and Using Surveys ................................................................................... 509
Guided Exercise: Creating and Using Surveys ........................................................... 514
Scheduling Job Launches ...................................................................................... 519
Guided Exercise: Scheduling Job Launches .............................................................. 521
Running Complex Workflows .................................................................................. 524
Guided Exercise: Running Complex Workflows ......................................................... 530
Lab: Constructing Ansible Tower Workflows ............................................................. 535
Summary ............................................................................................................. 546
12. Comprehensive Review 547
Comprehensive Review ......................................................................................... 548
vi DO417-RHAE2.8-en-1-20200106
Lab: Comprehensive Review Lab 1 ........................................................................... 551
Lab: Comprehensive Review Lab 2 .......................................................................... 557
Lab: Comprehensive Review Lab 3 ......................................................................... 563
Lab: Comprehensive Review Lab 4 ......................................................................... 567
A. Supplementary Topics 575
Managing Red Hat Ansible Tower User Roles ........................................................... 576
B. Legal Notices 583
arillso.chocolatey Role License ............................................................................... 584
DO417-RHAE2.8-en-1-20200106 vii
viii DO417-RHAE2.8-en-1-20200106
Document Conventions
References
"References" describe where to find external documentation relevant to a subject.
Note
"Notes" are tips, shortcuts or alternative approaches to the task at hand. Ignoring a
note should have no negative consequences, but you might miss out on a trick that
makes your life easier.
Important
"Important" boxes detail things that are easily missed: configuration changes that
only apply to the current session, or services that need restarting before an update
will apply. Ignoring a box labeled "Important" will not cause data loss, but may cause
irritation and frustration.
Warning
"Warnings" should not be ignored. Ignoring warnings will most likely cause data loss.
DO417-RHAE2.8-en-1-20200106 ix
x DO417-RHAE2.8-en-1-20200106
Introduction
DO417-RHAE2.8-en-1-20200106 xi
Introduction
In this course, the main computer system used for hands-on learning activities is workstation.
The credentials to access this system are displayed in your Red Hat Online Learning (ROL)
interface, under the Online Lab tab. This course uses a set of six virtual machines running in a
remote cloud environment:
All systems are connected to a private subnet, 172.25.250.0/24. IPs are generated during
provisioning and remain static during throughout the environment life cycle.
• workstation is the main system that you will use interactively in this course. You will connect
to this host using Remote Desktop Protocol (RDP) from your own computer or laptop.
Instructions for making these connections is covered in detail later in this introduction.
xii DO417-RHAE2.8-en-1-20200106
Introduction
The workstation system is the only system that is directly connected to the Internet. It is also
connected to a private network used by all other classroom systems.
• windc is the Microsoft Active Directory domain controller for the example.com domain.
• tower provides the Red Hat Ansible Tower service that you will use to run your automation
code.
• gitlab provides a GitLab CE service that provides the Git version control repositories, in which
your code and other exercise materials are stored.
The following list describes the user accounts that are available:
• On workstation, you will use the training user as your standard user account. The
password for this account is automatically generated and is available in the online learning
platform (ROL), under the Online Lab tab.
The local Administrator account on this system uses the same password.
• On windc, the local user account Administrator uses RedHat123@! as a password. This is
also the password for the example.com domain administrator account.
• On win1 and win2, the user devops is used by Red Hat Ansible Tower for management and
automation purposes.
DO417-RHAE2.8-en-1-20200106 xiii
Introduction
In order to access the remote classroom, you will need a computer with Internet access and an
RDP client. That device should have a screen resolution of at least 1280x800 pixels. We assume
that you will provide your own computer for this training course.
Important
If you are attending an instructor-led training session and do not have your own
computer with you, or have difficulty with your RDP client, then please ask the
instructor for assistance.
Windows 2000 or later Microsoft Remote Installed on all Windows system, Windows
Desktop 2000 or later
xiv DO417-RHAE2.8-en-1-20200106
Introduction
Machine States
STARTED The virtual machine is running and available (or, when booting, soon
will be).
STOPPED The virtual machine is completely shut down. Upon starting, the virtual
machine boots into the same state as when it was shut down (the disk
will have been preserved).
WAITING_TO_START The virtual machine is waiting for other virtual machines to start.
Classroom/Machine Actions
PROVISION LAB Create the ROL classroom. Creates all of the virtual machines needed
for the classroom and starts them. Can take up to an hour to complete.
DELETE LAB Delete the ROL classroom. Destroys all virtual machines in the
classroom. Caution: Any work generated on the disks is lost.
DO417-RHAE2.8-en-1-20200106 xv
Introduction
ACTION → Gracefully shut down the virtual machine, preserving the contents of
Shutdown its disk.
ACTION → Power Forcefully shut down the virtual machine, preserving the contents of its
Off disk. This is equivalent to removing the power from a physical machine.
At the start of an exercise, if instructed to reset a single virtual machine node, click ACTION →
Reset for only the specific virtual machine you wish to reset.
At the start of an exercise, if instructed to reset all virtual machines, click ACTION → Reset
If you want to return the classroom environment to its original state at the start of the course, click
DELETE LAB to remove the entire classroom environment. After the lab has been deleted, you
can click PROVISION LAB to provision a new set of classroom systems.
Warning
The DELETE LAB operation cannot be undone. Any work you have completed in
the classroom environment up to that point is lost.
To adjust the timer, click MODIFY to display the New Autostop Time window. Set the number
of hours until the classroom should automatically stop. Note that there is a maximum time of ten
hours. Click ADJUST TIME to apply this change to the timer settings.
Upon provisioning, the Online Lab tab displays the connection information for the environment.
This includes the list of systems that are provisioned, and the various credentials that you will use
throughout the course.
xvi DO417-RHAE2.8-en-1-20200106
Chapter 1
DO417-RHAE2.8-en-1-20200106 1
Chapter 1 | Introducing Red Hat Ansible Automation
Objectives
After completing this section, you should be able to describe the fundamental concepts of
automation with Red Hat Ansible Automation, its basic design, and common use cases.
However, this approach is error-prone; it is easy for a system administrator to skip a step or
perform a step incorrectly. Often, there is limited verification that the steps were performed
properly, or that they result in the expected outcome.
Furthermore, by managing each server manually and independently, it is very easy for many
servers that should be identical in configuration are different in minor (or major) ways. This
inconsistency can make maintenance more difficult and introduce errors or instability in the IT
environment.
Automation can help avoid the problems caused by manual system administration and
infrastructure management. As a system administrator, use automation to ensure that all your
systems are quickly and correctly deployed and configured. Automation frees you from running
repetitive tasks in your daily schedule, freeing up your time and allowing you to focus on more
critical things. For your organization, this means you can more quickly roll out the next version of
an application or updates to a service.
Infrastructure-as-Code
A good automation system allows you to implement Infrastructure-as-Code (IaC) practices. IaC
means using a machine-readable automation language to define and describe the state in which
you want your IT infrastructure. Ideally, this automation language is easy for humans to read,
because then you can easily understand what the state is and make changes to it. This code is
then applied to your infrastructure to ensure that it is actually in that state.
If the automation language is represented as simple text files, then you can manage it in a version
control system, such as Git, the same way you would manage software code. The advantage is
that every change can be checked into the version control system so that you have a history of the
changes you make over time. If you want to revert to an earlier, known good configuration, then
you can check out that version of the code and apply it to your infrastructure.
By managing your infrastructure as code, you can ensure that your staging and production
environments are consistent. This also enables you to implement continuous integration (CI) and
continuous delivery (CD) practices. You can integrate tools such as linters and unit tests to check
the code that defines the configuration of your infrastructure before committing your changes
Using these tools can help improve the overall quality of your code and enforce compliance
standards, building a foundation to support DevOps best practices.
2 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Developers can define their desired configuration in the automation language. Operators
can review those changes more easily to provide feedback, and can use this automation to
reproducibly ensure that systems are in the state expected by the developers. Finally, it helps you
to establish best practices, and to ensure that they are in line with various teams implementations.
Automation enables code review by multiple subject matter experts, and supports automated
documentation of the review process to reduce operational risks.
Ultimately, you can enforce that changes to your IT infrastructure must be made through
automation to mitigate human error.
What is Ansible?
Ansible is an open source automation platform and a simple automation language that can
describe IT application infrastructure in Ansible Playbooks. It is also an automation engine that runs
Ansible Playbooks.
Ansible can manage powerful automation tasks and can adapt to many different workflows and
environments. At the same time, new users of Ansible can use it to quickly become productive.
Ansible Is Simple
Ansible Playbooks provide human-readable automation. This means that playbooks are
automation tools that are also easy for humans to read, comprehend, and change. No special
coding skills are required to write them. Playbooks execute tasks in order. The simplicity of
playbook design makes them usable by every team, which allows people new to Ansible to rapidly
become productive.
Ansible Is Powerful
You can use Ansible for deploy applications, for configuration management, for workflow
automation, and for network automation. Thus, Ansible can be used to orchestrate the entire
application life cycle.
Ansible Is Agentless
Ansible is built around an agentless architecture. Typically, Ansible connects to the hosts it
manages using OpenSSH, Windows Remote Management (WinRM), or PowerShell Remoting
Protocol (PSRP) and then runs tasks, often by pushing out small programs called Ansible modules
to those hosts. These programs are used to put the system in a specific desired state. Any
modules that are pushed are removed when Ansible is finished with its tasks. You can start using
Ansible almost immediately, because no special agents need to be approved for use and then
deployed to the managed hosts. Because there are no agents and no additional custom security
infrastructure, Ansible is more efficient and more secure than other alternatives.
• Cross platform support: Ansible provides agentless support for Linux, Windows, UNIX, and
network devices, in physical, virtual, cloud, and container environments.
DO417-RHAE2.8-en-1-20200106 3
Chapter 1 | Introducing Red Hat Ansible Automation
• Human-readable automation: Ansible Playbooks, written as YAML text files, are easy to read and
help ensure that everyone understands what they will do.
• Perfect description of applications: Every change can be made by Ansible Playbooks, and every
aspect of your application environment can be described and documented.
• Easy to manage in version control: Ansible Playbooks and projects are plain text. They can be
treated like source code and placed in your existing version control system.
• Support for dynamic inventories: The list of machines that Ansible manages can be dynamically
updated from external sources to capture the correct, current list of all managed servers all the
time, regardless of infrastructure or location.
• Orchestration that integrates easily with other systems: HP Server Automation (HPSA), Puppet,
Jenkins, Red Hat Satellite, and other systems that exist in your environment can be used and
integrated into your Ansible workflow.
Communication is the key to DevOps. Ansible is the first automation language that can be read
and written across systems without prior programming knowledge.
Think Declaratively
Ansible is a desired-state engine. It approaches the problem of how to automate IT
deployments by expressing them in terms of the desired system state. Ansible puts your
systems into the desired state by only making necessary changes. Ansible is not a scripting
language and should not be treated as one.
4 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Managed hosts are listed in an inventory, which also organizes those systems into groups for
easier collective management. The inventory can be defined in a static text file, or dynamically
determined by scripts that get information from external sources.
Instead of writing complex scripts, Ansible users create high-level plays to ensure a host or group
of hosts are in a particular state. A play performs a series of tasks on the hosts, in the order
specified by the play. These plays are expressed in YAML format in a text file. A file that contains
one or more plays is called a playbook.
Each task runs a module, a small piece of code (written in Python, PowerShell, or some other
language), with specific arguments. Ansible ships with many useful modules that can perform a
wide variety of automation tasks. Each module is essentially a tool in your toolkit. Modules can act
on system files, install services or users, or interact with PowerShell DSC configurations.
When used in a task, a module generally ensures that some particular aspect of the machine is
in a particular state. For example, a task using one module may ensure that a file exists and has
particular permissions and contents, while a task using a different module may make certain that a
particular file system is mounted. If the system is not in that state, the task will put it in that state. If
DO417-RHAE2.8-en-1-20200106 5
Chapter 1 | Introducing Red Hat Ansible Automation
the system is already in that state, it does nothing. If a task fails, then by default Ansible will abort
the rest of the playbook for those hosts that failed.
Tasks, plays, and playbooks are designed to be idempotent. This means that you can safely run
a playbook on the same host multiple times. When your systems are in the correct state, the
playbook makes no changes when run. Therefore, running a playbook multiple times on the same
host is safe. There are a handful of modules that you can use to run arbitrary commands. However,
you must use those modules with care to ensure that they run in an idempotent way.
As discussed previously, the Ansible architecture is agentless. Therefore, when you run an Ansible
Playbook or an ad hoc command, the control node connects to the managed host, using SSH (the
default configuration) or WinRM (for most Windows hosts). Clients need only a WinRM listener
installed on hosts, rather than an Ansible-specific agent, and therefore, need not permit special
network traffic to a nonstandard port.
Red Hat Ansible Tower is an enterprise framework to help you control, secure, and manage your
Ansible automation at scale. It acts as the control node to run your Ansible Playbooks. It provides
a web-based user interface and a RESTful API. Linux administrators can use command-line tools
included with Ansible to run playbooks, but Red Hat Ansible Tower provides a centralized graphical
interface that helps you use Ansible more effectively with a team or at large scale. It allows users
with no Linux experience to easily run Ansible automation, while also providing a central point of
authorization, management, and logging of automation activities.
Use Cases
Unlike some other tools, Ansible combines and unites orchestration with configuration
management, provisioning, and application deployment in one easy-to-use platform.
6 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Configuration Management
Centralizing configuration file management and deployment is a common use case for
Ansible, and is how many power users are first introduced to the Ansible automation platform.
Application Deployment
When you define your application with Ansible, and manage the deployment with Red Hat
Ansible Tower, teams can effectively manage the entire application life cycle from
development to production.
Provisioning
Applications must be deployed or installed on systems. Ansible and Red Hat Ansible Tower can
streamline the process of provisioning systems, whether you are using a Preboot Execution
Environment (PXE) with Kickstart installation on bare-metal servers or virtual machines, or
creating virtual machines or cloud instances from templates.
Continuous Delivery
Creating a CI/CD pipeline requires coordination and buy-in from numerous teams. You cannot
do it without a simple automation platform that everyone in your organization can use. Ansible
Playbooks keep your applications properly deployed (and managed) throughout their entire
life cycle.
Orchestration
Configurations alone do not define your environment. You must also define how multiple
configurations interact, and ensure the disparate pieces can be managed as a whole.
References
Ansible
https://www.ansible.com
DO417-RHAE2.8-en-1-20200106 7
Chapter 1 | Introducing Red Hat Ansible Automation
Quiz
2. Which two of the following protocols does Ansible use to communicate with managed
Windows nodes? (Choose two.)
a. HTTP
b. HTTPS
c. WinRM
d. WinSCP
e. PowerShell remote protocol
3. Which of the following files defines the actions that Ansible performs on managed
nodes?
a. Host inventory
b. Manifest
c. Playbook
d. Script
8 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Solution
2. Which two of the following protocols does Ansible use to communicate with managed
Windows nodes? (Choose two.)
a. HTTP
b. HTTPS
c. WinRM
d. WinSCP
e. PowerShell remote protocol
3. Which of the following files defines the actions that Ansible performs on managed
nodes?
a. Host inventory
b. Manifest
c. Playbook
d. Script
DO417-RHAE2.8-en-1-20200106 9
Chapter 1 | Introducing Red Hat Ansible Automation
Objectives
After completing this section, you should be able to describe the architecture of a Windows
automation implementation using Red Hat Ansible Tower and a Git repository as a central point of
control.
• Use Red Hat Ansible Tower as the control node to run Ansible Playbooks.
• Store Ansible Playbooks and other materials in a distributed version control system, preferably
one based on Git.
• Use Windows-native source code editors that can directly work with files in your version control
system to edit Ansible Playbooks and other materials.
One advantage of this solution is that most of your Windows administrators do not need to use
the Linux command line in order to use Ansible. Instead, they can work through the Red Hat
Ansible Tower graphical, web-based user interface, or its REST API. This reduces the Ansible
learning curve for administrators, and also provides valuable capabilities from Ansible Tower, such
as event scheduling, logging, and secrets management.
Using a version control system to manage your code is a recommended practice, even if you are
not using Ansible Tower. This gives you the ability to track the people responsible for making
specific changes to the code, and the ability to roll back to older revisions, if needed. When using
Ansible to define something that is as important as your Infrastructure-as-Code, it is important
that you have solid practices to manage that code.
One reason why we recommend Git is because Git skills are common, and there are powerful
services that provide Git repository management for use in both the cloud, and as an on-site
installation. These include GitHub, GitLab, and Bitbucket, among others. In this course, we will use
a local installation of GitLab, rather than one of the cloud services, but these function similarly.
The next section provides a quick overview of how to work with a Git repository using Visual Studio
Code. In the remainder of this section, you will learn more about Red Hat Ansible Tower.
10 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
does not provide any facilities for managing shared access. Additionally, although playbooks may
allow for the delegation of complex tasks, executing those tasks may require highly privileged and
guarded administrator credentials. Red Hat Ansible Tower mitigates these challenges, providing a
framework for running and managing Ansible efficiently on an enterprise scale.
Ansible Tower eases the administration involved with sharing an Ansible infrastructure, while
maintaining organization security, by introducing features such as a centralized web UI for
playbook management, role-based access control (RBAC), and centralized logging and auditing.
The REST API enables you to integrate Ansible Tower with existing organizational workflows and
tool sets. The Ansible Tower API and notification features make it particularly easy to associate
Ansible Playbooks with other tools, such as Jenkins, Red Hat CloudForms, or Red Hat Satellite,
to enable continuous integration and deployment. It provides mechanisms to enable centralized
use and control of machine credentials and other secrets, without exposing them to end users of
Ansible Tower.
The Red Hat Ansible Automation subscription offers support for both Red Hat Ansible Tower
and Red Hat Ansible Engine. More information is available at https://www.redhat.com/en/
technologies/management/ansible.
You can interact with the underlying Ansible infrastructure for the enterprise using either the
Ansible Tower web UI or RESTful API. The Ansible Tower web UI is a graphical interface that
performs actions by executing calls against the Ansible Tower API. Any action available through
the Ansible Tower web UI can also be performed using the Ansible Tower RESTful API. The
RESTful API is essential for those users looking to integrate Ansible with existing software tools
and processes.
DO417-RHAE2.8-en-1-20200106 11
Chapter 1 | Introducing Red Hat Ansible Automation
Ansible Tower stores its data in a PostgreSQL back-end database, and makes use of the
RabbitMQ messaging system. Versions of Ansible Tower before version 3.0 also relied on a
MongoDB database. This dependency has since been removed, and data is now stored solely in a
PostgreSQL database.
Depending on the needs of your enterprise, Ansible Tower can be implemented using one of the
following architectures:
Note
This course focuses on the most straightforward architecture to deploy; that is, a
single Red Hat Ansible Tower server with an integrated database.
Visual Dashboard
The Ansible Tower web UI displays a dashboard that provides a summary view of the entire
Ansible environment for the enterprise. The Ansible Tower dashboard allows you to easily see
the current status of hosts and inventories, as well as the results of recent job executions.
12 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Job Scheduling
Use Ansible Tower to schedule playbook execution and updates from external data sources,
either on a one-time basis or at recurring intervals. This allows you to perform unattended
routine tasks, and is especially useful for tasks such as backup routines, which are ideally
executed during operational off-hours.
DO417-RHAE2.8-en-1-20200106 13
Chapter 1 | Introducing Red Hat Ansible Automation
User-triggered Automation
Ansible simplifies IT automation, and Ansible Tower takes it a step further by enabling user
self-service. The Ansible Tower streamlined web UI, coupled with the flexibility of its RBAC
system, allows you to reduce complex tasks to simple routines that are easy to use.
Credential Management
Ansible Tower centrally manages authentication credentials. This means that you can run
Ansible plays on managed hosts, synchronize information from dynamic inventory sources,
and import Ansible project content from version control systems. Ansible Tower encrypts the
passwords or keys provided so that they cannot be retrieved by Ansible Tower users. You can
grant users the ability to use or replace these credentials without actually exposing them to
the user.
Ansible supports more than 15 different credential types, which includes major providers such
as Google Compute Engine, Microsoft Azure, and VMware.
14 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Integrated Notifications
Ansible Tower notifies you when job executions succeed or fail. Ansible Tower can deliver
notifications using many applications, including email, Slack, and HipChat.
Multiplaybook Workflows
Complex operations often involve the serial execution of multiple playbooks. Ansible Tower
multi-playbook workflows allow users to chain together multiple playbooks to facilitate
the execution of complex routines involving provisioning, configuration, deployment, and
orchestration. An intuitive workflow editor also simplifies the modeling of multi-playbook
workflows.
RESTful API
The Ansible Tower RESTful API exposes every Ansible Tower feature available through the
web UI. The API's browsable format makes it self-documenting, and simplifies the lookup of
API usage information.
DO417-RHAE2.8-en-1-20200106 15
Chapter 1 | Introducing Red Hat Ansible Automation
16 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
With this flexible approach you can test your changes from a development branch against a set
of test servers. Based on the results, you can then decide whether to merge your changes to the
main branch to use them in the production environment.
References
For more information, refer to the Ansible Tower Administration Guide at
https://docs.ansible.com/ansible-tower/latest/html/administration/
DO417-RHAE2.8-en-1-20200106 17
Chapter 1 | Introducing Red Hat Ansible Automation
Guided Exercise
Outcomes
You should be able to log into the Ansible Tower web UI, explore the control panel, and
launch a template from the console.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1.1. Double click the desktop shortcut labeled Ansible Tower and authenticate with the
user admin and RedHat123@! as the password.
2.1. From the dashboard, click Users in the sidebar to view the accounts available within
Ansible Tower.
18 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
This menu displays the accounts available, including the admin account currently in
use.
2.2. Click Settings at the bottom of the console sidebar to access the Ansible Tower
configuration.
From this panel, you can configure authentication from various applications and
providers, such as GitHub or LDAP. Click the LDAP button to view the current
configuration for your instance.
In a production configuration, configure the authentication implementation that is
appropriate for your environment.
DO417-RHAE2.8-en-1-20200106 19
Chapter 1 | Introducing Red Hat Ansible Automation
2.4. Return to the Settings page, and then click License to view the licensing information
for Ansible Tower.
From this panel, you can peruse the licensing information for this instance of Ansible
Tower, as well as upload a new license file.
3.1. From the console sidebar, click Templates to access the available templates or
configure new ones. Templates are a set of instructions that execute Ansible Playbooks
and perform tasks using Ansible modules.
3.2. From the Templates list, select the Run architecture project template.
Note
To select a project for editing, click its name.
3.3. Select the create_desktop_file.yml playbook from the PLAYBOOK list, and
then click Save to update the job template.
The playbook instructs Ansible to create an ansible.txt text file on the devops'
desktop of the win1.example.com server.
Select LAUNCH to begin execution.
20 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
3.4. While the job is running, Ansible Tower displays the output of the tasks as they execute.
Ansible retrieves information about the system, and then runs the tasks. A task with a
state of changed indicates that the file was not present and that the task creates it.
The output also displays job statistics, such as the start time and information from the
template in use.
3.5. Once completed, the status changes from Running to Successful. If the job
encounters any issues, this status changes to Failed and the output contains
information regarding the errors.
DO417-RHAE2.8-en-1-20200106 21
Chapter 1 | Introducing Red Hat Ansible Automation
Select an entry from the output to access more information about the execution result.
4.1. To ensure that the file is present on win1.example.com, access the Remote
Desktop Connection client available from the Start menu. The client is accessible
from the Windows Server applications list.
Access win1 using devops as the user name. Click Connect to initiate the
connection. When prompted, use a password of RedHat123@!, and then click OK.
22 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
4.3. Ensure that the ansible.txt text file is present on the desktop.
DO417-RHAE2.8-en-1-20200106 23
Chapter 1 | Introducing Red Hat Ansible Automation
24 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Objectives
After completing this section, you should be able to retrieve, manage, edit, and store files in a
remote Git version control system such as GitHub or GitLab, using Visual Studio Code.
Infrastructure-as-Code
One key DevOps concept is the idea of Infrastructure-as-Code (IaC), previously discussed in
this chapter. Instead of managing your infrastructure manually, you define and build your systems
by running your automation code. Red Hat Ansible Automation is a key tool that can help you
implement this approach.
If Ansible projects are the code which is used to define the infrastructure, then a version control
system such as Git should be used to track and control changes to the code.
Version control also allows you to implement a life cycle for the different stages of your
infrastructure code, such as development, QA, and production. You can commit your changes to
a branch, and then test those changes in noncritical development and QA environments. Once
you are confident in the changes, you can merge them to the main production code and apply the
changes to your production infrastructure.
Introducing Git
Git is a distributed version control system (DVCS) that allows you to manage changes to files in a
project in a collaborative manner. Each revision of a file is committed to the system. Old versions
of files can be restored, and a log of who made the changes is maintained.
• The ability to compare two versions of the same file to identify changes.
• A record or log of who made what changes, and when those changes were made.
• Mechanisms for multiple users to collaboratively modify files, resolve conflicting changes, and
merge the changes together.
Each developer can start by cloning an existing shared project from a remote repository. Cloning
a project creates a complete copy of the original remote repository as a local repository. This is
a local copy of the entire history of the files in the version control system, and not just the latest
snapshot of the project files.
The developer makes edits in a working tree, which is a working area for new and modified files.
A set of related changes are then staged and committed to the local repository. At this point, no
changes have been made to the shared remote repository.
When the developer is ready to share their work, they push changes to the remote repository.
Alternatively, if the local repository is accessible from the network, the owner of the remote
repository can pull the changes from the developer's local repository to the remote repository.
DO417-RHAE2.8-en-1-20200106 25
Chapter 1 | Introducing Red Hat Ansible Automation
Likewise, when a developer is ready to update their local repository with the latest changes in the
remote repository, they can pull the changes, which fetches them from the remote repository and
merges them into the local repository.
To use Git effectively, a user must be aware of the three possible states of a file in the working
tree: modified, staged, or committed.
• Modified: the copy of the file in the working tree has been edited and is different from the latest
version in the repository.
• Staged: the modified file has been added to a list of changed files to commit as a set, but has
not yet been committed.
• Committed: the modified file has been committed to the local repository.
Once the file is committed to the local repository, the commit can be pushed to or pulled by a
remote repository.
A link to detailed information on Git can be found in the references at the end of this section.
In this course, you will use Visual Studio Code as your primary editor for Ansible files and tool for
working with Git repositories.
There are other text editors available on Windows with support for Git, including Atom and
Sublime Text.
26 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
After installing Git, run the Git GUI program accessible from the quick start menu. After cloning
a repository, you can configure the user name and email address settings for the repository, or
globally.
DO417-RHAE2.8-en-1-20200106 27
Chapter 1 | Introducing Red Hat Ansible Automation
Add the Path option with the value being the absolute path to the Git executable.
28 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Note
Make sure to escape any backslashes with an extra backslash, as shown in the
following figure.
Because you are working with Ansible Playbooks, which are in YAML format, install the YAML
extension by navigating to View → Extensions, and then search for or scroll down to the YAML
extension. Click Install.
You can clone a Git repository in Visual Studio Code by accessing the Command Palette, which
is accessible by selecting View → Command Palette or by pressing Ctrl+Shift+P on the
keyboard. Type Git: Clone to access the Git clone feature.
The command palette prompts you for the URL of the remote repository, and the intended parent
directory for the local repository.
DO417-RHAE2.8-en-1-20200106 29
Chapter 1 | Introducing Red Hat Ansible Automation
Note the version control status icons at the lower left of the screen. They currently indicate that
there have been no changes.
30 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Adding a new site.yml file results in a notification being added to the Source Control icon,
as well as a U being displayed next to site.yml. The U indicates that site.yml is untracked,
meaning that Git is not watching it for changes. If you navigate to the Source Control view, you
will see site.yml listed underneath Changes.
DO417-RHAE2.8-en-1-20200106 31
Chapter 1 | Introducing Red Hat Ansible Automation
Figure 1.34: The new file listed under Changes in Source Control view
Indicator Description
A (Added) This file has been added to the index and will be included in the next commit.
D (Deleted) This file has been deleted. The file will no longer appear in the Explorer view,
only in the Source Control view. The deletion of the file will be included in the
next commit.
Click + next to site.yml to add the file to Git, and then enter a commit message describing
your changes. Ideally, your commit message will be succinct enough to fit on a single line. Press
Ctrl+Enter to commit your changes.
Now that a local change has been committed, the local repository is ahead of the remote
repository in terms of changes. Note the status icon at the lower left, which shows that one change
can be pushed to the remote repository.
32 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
The status icons displayed in the lower left corner of the editor indicate that there are changes
ready to push to the remote Git repository. Click Synchronize Changes to push your local changes
to the remote repository, and retrieve any new changes from the repository.
The repositories are now synchronized again, and the next piece of work can begin.
References
Pro Git by Scott Chacon and Ben Straub (free book)
https://git-scm.com/book/en/v2
DO417-RHAE2.8-en-1-20200106 33
Chapter 1 | Introducing Red Hat Ansible Automation
Guided Exercise
Outcomes
You should be able to configure Git settings, and edit files stored in an existing Git
repository.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor and clone the architecture repository to your
workstation instance.
1.1. Click Search Windows, type code as the term for which to search, and then open
Visual Studio Code.
34 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
1.2. Open the command palette by navigating to View → Command Palette or by typing
Ctrl+Shift+P.
Type clone and select Git: Clone to clone a repository.
Use a repository URL of https://gitlab.example.com/student/
architecture.git. When prompted, select the Documents folder in the home
directory of the training user as the repository location, and then click Select
Repository Location. This clones the remote repository into the architecture
folder.
Optionally, view the files by selecting Open from the window that displays after
cloning.
DO417-RHAE2.8-en-1-20200106 35
Chapter 1 | Introducing Red Hat Ansible Automation
3.1. Select the site.yml file, and then change the task name and the name of the
managed Windows service from W32Time to Spooler.
...output omitted...
- name: Spooler service is enabled and running
win_service:
name: Spooler
start_mode: auto
state: running
3.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master,
indicating that changes have been made.
3.3. Change to the Source Control view, and then select +, next to site.yml, to stage
the changes.
3.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
4. Edit the README.md file, commit your changes, and then synchronize your local repository
with the remote one.
4.1. Select the Explorer view, and then the README.md file.
4.2. Change the service name in the description from W32Time to Spooler.
This is a sample README for the Managing Files in Git exercise in DO417
4.3. Click Save. Note the status icons in the lower left. There is an asterisk next to master
again, indicating that changes have been made.
4.4. Change to the Source Control view, and then select + next to README.md to stage
the changes.
4.5. Enter a commit message, and then press Ctrl+Enter to commit the changes.
4.6. The status icons displayed in the lower left corner of the editor indicate that there
are changes ready to push to the remote Git repository. Click Synchronize Changes,
represented by a circular arrow at the bottom of the editor, to push your local changes
to the remote repository, and retrieve any new changes from the repository.
36 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
DO417-RHAE2.8-en-1-20200106 37
Chapter 1 | Introducing Red Hat Ansible Automation
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
• On the hosts: line, insert a space and the text win1.example.com after the colon.
• For the first task, that is, the line that reads - name: Install service, replace "Install
service" with IIS Web Server is installed.
38 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
• For the second task (- name: Start service), change the line name: W3Svc to
name: IIS Web Server is started. Do not change the indentation of this line.
DO417-RHAE2.8-en-1-20200106 39
Chapter 1 | Introducing Red Hat Ansible Automation
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1.1. From workstation, double-click the GitLab icon on your Desktop to access your
GitLab instance located at https://gitlab.example.com.
1.2. Log in to GitLab using student as the user name and RedHat123@! as the password.
Make sure that LDAP is selected and click Sign In.
40 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
1.3. The page redirects you to the list of projects for the student user. From the Your
projects tab select the architecture project to view the contents of the repository.
1.4. The page lists all the files in the repository. Click review.yml to inspect the playbook.
1.5. The playbook invokes the win_feature module to install the IIS web server on
your managed hosts. After installation, the playbook starts the service by using the
win_service module.
DO417-RHAE2.8-en-1-20200106 41
Chapter 1 | Introducing Red Hat Ansible Automation
2. From workstation, access Visual Studio Code. If you did not already clone the
architecture repository, available at https://gitlab.example.com/student/
architecture.git, clone it to C:\Users\student\Documents\architecture.
Add the architecture folder to the Visual Studio Code workspace.
2.1. Click Search Windows, and then type code to search for, and then open, Visual Studio
Code.
2.2. To clone the architecture repository, open the command palette by navigating to
View → Command Palette or by typing Ctrl+Shift+P.
Type clone and select Git: Clone to clone a repository.
Use a repository URL of https://gitlab.example.com/student/
architecture.git. When prompted, select the Documents folder in the home
directory of the training user as the repository location, and click Select Repository
Location. This clones the remote repository into the architecture folder.
Optionally, to view the files select Open from the window that displays after cloning.
2.3. To add the architecture folder to your workspace, navigate to File → Open Folder.
42 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
From the Windows Explorer, navigate to Local Disk (C:) → Users → student →
architecture and then click Select Folder.
3. Use Visual Studio Code to edit the file review.yml in the architecture project. These
edits will change an Ansible Playbook. For now, do not worry about what these changes do, as
this exercise is intended to give you a chance to practice using Visual Studio Code with Git.
Read the file and make the following changes:
• On the hosts: line, insert a space and the text win1.example.com after the colon.
• For the first task, that is, the line that reads - name: Install service, replace "Install
service" with IIS Web Server is installed.
• For the second task (- name: Start service), change the line name: W3Svc to
name: IIS Web Server is started. Do not change the indentation of this line.
3.1. From Visual Studio Code, open the review.yml playbook in the architecture folder.
On the hosts: line, insert a space and the text win1.example.com after the colon.
---
- name: Install the IIS web server on managed hosts
hosts: win1.example.com
...output omitted...
3.2. For the first task, that is, the line that reads - name: Install service, replace
"Install service" with IIS Web Server is installed.
DO417-RHAE2.8-en-1-20200106 43
Chapter 1 | Introducing Red Hat Ansible Automation
...output omitted...
tasks:
- name: IIS Web Server is installed
win_feature:
name: Web-Server
state: present
...output omitted...
3.3. For the second task (- name: Start service), change the line name: W3Svc to
name: IIS Web Server is started.
...output omitted...
- name: IIS Web Server is started
win_service:
name: W3Svc
state: started
3.4. Save your file. After your updates, the file should display as follows:
---
- name: Install the IIS web server on managed hosts
hosts: win1.example.com
tasks:
- name: IIS Web Server is installed
win_feature:
name: Web-Server
state: present
Note
The completed solution file is available at solutions/review.sol in the
architecture project.
4. Add your changes to the Git index, and then commit your changes using a message of Use
more descriptive task names and target the correct host.
Commit and push your changes back to the master branch.
4.1. From the Visual Studio Code side bar, select Source Control to access the list of
changes.
44 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
4.2. Hover over review.yml to access the available options for the file. Click Stage
Changes to add your changes to the index.
4.3. In the Message text file, enter a message of Use more descriptive task names
and target the correct host
DO417-RHAE2.8-en-1-20200106 45
Chapter 1 | Introducing Red Hat Ansible Automation
4.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
5. Access the GitLab web console and review the review.yml playbook in the
architecture repository to ensure that the changes are available on the remote server.
46 DO417-RHAE2.8-en-1-20200106
Chapter 1 | Introducing Red Hat Ansible Automation
Summary
In this chapter, you learned:
• Ansible is an open source automation platform and a simple automation language that can
describe IT application infrastructure.
• Ansible is installed and run from a control node, that runs playbooks against managed hosts..
• Ansible Tower provides native tools and features for managing Microsoft Windows
environments.
• Git is a distributed version control system (DVCS) that allows you to manage changes to files in
a project in a collaborative manner.
DO417-RHAE2.8-en-1-20200106 47
48 DO417-RHAE2.8-en-1-20200106
Chapter 2
DO417-RHAE2.8-en-1-20200106 49
Chapter 2 | Running Simple Automation Commands
Objectives
After completing this section, you should be able to configure Microsoft Windows systems to
provide the prerequisites and access needed for management by Red Hat Ansible Automation.
Managed Hosts
One of the benefits of Ansible is that managed hosts do not need to have a special agent installed.
The Ansible control node connects to managed hosts using a standard network protocol to ensure
that the systems are in the specified state. On Windows systems, Ansible connects to the Windows
Remote Management (WinRM) service and its listener.
Minimum Requirements
Before getting started, verify that the minimum host operating system requirements are met.
You can use Ansible to manage all versions of Windows that are under Microsoft mainstream
and extended support. Older versions of Windows, such as Windows Server 2008 or Windows 7,
require PowerShell and .NET Framework updates. Always apply the latest security patches.
• Windows Server (2008, 2008 R2, 2012, 2012 R2, 2016, or 2019) or Windows 7, 8.1, or 10
Windows versions since Windows Server 2012 and Windows 8 ship with the minimum required .NET
and PowerShell dependencies. Versions of Windows prior to this require download and installation
of the latest service pack, .NET framework, and PowerShell.
These are the basic requirements for Ansible to work in general. However, some Ansible modules
may have additional requirements that will be listed in the documentation for those modules at
https://docs.ansible.com/ansible/latest/user_guide/modules.html.
Important
Due to a WinRM memory issue, PowerShell 3.0 requires a hotfix. Refer to the
Microsoft support article available at https://support.microsoft.com/en-us/
help/2842230/out-of-memory-error-on-a-computer-that-has-a-customized-
maxmemorypersh for more information.
Install the latest stable updates to keep your systems secure and reliable.
50 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
WinRM is enabled by default since Windows Server 2012. However, you still need to configure a
WinRM listener, the corresponding firewall rules, and the authentication mechanism.
Ansible uses the PowerShell Remoting Protocol (PSRP) on top of WinRM to execute PowerShell
commands on a target. PSRP provides a faster direct connection to PowerShell.
Since the Ansible connection normally depends on both WinRM and PowerShell, Ansible cannot
interact directly with WinRM listeners or upgrade PowerShell.
Note
Ansible 2.8 provides an experimental feature that allows you to use SSH instead of
WinRM to connect to Windows hosts. It is not yet supported and might change in
future versions of Ansible. This course uses the standard WinRM protocol to connect
to Windows-based managed hosts.
2. Runs the WinRM service, if not already running, and configures it to automatically start on
boot.
6. Configures the Windows firewall for WinRM connections over both HTTP and HTTPS.
The following list describes the list of arguments that you can use with the PowerShell script:
-EnableCredSSP
Enables the CredSSP authentication protocol.
DO417-RHAE2.8-en-1-20200106 51
Chapter 2 | Running Simple Automation Commands
-DisableBasicAuth
Disables Basic authentication. This option is recommended since Basic authentication is the
least secure WinRM authentication method.
-CertValidityDays
Specifies the expiration of the self-signed SSL certificate created for HTTPS. The default
validity is 1095 days (3 years).
-ForceNewSSLCert
Forces the creation of a new SSL certificate.
-SubjectName
Specifies the CN (Common Name) of the SSL certificate. Defaults to the host name.
-SkipNetworkProfileCheck
Allows for enabling PS Remoting without checking the network profile.
-Verbose
Enables verbose output. This option is useful for debugging.
To avoid inconsistencies across systems and reduce manual steps, integrate the script as part
of an automated host provisioning process. Specific methods for achieving this vary across
environments and are outside of the scope of this course.
Authentication
Ansible can use a variety of protocols to authenticate its connection with Windows hosts. These
are: Basic, Certificate, CredSSP, NTLM, and Kerberos. You must configure the managed host to
accept the protocol best suited for your environment.
Basic Yes No No No
Certificate Yes No No No
Warning
Basic and certificate authentication strategies are unencrypted. It is strongly
advised to only allow these protocols over trusted HTTPS connections.
52 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Basic and certificate authentication protocols are simple but less secure. Additionally, these
options can only use local accounts. Most production configurations require a protocol designed
for domain accounts.
CredSSP, NTLM, and Kerberos support domain accounts. CredSSP and Kerberos are preferred
due to their security, speed, and support for credential delegation.
CredSSP
Credential Security Support Provider (CredSSP) supports authentication for both local and
domain accounts.
Unlike Basic authentication, CredSSP encrypts credentials prior to transmitting them to the target
host. Encrypted messages may be sent over HTTP.
Note
This course uses CredSSP for the classroom environment.
A primary feature of CredSSP is credential delegation. This allows your target server to
authenticate to a second server using your credentials.
Important
Only use CredSSP credential delegation with trusted hosts. User credentials are
passed directly to the servers.
The NTLM protocol requires no additional setup and the WinRM service enables it by default.
NTLM is widely used for legacy compatibility, however it is not preferred for production
applications due to security weaknesses and known vulnerabilities. Kerberos has superseded
NTLM as the recommended authentication protocol.
Kerberos
Kerberos is the default Microsoft network authentication protocol and provides a more
sophisticated authentication option, which is recommended for use with domain accounts.
Clients authenticate with a Kerberos Key Distribution Center (KDC) to retrieve a session ticket. The
Active Directory domain controller can provide the role of the KDC. Shared secrets are used to
encrypt and decrypt messages between entities.
DO417-RHAE2.8-en-1-20200106 53
Chapter 2 | Running Simple Automation Commands
Unlike CredSSP and NTLM, Kerberos does not support local accounts.
References
Ansible Windows Guides — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/windows.html
54 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Quiz
1. Which two technologies are required on Windows managed hosts? (Choose two.)
a. OpenSSH 8.0
b. .NET Framework 4.0
c. Visual Studio 2019
d. PowerShell 3.0
2. What are two limitations of the Ansible WinRM connection? (Choose two.)
a. Ansible cannot execute commands that require administrator access.
b. Ansible cannot interact with the WinRM listener.
c. Ansible cannot upgrade PowerShell.
d. Ansible cannot reboot the host.
5. Which three features make Kerberos the preferred option for production
environments? (Choose three.)
a. Kerberos is the default Microsoft network authentication protocol.
b. Kerberos supports Active Directory domain accounts.
c. Kerberos uses symmetric key cryptography and a system of tickets instead of passing
account credentials directly to the target host.
d. Kerberos cannot be operated securely in untrusted networks.
DO417-RHAE2.8-en-1-20200106 55
Chapter 2 | Running Simple Automation Commands
Solution
1. Which two technologies are required on Windows managed hosts? (Choose two.)
a. OpenSSH 8.0
b. .NET Framework 4.0
c. Visual Studio 2019
d. PowerShell 3.0
2. What are two limitations of the Ansible WinRM connection? (Choose two.)
a. Ansible cannot execute commands that require administrator access.
b. Ansible cannot interact with the WinRM listener.
c. Ansible cannot upgrade PowerShell.
d. Ansible cannot reboot the host.
5. Which three features make Kerberos the preferred option for production
environments? (Choose three.)
a. Kerberos is the default Microsoft network authentication protocol.
b. Kerberos supports Active Directory domain accounts.
c. Kerberos uses symmetric key cryptography and a system of tickets instead of passing
account credentials directly to the target host.
d. Kerberos cannot be operated securely in untrusted networks.
56 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Objectives
After completing this section, you should be able to configure Red Hat Ansible Tower with an
inventory of Windows hosts to manage, and credentials needed to authenticate and connect to
those hosts.
You can set other information through inventory variables on individual hosts, host groups, or all
members of a particular inventory. Inventory variables can modify how Ansible Tower interacts with
or connects to hosts, and automation jobs can use them to determine what to do.
You can configure more than one inventory in Ansible Tower, and use different inventories for
different purposes. Manually specify hosts and host groups in an inventory, or dynamically
generate inventory settings from a remote source of information, such as Microsoft Azure
Resource Manager or Amazon Web Services EC2.
You can create inventories manually or dynamically provision them. Inventories require a name and
must be assigned to an organization.
The following example outlines the procedure to manually create an inventory in the web-based
user interface:
DO417-RHAE2.8-en-1-20200106 57
Chapter 2 | Running Simple Automation Commands
Click SAVE.
Once the inventory exists, you can add hosts to it, assign those hosts to groups, and set values for
inventory variables.
There are two main ways to add hosts to inventories. Static inventories are managed manually.
Dynamic inventories are dynamically updated the with hosts and groups in the inventory by
retrieving a list from some central source of information, such as Microsoft Azure Resource
Manager, Amazon EC2, or VMware vCenter. It is often easier and more efficient to set up a
dynamic inventory that gets up to date information from an accurate central source.
1. In the Ansible Tower web-based user interface, click the Inventories in the navigation pane,
and then click the name of the inventory to which you want to add a host.
2. On the inventory detail window, click the HOSTS button. Then, click the + button, which
displays the tooltip "Create a new host."
3. In the HOST NAME field, enter the host name or IP address for the host which automation
tools use to manage that host.
4. You may define values for Ansible inventory variables that only apply to this host in the
VARIABLES box, in either YAML or JSON format. More detail on variables and their usage
will be covered later in this course. For Windows-based hosts, you may need to set variables
that control how Ansible Tower will connect to that host for management purposes. These
variables are discussed later in this section.
5. Click SAVE.
58 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Note
To set up a dynamic inventory instead, select the SOURCES button from the
inventory interface. Click the + button to add a source, and then give the source a
name, select the source type you are using, and fill in other necessary information
for that source type. More information is available in the documentation for
Ansible Tower at https://docs.ansible.com.
Hosts can be placed in multiple groups simultaneously. For example, you could create a set of
groups for development, testing, and production systems. You could also create groups based
on the physical location or data center in which a host is located. You could set up groups based
on the purpose or application on those systems. Then, you could create a final set of groups
based on whether a system is running Windows Server 2016, Windows Server 2019, or Red Hat
Enterprise Linux 8. You can even nest groups, so an us group could have the us-west-1 and us-
east-1 groups as members. By using groups like this, you can more easily apply automation tasks
to many hosts of the same type without using complex conditional tests in the Ansible Playbooks.
1. In the Ansible Tower web-based user interface, click the Inventories in the navigation pane,
and then click the name of the inventory to which you want to add a group.
2. On the inventory's detail screen, click the GROUPS button. Then, click the + button, which
displays the tooltip "Create a new group.""
3. In the NAME field, enter the name to use for the group.
4. You may define values for Ansible inventory variables that apply to all members of this group
in the VARIABLES box, in either YAML or JSON format. If both a group variable and a
host variable set a value for the same variable name, the value of the host variable takes
precedence.
5. Click SAVE.
6. Nested groups are created, and hosts added to the group, in the same way as for top-level
inventory groups. In the detail screen for the group, click the GROUPS button to create a
DO417-RHAE2.8-en-1-20200106 59
Chapter 2 | Running Simple Automation Commands
nested group for this inventory, thereby adding the hosts included in each nested group to
the new group. Alternatively, click the HOSTS button to add hosts to the group.
You can define any variables in the VARIABLES field. Ansible Playbooks read these variables
and apply their value to the hosts in that group. This is useful if some values depend on the
environment, for example, a different path between a development environment and a production
environment.
The following screenshot shows how to use group variables to define the root directory of a web
server in a staging environment.
Variable Purpose
Although you can define these variables for each host, it is useful and more practical to define
them for the inventory, or for a group, especially if all the hosts in the inventory are hosts that
should have the same settings. If you have a mix of Windows hosts and other operating systems
and devices in the inventory, then you can create a group for the Windows hosts and apply the
settings to all hosts in that group.
These settings must be made in the appropriate Variables frame. The following example
demonstrates setting them for the entire inventory.
60 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
1. Instructs Ansible Tower to utilize a different connection method for a Windows host, in this
case, WinRM. By default, Ansible uses the SSH protocol to connect to any host.
3. Instructs Ansible to ignore the Certificate Authority (CA) signature on the WinRM certificate
presented by the server, and simply accept it. This setting is necessary if the WinRM
certificate is self-signed. Set the option to validate if you use WinRM certificates signed by
a valid CA.
Note
If your WinRM certificate is signed by a public CA, then it should validate. If you are
using a custom CA certificate to sign the WinRM certificate, then add the custom
CA certificate to your Ansible Tower installation. Details on how to configure this
certificate validation are beyond the scope of this course, but you can find more
information in the Ansible User Guide in the section "HTTPS Certificate Validation"
[https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#https-
certificate-validation].
For more information on WinRM certificates, follow the How To: Configure WINRM
for HTTPS link listed in the references section.
4. Instructs Windows Ansible to use the CredSSP transport method, which is discussed in
Preparing Microsoft Windows Hosts for Automation. Windows has various authentication
methods that you can use to connect to your servers.
The following diagram shows how Ansible Tower uses credentials stored in its database to connect
to Windows hosts through the transport method that you define. It uses the connection to run
playbooks or ad hoc modules.
DO417-RHAE2.8-en-1-20200106 61
Chapter 2 | Running Simple Automation Commands
There are many types of credentials supported by Ansible Tower. Use machine credentials to
authenticate to your inventory hosts. This credential type must contain credentials that your
connection method can use to authenticate. For example, it can contain a username and a
password for a user on your Windows systems that has administrator privileges, so that Ansible
Tower can manage components. After creating the credential, the password is encrypted so that
no one can read it, but Ansible Tower can decrypt and use it.
1. In the Ansible Tower web-based user interface, click the Credentials in the navigation pane.
2. Create a new credential. On the CREDENTIALS window, click the + button, which displays
the tooltip "Create a new credential."
3. On the NEW CREDENTIAL window, enter a name for the credential. In the CREDENTIAL
TYPE field, click the magnifying glass icon and select the Machine credential type. It may be
on the second page of the search results. Click the SELECT button.
Alternatively, you can type the word Machine in the field.
4. For password-based authentication, add a user name and a password in the TYPE DETAILS
fields that display. If you leave the PASSWORD field blank, then you can also select the
Prompt on launch check box. If this check box is selected, then Ansible Tower prompts the
user to enter the password when running automation tasks that use this credential.
62 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
5. Click SAVE.
The following screenshot shows how the password field is displayed after the machine credential is
created.
References
Window Support — Ansible Documentation
https://docs.ansible.com/ansible/2.3/intro_windows.html
DO417-RHAE2.8-en-1-20200106 63
Chapter 2 | Running Simple Automation Commands
Guided Exercise
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From workstation, click the Ansible Tower icon on your desktop to access Ansible Tower.
Log in to the web console as admin and RedHat123@! as the password.
2. Before you can interact with the hosts, you must create an inventory and define the
connection information. In the following steps, you create the group and add a host.
2.1. Navigate to Inventories to manage inventories. Click Create a new inventory, and
then select Inventory to create a new static inventory.
64 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Field Value
Name Dev
Organization Default
2.3. Define some inventory variables so that all hosts in the inventory inherit the settings.
Enter the following variables in the Variables area and click SAVE to create the
inventory.
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_server_cert_validation: ignore
ansible_winrm_transport: credssp
By default, Ansible uses the SSH protocol to connect to any host. Your Windows
servers are configured with a WinRM listener instead, so you must use this variable
to instruct Ansible to use the WinRM connection method.
This variable instructs Ansible to use the encrypted WinRM TLS port 5986.
This variable instructs Ansible to ignore the validation of the WinRM certificate, as
the environment uses self-signed certificates.
This variable instructs Ansible to authenticate using CredSSP for authentication.
Note
YAML uses three dashes (---) to separate directives in a YAML file. This also serves
to signal the start of a document if no directives are present. Removing or leaving
the dashes in this case does not make any difference.
2.4. Create a group for this development inventory by selecting GROUPS, and then
clicking the + button, which displays the tooltip Create a new group.
DO417-RHAE2.8-en-1-20200106 65
Chapter 2 | Running Simple Automation Commands
Name the group dev_servers, and then click SAVE to create the group.
2.5. Create a new host for the dev_servers group by selecting HOSTS. Click the +
button, which displays the tooltip Add a host, and then select New Host from the
menu displayed.
Use the HOST NAME field to name the new host win2.example.com. Because the
inventory defines the connection information, you do not need to specify it in the host
definition.
Click SAVE to create the host.
66 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Note
The breadcrumb trail at the top of the page displays the inventory structure.
2.6. Review all hosts in the inventory from the page displayed when the new host is saved.
This page provides access to the following operations:
• Including or excluding hosts from jobs; this is indicated by the ON/OFF switch. All
hosts that are created are included by default.
• Editing hosts, including renaming them or deleting them.
• Executing commands by invoking ad hoc modules.
• Managing groups, including renaming them or deleting them.
3.1. To review the credentials that Ansible Tower uses to connect to your hosts, select
Credentials from the main menu.
Notice that the Windows domain controller has a devops user that belongs to the
Domain Admins group.
Click the Edit credential pencil icon for the DevOps credential to review its credential
information.
DO417-RHAE2.8-en-1-20200106 67
Chapter 2 | Running Simple Automation Commands
This credential uses a type of Machine, which is used for connecting directly to
servers. Notice the user name that matches the name of the user in Active Directory.
The password is encrypted and unreadable. Extra fields are available to configure
authentication, however, the connection method we are using for Windows systems in
these activities do not use them.
Click CANCEL to return to the CREDENTIALS page, and then log out.
68 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Objectives
After completing this section, you should be able to describe what an Ansible module is, and run a
single operation on managed hosts as an ad hoc command, using Red Hat Ansible Tower.
Ad hoc commands are useful for quick tests and changes. For example, you can use an ad hoc
command to make sure that a certain line exists in the %SystemRoot%\System32\drivers
\etc\hosts file on a group of servers. You could use another ad hoc command to efficiently
restart a service on many different machines, or to ensure that a particular software package is
up-to-date.
However, ad hoc commands cannot perform complex or repetitive tasks; use Ansible Playbooks to
realize the full power of Ansible for repeatable automation.
Note
Ad hoc commands interact with Ansible modules, which are small programs or
scripts that are executed on managed hosts to implement an automation task. Every
module has a particular use, such as creating a user, installing a package, executing a
PowerShell script, or creating a scheduled task.
Ansible ships with many modules for managing Windows environment. Chapter 3,
Implementing Ansible Playbooks, discusses modules in detail.
2. Select the check boxes next to the hosts on which you want to run the command.
DO417-RHAE2.8-en-1-20200106 69
Chapter 2 | Running Simple Automation Commands
4. In the EXECUTE COMMAND window, select a module from the MODULE list. In the
ARGUMENTS field, specify any arguments required by the selected module. Although not all
modules require additional arguments, many do.
In the MACHINE CREDENTIAL field, select the machine credential needed to authenticate
to the managed hosts on which you will run this ad hoc command. Use the magnifying glass
icon to see a list of available machine credentials.
The win_ping module in the following example needs no arguments, and checks to see if the
hosts it runs on can run Ansible automation.
The question mark of the ARGUMENTS field is dynamic. After selecting a module, clicking
the icon shows some text that contains a link; that link points to the module documentation.
This is a useful feature for quickly determining the module capabilities and how to use it.
70 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
6. Ansible Tower displays a new screen in your web browser for the job you just started. As the
job runs, the DETAILS pane continuously updates with information on the status of the job.
The pane on the right displays the name of the module running, and the output from the
Ansible ad hoc command. This output provides more information about job successes and
failures, warnings, and other useful details resulting from the Ansible command.
DO417-RHAE2.8-en-1-20200106 71
Chapter 2 | Running Simple Automation Commands
Note
By default, a limited subset of modules can be used in ad hoc commands run
by Ansible Tower. However, any available module can be included in an Ansible
Playbook that is run by Ansible Tower.
An Ansible module is PowerShell (for modules which are used on Windows) or Python code that
performs a specific task, such as installing software or configuring a service. The core Ansible
product includes many modules, and the following table lists several of the Windows specific ones.
Name Description
win_reboot Handles reboots for Windows systems, for example, after win_update has
applied system updates.
Important
For a complete list of available modules and documentation on how to use them,
see Windows Modules — Ansible Documentation [https://docs.ansible.com/ansible/
latest/modules/list_of_windows_modules.html].
Most modules require arguments to control their operation. A list of the arguments available
for a module is available in the module documentation. When you run a module in an ad hoc
command through Ansible Tower, specify any arguments in the ARGUMENTS field on the
EXECUTE COMMAND page. This field accepts arguments entered as a space separated list of
argument=value items.
For example, to start the spooler service on selected managed hosts with an ad hoc command,
select the win_service module and then put the text name=spooler state=started in the
ARGUMENTS field.
72 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
This instructs Ansible to manage the spooler service to ensure that it is running. This is
accomplished by the the usage of two arguments: name, and state.
Most modules are idempotent, which means that you can run them safely multiple times, and if the
system is already in the correct state, they do nothing. For example, if you run the previous ad hoc
command again, it should report no change since the spooler service is already running. This is
shown as a change of the text color.
DO417-RHAE2.8-en-1-20200106 73
Chapter 2 | Running Simple Automation Commands
a module: to delete a module, click the delete icon next to the module name, and to add a module,
type its name and type ENTER. To delete a module, you can also click the field to bring a list that
shows all the active modules and select a module from that list.
The following screenshot shows how to add the win_scheduled_task module to the list.
After adding it, the module is available for running ad hoc commands:
74 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Note
If a module is missing from the list of modules that you can use for ad hoc
commands, navigate to Settings → Jobs and add the module to the MODULE
area.
The win_command module allows you to quickly execute remote commands on managed hosts.
These commands are not processed by the shell on the managed hosts. As such, they cannot
access environment variables or perform shell operations such as <, >, | and ;.
For situations where commands require shell processing, administrators can use the win_shell
module. Like the win_command module, you pass the commands to be executed as arguments to
the module in an ad hoc command. Ansible then executes the command remotely on the managed
hosts. Unlike the win_command module, the commands are processed through a shell (by default,
PowerShell) on the managed hosts. Therefore, environment variables are accessible and shell
operations are also available for use.
DO417-RHAE2.8-en-1-20200106 75
Chapter 2 | Running Simple Automation Commands
Important
In most circumstances, it is a recommended practice to avoid the win_command
and win_shell "run command" modules if you can use other modules to
accomplish the same thing.
Most other modules are idempotent and can perform change tracking automatically.
They can test the state of systems and do nothing if those systems are already in
the correct state. By contrast, it is much more complicated to use "run command"
modules in a way that is idempotent. Depending upon them makes it more difficult
to ensure that rerunning an ad hoc command or playbook will not cause an
unexpected failure.
There are times when "run command" modules are valuable tools and a good
solution to a problem. If you do need to use them, it is best to try the win_command
module first, resorting to win_shell module only if you need its special features.
One limitation of ad hoc commands is that you can only use a single module as a single task. An
Ansible Playbook allows you to write more complex automation that executes a sequence of tasks.
Another limitation is that an ad hoc command is authored and executed as needed. That is, you
invent it "on the fly" and do not save the command after it runs. Version control systems normally
manage Ansible Playbooks so that you can easily reuse them.
Finally, Ansible Tower normally only provides a limited set of modules for use as ad hoc commands.
The Ansible Tower server administrator can change these settings in Settings → Jobs, but it is
still less flexible than simply writing and using a playbook.
The next chapter of this course teaches you how to write and use Ansible Playbooks.
References
Control with Ansible Tower, Part 2
https://www.ansible.com/blog/control-with-ansible-tower-part-2
76 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Guided Exercise
Outcomes
You should be able to execute ad hoc commands on a managed host from within Ansible
Tower.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1.1. From workstation, double-click the Ansible Tower shortcut icon on your Desktop
to access your Ansible Tower instance located at http://tower.example.com.
1.2. Log in to Ansible Tower using student as the user name and RedHat123@! as the
password.
DO417-RHAE2.8-en-1-20200106 77
Chapter 2 | Running Simple Automation Commands
1.3. From the main dashboard page, select Inventories from the sidebar and choose
Default inventory from the inventories listed.
1.4. From the Default inventory page, click HOSTS, and then select the
win1.example.com host entry.
1.5. After checking win1.example.com, click RUN COMMANDS to enter the ad hoc
command execution screen.
78 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
2. Using the win_ping module, verify that the win1.example.com server is running and
reachable by Ansible.
2.1. On the RUN COMMAND page, select the module win_ping from the MODULE list
2.2. Click the question mark icon of the ARGUMENTS field. This shows a windows that
contains a link that points to the win_ping documentation.
2.4. Review the output to verify that the module ran successfully, confirming that Ansible
successfully communicated with the server.
3. Navigate back to the RUN COMMANDS page for the win1.example.com server.
Using the setup module, gather the Ansible facts for the win1.example.com server. You
will explore the usage of this output information, and use these facts available to Ansible, in
subsequent chapters and exercises.
DO417-RHAE2.8-en-1-20200106 79
Chapter 2 | Running Simple Automation Commands
3.1. Navigate back to the RUN COMMANDS page for the win1.example.com server.
On the RUN COMMAND page, select the setup module from the MODULE list, and
then click LAUNCH.
3.2. Review the output to verify that the module ran successfully, confirming that Ansible
contacted the system and profiled various aspects of the environment. Take note of
the various facts Ansible gathers, as you will use these in subsequent chapter exercises.
80 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
4.1. On the RUN COMMAND page, select the module win_reboot from the MODULE
list, and then click LAUNCH.
4.2. Review the output to verify that the module ran successfully and that Ansible restarted
the server.
5. Using the win_ping module, verify that the win1.example.com server is running and
reachable by Ansible.
5.1. On the RUN COMMAND page, select the module win_ping from the MODULE list,
and then click LAUNCH.
DO417-RHAE2.8-en-1-20200106 81
Chapter 2 | Running Simple Automation Commands
5.2. Review the output to verify that the module ran successfully, that the system is running
after the reboot, and that Ansible can successfully communicate with it.
82 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Lab
Outcomes
You should be able to:
• Access the Ansible Tower web console and inspect the default inventory.
• Log into the target host to verify the success of ad hoc commands.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
DO417-RHAE2.8-en-1-20200106 83
Chapter 2 | Running Simple Automation Commands
6. Log into the win1.example.com server to verify the installation of the web service, and
that it is currently running.
After verifying that Ansible successfully installed the web server feature and started the
service, disconnect from win1.example.com.
7. Use additional Ansible ad hoc commands to revert your the changes made to the
environment. Return to the EXECUTE COMMAND window for the win1.example.com
server.
Using the win_service module, stop the W3Svc web server on the win1.example.com
server.
8. Return to the EXECUTE COMMAND window for the win1.example.com server.
Using the win_feature module, uninstall the web server feature on the
win1.example.com server.
9. Using the win_reboot module, restart the win1.example.com server.
10. Using the win_ping module, verify that the win1.example.com server is running and
reachable by Ansible.
84 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
Solution
Outcomes
You should be able to:
• Access the Ansible Tower web console and inspect the default inventory.
• Log into the target host to verify the success of ad hoc commands.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1.1. From workstation, double-click the Ansible Tower shortcut icon on your Desktop
to access your Ansible Tower instance, located at http://tower.example.com.
1.2. Log in to Ansible Tower using student as the user name and RedHat123@! as the
password.
DO417-RHAE2.8-en-1-20200106 85
Chapter 2 | Running Simple Automation Commands
1.3. From the main dashboard window, select Inventories from the sidebar and choose
Default inventory from the inventories listed.
1.4. From the Default inventory window, select the HOSTS button and select the check
box next to the win1.example.com host entry.
86 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
1.5. After selecting win1.example.com, click RUN COMMANDS to enter the EXECUTE
COMMAND window for running ad hoc commands..
2. Using the win_ping module, verify that the win1.example.com server is running and
reachable by Ansible.
2.1. On the EXECUTE COMMAND window, select the module win_ping from the
MODULE list, and then click LAUNCH.
DO417-RHAE2.8-en-1-20200106 87
Chapter 2 | Running Simple Automation Commands
2.2. Review the output to verify that the module ran successfully, confirming that Ansible
could successfully communicate with the server.
3.1. Return to the EXECUTE COMMAND window for the win1.example.com server.
On the EXECUTE COMMAND window, select the module setup from the MODULE
list, and then click LAUNCH.
88 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
3.2. Review the output to verify that the module ran successfully, and that Ansible contacted
the system and profiled various aspects of the environment. Take note of the various
facts Ansible gathers, as you will use these in subsequent chapter exercises.
DO417-RHAE2.8-en-1-20200106 89
Chapter 2 | Running Simple Automation Commands
4.1. Return to the EXECUTE COMMAND window for the win1.example.com server.
On the EXECUTE COMMAND window, select the win_feature module from the
MODULE list. In the ARGUMENTS field, supply the arguments name=Web-Server
state=present, and then click LAUNCH.
4.2. Review the output to verify that the module ran successfully and that Ansible has added
the feature.
5.1. Return to the EXECUTE COMMAND window for the win1.example.com server.
90 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
On the EXECUTE COMMAND window, select the win_service module from the
MODULE list. In the ARGUMENTS field, supply the arguments name=W3Svc
state=started, and then click LAUNCH.
5.2. Review the output to verify that the module ran successfully and that Ansible has started
the service.
6. Log into the win1.example.com server to verify the installation of the web service, and
that it is currently running.
After verifying that Ansible successfully installed the web server feature and started the
service, disconnect from win1.example.com.
DO417-RHAE2.8-en-1-20200106 91
Chapter 2 | Running Simple Automation Commands
Once you connect to the win1.example.com server, open the Server Manager by
selecting it from the Start Menu.
6.2. Select IIS from the menu to verify that the web service is installed and running.
7. Use additional Ansible ad hoc commands to revert your the changes made to the
environment. Return to the EXECUTE COMMAND window for the win1.example.com
server.
Using the win_service module, stop the W3Svc web server on the win1.example.com
server.
7.1. Return to the EXECUTE COMMANDS window for the win1.example.com server.
On the EXECUTE COMMAND window, select the win_service module from the
MODULE list. In the ARGUMENTS field, supply the arguments name=W3Svc
state=stopped, and then click LAUNCH.
92 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
7.2. Review the output to verify that the module ran successfully and that Ansible has
stopped the service.
DO417-RHAE2.8-en-1-20200106 93
Chapter 2 | Running Simple Automation Commands
Using the win_feature module, uninstall the web server feature on the
win1.example.com server.
8.1. Return to the EXECUTE COMMAND window for the win1.example.com server.
On the EXECUTE COMMAND window, select the win_feature module from the
MODULE list. In the ARGUMENTS field, supply the arguments name=Web-Server
state=absent, and then click LAUNCH.
8.2. Review the output to verify that the module ran successfully and that Ansible has
removed the feature.
94 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
9.1. On the EXECUTE COMMAND window, select the win_reboot module from the
MODULE list, and then click LAUNCH.
DO417-RHAE2.8-en-1-20200106 95
Chapter 2 | Running Simple Automation Commands
9.2. Review the output to verify that the module ran successfully and that Ansible restarted
the server.
10. Using the win_ping module, verify that the win1.example.com server is running and
reachable by Ansible.
10.1. On the EXECUTE COMMAND window, select the win_ping module from the
MODULE list, and then click LAUNCH.
10.2.Review the output to verify that the module ran successfully, that the system is running
after the reboot, and that Ansible can successfully communicate with it.
96 DO417-RHAE2.8-en-1-20200106
Chapter 2 | Running Simple Automation Commands
DO417-RHAE2.8-en-1-20200106 97
Chapter 2 | Running Simple Automation Commands
Summary
In this chapter, you learned:
• Ansible communicates with Windows hosts using Windows Remote Management (WinRM),
which is enabled by default since Windows Server 2012.
• You can define connection settings for your Windows-based hosts in inventory variables at the
inventory level, for specific groups, or on a host-by-host basis.
• Ansible Tower credentials allow you to store sensitive authentication data such as passwords or
authentication information used to access source code repositories.
• Ad hoc commands allow you to execute an Ansible module as a one-time task on a managed
host, or on a selection of hosts in an inventory.
98 DO417-RHAE2.8-en-1-20200106
Chapter 3
Implementing Ansible
Playbooks
Goal Write a simple playbook to automate tasks on
multiple Microsoft Windows-based hosts, and then
use Red Hat Ansible Tower to run it.
DO417-RHAE2.8-en-1-20200106 99
Chapter 3 | Implementing Ansible Playbooks
Writing Playbooks
Objectives
After completing this section, you should be able to write a basic Ansible Playbook and store it in a
Git repository.
A play is an ordered set of tasks run against hosts selected from your inventory. A playbook is a
text file containing a list of one or more plays to run in a specific order.
Plays allow you to change a lengthy, complex set of manual administrative tasks into an easily
repeatable routine with predictable and successful outcomes. In a playbook, you can save the
sequence of tasks in a play in a human-readable and immediately runnable form. Playbooks may
be authored in either YAML or JSON formats. Because of the way in which they are written, the
tasks themselves document the steps needed to deploy your application or infrastructure.
Any ad hoc command can be rewritten as a single task play, and then saved in a playbook for use
and later reuse.
100 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
A playbook is a text file written in YAML format, and normally is saved using the standard file
extension .yml. The playbook uses indentation with space characters to indicate the structure
of its data. YAML does not place strict requirements on how many spaces are used for the
indentation, but there are two basic rules:
• Data elements at the same level in the hierarchy (such as items in the same list) must have the
same indentation.
• Items that are children of another item must be indented more than their parents.
The ad hoc command from Figure 3.1 could be converted into the Ansible Playbook as illustrated:
---
- name: Converted ad hoc command example
hosts: win1.example.com
tasks:
- name: Make sure the spooler service is started
win_service:
name: spooler
state: started
Important
Only the space character can be used for indentation; tab characters are not
allowed. Specifically, a two space indentation is standard in YAML files written for
Ansible.
In this course, you use Visual Studio Code as your text editor. However, there are
many other options to consider when you are working with Ansible in a production
environment. Visual Studio Code has extensions that allow customizations for
various languages and preferences, including syntax assistance for YAML. Each
editor has settings that you can adjust to make it easier to edit your YAML
playbooks.
A playbook begins with a line consisting of three dashes (---) as the start of a document marker.
It may end with three dots (...) as the end of a document marker, although in practice these are
often omitted.
In between those markers, the playbook is defined as a list of plays. An item in a YAML list starts
with a single dash followed by a space. For example, a YAML list might appear as follows:
DO417-RHAE2.8-en-1-20200106 101
Chapter 3 | Implementing Ansible Playbooks
- apple
- orange
- grape
In the example playbook, the line after --- begins with a dash, and starts the first (and only) play
in the list of plays.
The play itself is a collection of key-value pairs. Keys in the same play should have the same
indentation. The following example shows a YAML snippet with three keys. The first two keys have
simple values. The third key has a list of three items as a value.
The original example play has three keys, name, hosts, and tasks; these keys all have the same
indentation.
The first line of the example play starts with a dash and space, indicating that the play is the first
item in a list, followed by the first key, which is the name attribute. The name key associates an
arbitrary string with the play as a label. This label identifies the purpose of the play. The name key
is optional, but is recommended because it helps to document your playbook. This is especially
useful when a playbook contains multiple plays.
The second key in the play is a hosts attribute, which specifies the hosts against which tasks in
the play are run. Like the argument for the ansible command, the hosts attribute takes a host
pattern as a value, such as the names of managed hosts or of groups in the inventory.
hosts: win1.example.com
Finally, the last key in the play is the tasks attribute, whose value specifies a list of tasks to run
for this play. This example has a single task that runs the win_service module with specific
arguments, to ensure that the spooler service has been started.
tasks:
- name: Make sure the spooler service is started
win_service:
name: spooler
state: started
The tasks attribute is the part of the play that actually lists, in order, the tasks to be run on the
managed hosts. Each task in the list is itself a collection of key-value pairs.
In the preceding example, the only task in the play has two keys:
• name is an optional label that documents the purpose of the task. It is a good idea to name
all your tasks to document the purpose of each step of the automation process. This label is
102 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
intended to be human readable, and is shown in the output during the play execution, as Ansible
performs each task.
• win_service is the module to run for this task. Arguments are passed as a collection of key-
value pairs, which are children of the module (name and state).
The following is another example of a tasks attribute with multiple tasks, using the
win_service module to ensure that several network services are configured to start at boot: the
win_regedit module to delete a registry key, and the win_region module to set the region
format to United States English:
tasks:
- name: Ensure that WinRM is started when the system has settled
win_service:
name: WinRM
start_mode: delayed
Important
The order in which the plays and tasks are listed in a playbook is important, because
Ansible runs them in the same order.
The playbooks you have seen so far are basic examples; more sophisticated examples of plays
and tasks are presented later in this course. Information on the various modules provided
with Ansible is available on the web at https://docs.ansible.com/ansible/latest/modules/
modules_by_category.html, but a number of frequently useful modules will be introduced in
upcoming sections.
References
Intro to Playbooks — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html
DO417-RHAE2.8-en-1-20200106 103
Chapter 3 | Implementing Ansible Playbooks
Guided Exercise
Writing Playbooks
In this exercise, you will write a basic Ansible Playbook and store it in a remote Git repository.
Outcomes
You should be able to use Visual Studio Code to write a simple Ansible Playbook and store it
in a Git repository.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch Visual Studio Code and install the Red Hat YAML extension.
1.2. Change to the Extensions view, and search the extensions marketplace for yaml.
1.3. Select the YAML extension at the top of the list and click Install.
2.1. Click View → Command Palette or type Ctrl+Shift+P to open the command
palette.
Type clone, and then select Git: Clone to clone a repository.
104 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
directory of the training user as the repository location, and then click Select
Repository Location. This clones the remote repository into the playbooks folder.
2.3. From the dialog that appears after cloning select Open to view the files.
3. Click the icon next to PLAYBOOKS to create a new file, and then name that file install-
iis.yml.
---
5. Add the name of the playbook, and the hosts to be targeted by its execution.
---
- name: Install the IIS web service
hosts: win1.example.com
---
- name: Install the IIS web service
hosts: win1.example.com
tasks:
DO417-RHAE2.8-en-1-20200106 105
Chapter 3 | Implementing Ansible Playbooks
7. Add a task to install the Web-Server feature on the target server. Use the win_feature
Ansible module to accomplish this installation.
---
- name: Install the IIS web service
hosts: win1.example.com
tasks:
8. Add a task to start the W3Svc service on the target server. Use the win_service Ansible
module to accomplish this management task.
---
- name: Install the IIS web service
hosts: win1.example.com
tasks:
9. Add a final task to place a simple index.html file on the target server that contains
the phrase, "Hello World!" Use the win_copy Ansible module to accomplish this content
addition.
---
- name: Install the IIS web service
hosts: win1.example.com
tasks:
106 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Note
The completed file is available in the write.sol file in the solutions directory.
10. Click Save. Note the status icons at the bottom. An asterisk appears next to Master,
indicating that changes have been made.
11. Gp to the Source Control view, and then click + for the install-iis.yml file to stage
the changes.
12. Enter a commit message that describes the work you have done, and then press
Ctrl+Enter to commit the changes.
13. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
Click Yes or Ask Me Later when prompted.
DO417-RHAE2.8-en-1-20200106 107
Chapter 3 | Implementing Ansible Playbooks
Objectives
After completing this section, you should be able to configure a job template for a playbook in
Red Hat Ansible Tower, and use it to run the playbook on managed hosts.
Before you can run a playbook in Ansible Tower, you must first set up a job template specifying
where Ansible Tower can find the playbook, the inventory and credentials to use, and any special
settings controlling how you want the playbook to run. Creating a job template requires that you
perform the following steps, which will be covered in more detail later in this section:
• Create an SCM credential that Ansible Tower can use to authenticate to your version control
system.
• Create a project that specifies the location of the playbook repository in your version control
system, the credential to access the version control system, and how to update the copy of the
repository used by Ansible Tower.
• Create a job template that specifies how you want the playbook to run, and that the playbook
can be reused in the same way again and again.
Generally, you only perform these steps once. Then, you "launch" the job template to run your
playbook, and the results are reported in the Ansible Tower interface. Each run of the playbook is
recorded as a job.
The remainder of this section will review these steps in detail, and discuss how to review the output
of your playbook run.
Note
Some of the instructions mention the role (permissions) a user needs to perform
specific steps. The admin user has all permissions and can perform all steps. Other
users created by the admin may have fewer permissions.
108 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
authentication tasks on them. Source Control Credentials, also called SCM Credentials, store
authentication information that Ansible Tower uses to access project materials stored in a version
control system like Git. SCM Credentials store the user name and the password or private key (and
private key passphrase, if any) required to authenticate access to the source control repository.
This is an outline of the procedure used create an SCM credential, so that Ansible Tower can
retrieve playbooks, roles, or other materials from a Git repository.
a. If creating a private SCM Credential, then there are no specific role requirements.
b. If creating an SCM Credential belonging to an organization, then log in as a user with the
Admin role for that organization.
3. In the CREATE CREDENTIAL pane, enter the required information for the new credential.
4. After selecting the Source Control credential type, the appropriate fields display in the
TYPE DETAILS section.
Enter authentication data in the respective fields. For example, you may need to specify a
user name. If a password is needed, you must enter that in the password field. If you are using
an SSH private key to authenticate, either copy and paste or drag and drop your private key
into the SCM PRIVATE KEY field. That key can be a passphrase encrypted SSH private
key, in which case you can provide the passphrase to Ansible Tower in the PRIVATE KEY
PASSPHRASE field.
DO417-RHAE2.8-en-1-20200106 109
Chapter 3 | Implementing Ansible Playbooks
Creating a Project
In Ansible Tower, the project resource represents a repository that is available in a version control
system (also referred to by Ansible Tower as a source control management or SCM system), and
has at least one playbook and its associated resources, such as files and templates. In this course,
you are using Git to manage these files. The design of Ansible Tower assumes that most Ansible
projects are in a version control system, and it can automatically retrieve updated materials for a
project from several commonly used version control systems.
Ansible Tower supports the ability to download and automatically get updates of project materials
from SCMs using Git, Subversion, or Mercurial.
The following procedure shows how to create a project in Tower that connects to an existing Git
repository, which contains Ansible Playbooks.
1. Log in to the Ansible Tower web interface as a user that has the Admin role.
2. Select Projects to go to the list of projects. Click + to create the new project.
4. To assign the project to a specific organization, click the magnifying glass icon for the
ORGANIZATION field, and then select an organization.
5. From the SCM TYPE list, select the Git item to instruct Ansible Tower to retrieve a Git
repository.
6. Enter the location of the Git repository in the SCM URL field.
Optionally, in the SCM BRANCH/TAG/COMMIT field, specify the branch, tag or commit of
the repository from which to obtain the contents.
110 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
If the repository server requires authentication, select a new credential in the SCM
CREDENTIAL field.
7. Finally, configure how the project gets updates from the version control system (SCM).
Available settings are Clean, Delete on Update, and Update Revision on Launch.
Clean
This SCM update option removes local modifications to project materials on Ansible Tower
before getting the latest revision from the source control repository.
Delete on Update
This SCM option completely removes the local project repository on Ansible Tower before
retrieving the latest revision from the source control repository. For large repositories, this
operation takes longer than Clean.
Update on Launch
This SCM option automatically updates the project from the source control repository each
time you use the project to launch a job. Ansible Tower tracks this update as a separate job. If
this option is not selected, you must update the project manually.
If you do not want to use these automatic settings, then you can manually update a project to
the latest version in the source control repository. The following procedure outlines the steps for
manually updating a project from an SCM source.
1. Log in as a user that has the Update role for the project.
3. A synchronize icon is visible under the ACTIONS column if the user has the Update role for a
given project. Click the icon to trigger an immediate update of a project.
DO417-RHAE2.8-en-1-20200106 111
Chapter 3 | Implementing Ansible Playbooks
Once you create a job template in Ansible Tower, you can reuse it to run the playbook
again, as often as needed. This allows you to rerun the playbook to correct any unexpected
misconfigurations or changes that have been made to your servers, or to prepare additional
servers that have been added to the inventory. Therefore, you normally set up the job template
only once, but you run it whenever you update your playbook, or periodically to ensure expected
host configuration. The Launch button, or icon, for a job template is used to run its playbook.
The following procedure details how to create a job template for running a playbook:
1. Log in to the Ansible Tower web interface as a user who has the Use role for an inventory, a
project, and a machine credential.
Click +, and then select Job Template to create a new job template.
3. Enter a name for the job template, and then select Run as the job type.
4. Click the magnifying glass icon for the INVENTORY field, and then select the desired
inventory to specify the managed hosts against which the job will execute.
5. Click the magnifying glass icon for the PROJECT field, and then select the project containing
the playbook that the job will execute.
6. Specify the playbook that the job will execute by selecting a playbook from the PLAYBOOK
list. The list shows all the playbooks that exist in the project.
7. Specify the credential to use for authenticating against the managed hosts.
8. Select a desired setting from the VERBOSITY list. This selection determines the level of
detail that is generated in the output of the job run.
112 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Note
For more information on the various fields, consult the Job Templates — Ansible
Documentation link provided in the references section.
The flexibility to change job parameters at the time the job executes encourages playbook reuse.
For example, rather than creating multiple job templates to run the same playbook on different
sets of managed hosts, create a single job template and select Prompt on launch for the
inventory field. When the job runs, you can specify the inventory for the play. Users can only select
Inventories on which they have the Use role.
DO417-RHAE2.8-en-1-20200106 113
Chapter 3 | Implementing Ansible Playbooks
Figure 3.9: A job template prompting for inventory when launching a job
Launching Jobs
Most of the time, you will already have your job template and all its components configured. All you
will usually do is to run your playbook by launching a job from an existing job template.
The following describes how to use an existing job template to run a playbook:
1. Log in as a user that has the Execute role for the job template.
3. Locate the job template to run from the list of templates, and then click the rocket icon
beneath the ACTIONS column to launch the job.
4. If you have enabled the Prompt on launch option for any of the fields, Tower prompts
you for input before executing the job. Enter the inputs for the parameter, and then click
LAUNCH to launch the job, as shown in Figure 3.10.
114 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
The job detail page is divided into two panes. The DETAILS pane displays details of the job
parameters, whereas the job output pane displays the output of the playbook run by the job.
Across the top of the job output pane is a summary detailing the number of plays and tasks that
were executed, the count of hosts that Tower used for executing the job, and also the time it took
for the job to execute. Additionally, you can use controls to maximize this pane to full-screen size,
or to download the output of the job execution.
Along the left side of the output section, you can use the + and - controls to expand or collapse
the output for each task in the playbook. Controls in the output section enable scrolling through
the output, as well as jumping to the beginning and end of the output, as shown in Figure 3.11.
DO417-RHAE2.8-en-1-20200106 115
Chapter 3 | Implementing Ansible Playbooks
To better understand how to interpret the output of the playbook run in the job record, consider
the following playbook:
---
- name: Converted ad hoc command example
hosts: win1.example.com
tasks:
- name: Make sure the spooler service is started
win_service:
name: spooler
state: started
A successful run of the playbook might result in the following job output:
A line is printed that displays the name of the play, and the name of each task in the play. Note
that the "Gathering Facts" task is a special task that normally runs by default and uses the setup
module automatically to set some machine-specific variables at the start of a play. Facts and fact
gathering will be covered later in the course.
Each task lists all the hosts on which the task ran, as well as the outcome of the task:
• ok means the task did not make any changes to the host.
116 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
• changed means that the task made a change to the system, and now the system is OK.
• fatal means there was a fatal error of some sort when running this task on this host. Ansible
will normally stop trying to run the playbook on that host for this job. Additional information
about the fatal error is included in the output.
• skipping means the playbook task was skipped for this host, probably due to conditional
execution, which will be discussed later in this course.
At the end of the play is a play recap that has a line for each host in the play, and how many tasks
matched certain outcomes for that host. If a task reported changed, then it will be also counted as
ok in the play recap. Besides ok, changed, and skipped, there are a number of other outcomes
reported in the play recap:
• unreachable is counted if the host could not be contacted over the network, or there was
some fatal error.
• failed counts tasks that failed, stopping execution of the playbook for that host.
• rescued counts tasks that failed, but were recovered by block rescue handling, which is covered
later in this course.
• ignored counts tasks that failed, but for which playbook execution was allowed to continue on
failure. This must be configured by the author of the playbook.
In general, Ansible Playbooks are idempotent and it is safe to run a playbook multiple times. If the
targeted managed hosts are already in the correct state, then no changes should be made. For
example, assume that the playbook from the previous example is run again:
This time, all tasks passed with status ok and no changes were reported.
DO417-RHAE2.8-en-1-20200106 117
Chapter 3 | Implementing Ansible Playbooks
References
Ansible Tower User Guide
http://docs.ansible.com/ansible-tower/latest/html/userguide/index.html
118 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Guided Exercise
Outcomes
You should be able to create a project and a job template, and to launch a job from the
Ansible Tower web interface.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Complete the section called "Guided Exercise: Writing Playbooks" presented earlier in this
chapter.
2. Create a new Source Control credential. The project that you create at a later step will use
this credential.
DO417-RHAE2.8-en-1-20200106 119
Chapter 3 | Implementing Ansible Playbooks
Field Value
ORGANIZATION Default
USERNAME student
PASSWORD RedHat123@!
Leave the SCM PRIVATE KEY and PRIVATE KEY PASSPHRASE fields blank.
Field Value
ORGANIZATION Default
120 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
3.4. Click SAVE to create the project. This automatically triggers the SCM update of the
project.
The CLEAN and UPDATE REVISION ON LAUNCH options ensure that the Ansible
Job refreshes the playbook from Git prior to running the job. Ansible Tower uses the
values provided in the SCM URL and SCM CREDENTIAL fields to retrieve a local
copy of the repository.
4.1. Scroll down the page and wait for a few seconds. In the list of projects, there is a status
icon to the left of the project, Run Practice. This icon is white at the start, red with
an exclamation mark when it fails, and green when it succeeds.
4.2. Click the status icon to show the detailed status page for the SCM update job. As
you can see in the DETAILS window, the SCM update job runs like any other Ansible
Playbook.
4.3. Verify that the status of the job in the DETAILS section shows Successful.
Field Value
DO417-RHAE2.8-en-1-20200106 121
Chapter 3 | Implementing Ansible Playbooks
Field Value
PLAYBOOK install-iis.yml
CREDENTIAL DevOps
Important
A solutions/install-iis.sol solution file is available in the playbooks git
repository.
5.5. Leave the other fields untouched and click SAVE to create the job template.
6.2. On the same line as the job template Install IIS, click the rocket icon on the right
to launch the job. This redirects you to a detailed status page for the running job.
6.3. Observe the live output of the running job for a moment.
122 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
6.4. Verify that the status of the job in the DETAILS pane displays Successful.
6.5. Read the output log to ensure that all tasks completed successfully. The play recap
at the bottom of the log should indicate that three tasks resulted in changes to the
win1.example.com host.
SSH password:
PLAY [The IIS web service is started] ******************************************
DO417-RHAE2.8-en-1-20200106 123
Chapter 3 | Implementing Ansible Playbooks
Note
If a playbook is improperly formatted, Ansible displays a status of FAILED and a red
exclamation mark. The error message in the log output can assist in debugging the
issue, and may point you directly to the problematic line.
You may also compare your playbook with the solution playbook solutions/
install-iis.sol in the playbooks git repository to complete this guided
exercise.
Hello, World!
8.1. Return to the Tower interface, and click Jobs. You will see a list of jobs that have
already run.
8.2. Click the top job in the list. This is the job that you just executed.
124 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Objectives
After completing this section, you should be able to write a playbook that uses multiple plays, and
per-play privilege escalation, to perform tasks as particular users.
This can be very useful when orchestrating a complex deployment, which may involve different
tasks on different hosts. You can write a playbook that runs one play against one set of hosts, and
when that finishes, runs another play against another set of hosts.
Writing a playbook that contains multiple plays is very straightforward. Each play in the playbook is
written as a top-level list item in the playbook, and each list item follows the same play syntax.
The following example shows a playbook with two plays. The first play runs against web hosts, and
the second play runs against app hosts.
---
# This is a playbook with two plays
DO417-RHAE2.8-en-1-20200106 125
Chapter 3 | Implementing Ansible Playbooks
You can enable privilege escalation for an entire playbook by selecting the ENABLE PRIVILEGE
ESCALATION check box for your job template. The privilege escalation method to use, the
alternative user to run, and the password for that user, are usually provided as part of your machine
credential.
You can use special keywords in your playbook to specify privilege escalation settings for a play, or
specific tasks in the play, that are different from those specified in your machine credential. These
keywords override the ENABLE PRIVILEGE ESCALATION selection for that play or task.
Use the become keyword to enable or disable privilege escalation, regardless of how it is defined
in the Ansible configuration file. Use the values yes or true to enable privilege escalation, and no
or false to disable it.
become: true
If you enable privilege escalation, then you can use the become_method keyword to define the
privilege escalation method to use during a specific play. The example below illustrates that runas
be used for privilege escalation.
become_method: runas
Additionally, you can use the become_user keyword to define the user account to execute tasks
for a specific play.
become_user: privileged_user
The next example demonstrates this playbook specifying that privilege escalation must be used
for one task, and the default settings used for another, with privilege escalation details defined by
the play:
126 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
For each module, the Ansible documentation website provides a summary of functions and
instructions, detailing how each specific function can be invoked with options to the module. The
documentation also provides useful examples that show you how to use each module, and how to
set their keywords in a task.
In subsequent sections, this course will introduce many modules specifically useful for
Microsoft Windows automation tasks.
YAML Comments
Use comments to aid playbook readability. In YAML, everything to the right of the number or hash
symbol (#) is a comment. If there is content to the left of the comment, precede the number
symbol with a space.
YAML Strings
Quotation marks around strings are not required, even if the string contains spaces. Optionally, you
can enclose strings in either double quotes or single quotes.
this is a string
'this is another string'
"this is yet another a string"
DO417-RHAE2.8-en-1-20200106 127
Chapter 3 | Implementing Ansible Playbooks
Double-quoted strings parse escape sequences identified by a prefixed backslash character. Use
escape sequences to insert special characters such as \t for tab or \b for backspace. If a string
contains a backslash character \ that is not used to start an escape sequence, enclose the string in
single quotes to prevent parsing. Variables embedded in strings that are enclosed in single quotes
will still work correctly.
There are two ways to write multiline strings. You can use the vertical bar (|) character to denote
that newline characters within the string are to be preserved.
include_newlines: |
Example Company
123 Main Street
Atlanta, GA 30303
You can also write multiline strings using the greater than (>) symbol to indicate that newline
characters should be converted to spaces, and that leading white spaces in the lines should be
removed. This method is often used to break long strings at space characters, so that they can
span multiple lines for better readability.
fold_newlines: >
This is an example
of a long string,
that will become
a single sentence once folded.
Strip the ending newline from the multiline string by appending the minus (-) symbol to the > or |
indicators.
no_newlines: >-
This example will
contain no newlines
at all.
YAML Dictionaries
You are familiar with collections of key-value pairs written as an indented block, as follows:
name: svcrole
svcservice: W3Svc
svcport: 80
You may be familiar with dictionaries written in a condensed format and enclosed in curly braces,
as follows:
In most cases, you should avoid the condensed format because it is harder to read and identify
changes in diff tools.
128 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
YAML Lists
You are familiar with lists that are written with the normal single dash syntax:
hosts:
- servera
- serverb
- serverc
tasks:
- name: shorthand form
service: name=W3Svc enabled=true state=started
tasks:
- name: preferred expanded form
service:
name: W3Svc
enabled: true
state: started
Avoid the shorthand form, and use the expanded form with one key-value pair per line.
The expanded form has more lines, but it is easier to work with. The keywords for the task are
stacked vertically, and are easier to differentiate. Your eyes can run straight down the play, with
less shifting from left to right. Also, the expanded syntax is native YAML, whereas, the shorthand
form is not. Syntax highlighting tools in modern text editors work more effectively if you use the
expanded format, rather than the shorthand format.
DO417-RHAE2.8-en-1-20200106 129
Chapter 3 | Implementing Ansible Playbooks
References
Intro to Playbooks — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html
130 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Guided Exercise
Outcomes
You should be able to construct and execute a playbook to manage configuration, and
perform administration, on a managed host.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor and, if you have not already cloned the playbooks
repository, clone it to your workstation.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
DO417-RHAE2.8-en-1-20200106 131
Chapter 3 | Implementing Ansible Playbooks
2. Create a new playbook, name it multi.yml, and then add the lines needed to start the
first play. The play creates a Windows file share on win1.example.com.
2.1. Navigating to File → New File or press Ctrl+N to create a new file.
2.2. Add a line to the beginning of the file consisting of three dashes. This indicates the
start of the YAML document.
---
2.3. Add the following line to provide a name for the play that describes the desired state.
2.4. Add the following line to specify that the play applies to the win1.example.com
managed host. Indent the line with two spaces (aligning with the name keyword above
it) to include it as part of the first play.
hosts: win1.example.com
2.5. Add the following line to define the beginning of the tasks list. Indent the line with
two spaces (aligning with the keywords above it) to include it as part of the first play.
tasks:
2.6. Save the file by navigating to File → Save or by pressing Ctrl+S. Name the playbook
multi.yml, and then save it in the playbooks repository that you created in the
Documents folder.
132 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
3. The first task in the play checks for the existence of a C:\shares\backup directory on
win1.example.com. If the directory does not exist, Ansible will create it.
Indent the first line of the task with four spaces. Under the tasks keyword in the first play,
add the following lines.
4. Add a task in the play that uses the win_share module to ensure that the C:\shares
\backup directory is shared on the network. Add the following lines to the playbook,
beneath the preceding task. Be sure to indent the first line with four spaces so that both
tasks are aligned vertically.
5. Start a new play within the same playbook to configure the win2.example.com host to
copy a file to the win1.example.com share for backup.
5.1. Add the following line without indentation to create a second play.
5.2. Specify win2.example.com as the target host for the play. Use two spaces in front of
hosts, so that hosts aligns horizontally with name directly above it.
hosts: win2.example.com
5.3. Add the following line to define the beginning of the tasks list for the second play.
DO417-RHAE2.8-en-1-20200106 133
Chapter 3 | Implementing Ansible Playbooks
tasks:
6. Create a task that copies example content into a file on win2.example.com for backup.
Indent the first line of the task with four spaces. Under the tasks keyword in the second
play, add the following lines.
7. Add a final task to the playbook that copies the file to the win1 file share. Indent the task
declaration in line with the previous task.
8. Verify that the final multi.yml playbook matches the following structured content.
---
- name: Backup directory is shared on win1
hosts: win1.example.com
tasks:
- name: Backup directory exists
win_file:
path: C:\shares\backup
state: directory
- name: Share is present
win_share:
name: backup
description: Critical backup files
path: C:\shares\backup
full: devops
state: present
134 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
9. Commit the changes to your local Git repository, and then push them to the remote
repository.
9.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
9.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
10. From workstation, access your Ansible Tower instance available at http://
tower.example.com. Connect as the student user and RedHat123@! as the password.
11.3. Click the GROUPS tab then select the Windows group.
DO417-RHAE2.8-en-1-20200106 135
Chapter 3 | Implementing Ansible Playbooks
11.4. Click the HOSTS tab to access the list of hosts in the group.
11.5. Click + and select New host to add a new host to the group.
Field Value
12. In the navigation pane, click Projects. Click the refresh icon next to the project name to
ensure the playbooks repository project fetches the new file.
13.2. Click + to create a new job template, and then select Job Template.
Field Value
PLAYBOOK multi.yml
CREDENTIAL DevOps
136 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
15. Observe the output and ensure that the STATUS of the job in the DETAILS pane displays
Successful. Read the output log to verify that both the Backup directory is
shared on win1 and the File is backed up from win2 plays executed.
16. Connect to the win1.example.com managed host to verify that the file has been copied
from win2.example.com.
16.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
16.2. Enter win1.example.com for Computer and EXAMPLE\student for User Name
and RedHat123@! as the password.
DO417-RHAE2.8-en-1-20200106 137
Chapter 3 | Implementing Ansible Playbooks
138 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. In a previous activity, you installed and started the web server. Run the remove-iis.yml
playbook to remove the service and the web page. To run this playbook, access Ansible Tower
from workstation, accessible at https://tower.lab.example.com, or by double-
clicking the Ansible Tower desktop icon.
Log in to Ansible Tower using admin as the user name and RedHat123@! as the password.
Update the Run playbooks project job template by selecting the remove-iis.yml
playbook.
Run the job template.
2. From workstation, access your GitLab instance at https://gitlab.example.com. You
can either use the desktop icon, or use Chrome to access the URL. Log in using student as
user name and RedHat123@! as the password. Make sure to select the LDAP authentication
method.
Access the playbooks repository and review the install-review.yml playbook. The
playbook installs the Web-Server service, starts the associated service, and create a custom
index.html file.
3. From workstation, access Visual Studio Code and clone the Git repository, accessible at
https://gitlab.example.com/student/playbooks.git, to C:\Users\student
\Documents\playbooks.
DO417-RHAE2.8-en-1-20200106 139
Chapter 3 | Implementing Ansible Playbooks
Add the playbooks folder to your workspace, and then make the following changes to the
install-review.yml playbook. Comments in the playbook indicate the changes to make.
• Give the first play (which reads - name: Install web service) a name of The IIS
web server is deployed and running.
• Rename the first task (which reads - name: Install service) to IIS service is
installed.
• Rename the second task (which reads - name: Start service) to IIS service is
running.
• Update the content of the index.html HTML file for the two tasks that target the two
different hosts by updating the content parameter. Give the modules a value of The
win1 web server has been provisioned by Ansible and The win2 web
server has been provisioned by Ansible.
4. Save your changes, commit the file using a message of Add better description to
playbook, and push your changes to the remote repository.
5. From Ansible Tower, update the Default inventory inventory by adding
win2.example.com as a host in the Windows group of that same inventory.
6. From Ansible Tower, update the Run playbooks project job template by instructing it to
use install-review.yml as the playbook.
Run the job template, and then review the job output; the output of the job indicates that
Ansible installs and configures the web server on the two hosts of the default inventory, and
then customizes the web page for each host.
7. From workstation open Chrome and access http://win1.example.com. Ensure that
the home page reads as follows:
140 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. In a previous activity, you installed and started the web server. Run the remove-iis.yml
playbook to remove the service and the web page. To run this playbook, access Ansible Tower
from workstation, accessible at https://tower.lab.example.com, or by double-
clicking the Ansible Tower desktop icon.
Log in to Ansible Tower using admin as the user name and RedHat123@! as the password.
Update the Run playbooks project job template by selecting the remove-iis.yml
playbook.
Run the job template.
1.1. From workstation double-click the Ansible Tower desktop icon to open the web
console.
Log in to Ansible Tower using admin as the user name and RedHat123@! as the
password.
1.2. Access the Run playbooks project job template, accessible from the Templates
link. Click the job template to edit it.
1.3. Select the remove-iis.yml in the PLAYBOOKS field, and then click SAVE to save
your changes.
DO417-RHAE2.8-en-1-20200106 141
Chapter 3 | Implementing Ansible Playbooks
1.4. To run the job template, click either the rocket icon or the LAUNCH button that is
available after saving your changes.
1.5. The output indicates that Ansible removes the index.html file, stops the web server
service, and removes the IIS service (Web-Server) from win1.example.com.
2.1. Double-click the GitLab desktop icon, and then log in to GitLab using student as the
user name and RedHat123@! as the password.
Review the install-review.yml playbook in the playbooks repository. To do so
navigate to Projects → Your projects and select student / playbooks. Click
142 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
3. From workstation, access Visual Studio Code and clone the Git repository, accessible at
https://gitlab.example.com/student/playbooks.git, to C:\Users\student
\Documents\playbooks.
Add the playbooks folder to your workspace, and then make the following changes to the
install-review.yml playbook. Comments in the playbook indicate the changes to make.
• Give the first play (which reads - name: Install web service) a name of The IIS
web server is deployed and running.
• Rename the first task (which reads - name: Install service) to IIS service is
installed.
• Rename the second task (which reads - name: Start service) to IIS service is
running.
• Update the content of the index.html HTML file for the two tasks that target the two
different hosts by updating the content parameter. Give the modules a value of The
win1 web server has been provisioned by Ansible and The win2 web
server has been provisioned by Ansible.
3.1. From workstation, access Visual Studio Code by double-clicking the Desktop
shortcut.
3.2. Clone the playbooks repository by opening the command palette. To do so, navigate
to View → Command Palette or press Ctrl+Shift+P.
Type clone, and then select Git: Clone to clone a repository.
DO417-RHAE2.8-en-1-20200106 143
Chapter 3 | Implementing Ansible Playbooks
Optionally, select Open from the window that displays after cloning to open the folder.
3.4. To add the playbooks folder to your workspace, navigate to File → Open Folder.
From the Windows Explorer, navigate to Local Disk (C:) → Users → student →
playbooks, and then click Select Folder.
3.5. Open the install-review.yml playbook in the architecture project. Make the
following changes:
• Give the first play a name of The IIS web server is deployed and running.
---
# Update the name of the play
- name: The IIS web server is deployed and running
hosts: all
...output omitted...
...output omitted...
# Change the name of this task
- name: IIS service is installed
win_feature:
name: Web-Server
state: present
...output omitted...
...output omitted...
# Change the name of this task
- name: IIS service is started
win_service:
name: W3Svc
state: started
...output omitted...
• Update the content of the index.html HTML file for the two tasks that target the
two different hosts by updating the content parameter. Give the modules a value of
The win1 web server has been provisioned by Ansible and The win2
web server has been provisioned by Ansible
...output omitted...
- name: The default web page is created on win1
hosts: win1.example.com
tasks:
# Change the content of the file
- name: Index file is created
win_copy:
content: "The win1 web server has been provisioned by Ansible"
dest: C:\Inetpub\wwwroot\index.html
144 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
After these changes are complete, the file should look like the following. The output
intentionally omits the comments.
---
- name: Web server is installed and running
hosts: all
tasks:
- name: IIS service is installed
win_feature:
name: Web-Server
state: present
Note
The completed solution file is available at solutions/install-review.sol of
the playbooks project.
4. Save your changes, commit the file using a message of Add better description to
playbook, and push your changes to the remote repository.
4.2. From the Visual Studio Code side bar, select Source Control to access the list of
changes.
DO417-RHAE2.8-en-1-20200106 145
Chapter 3 | Implementing Ansible Playbooks
4.3. Hover over install-review.yml to access the available options for this file. Click
Stage Changes to add your changes to the index.
4.4. In the Message text file, enter a message of Add better description to the
install playbook.
4.6. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
146 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
5.1. From Ansible Tower, click Inventories in the navigation pane to access the Default
inventory inventory.
Click the Default inventory to edit it.
5.3. Click the Windows inventory to access its content, and then select HOSTS to access
the hosts list.
5.4. Click the green plus sign, and then select Existing Host to add the previously created
win2.example.com host.
6. From Ansible Tower, update the Run playbooks project job template by instructing it to
use install-review.yml as the playbook.
Run the job template, and then review the job output; the output of the job indicates that
Ansible installs and configures the web server on the two hosts of the default inventory, and
then customizes the web page for each host.
6.1. From Ansible Tower, click Templates in the navigation pane to access the Run
playbooks project job template.
6.2. Click the job template to edit it. Select install-review.yml for the PLAYBOOK
field, and then click SAVE to update the job template.
6.4. This action redirects you to the job output. The output indicates that Ansible is able to
install and start the web server on win1 and win2, and create the custom index.html
HTML page on each server.
DO417-RHAE2.8-en-1-20200106 147
Chapter 3 | Implementing Ansible Playbooks
7.1. To ensure that the web server is running and that the web page is available on the server,
open a new tab in Chrome and access http://win2.example.com.
7.3. Open a new tab and access http://win2.example.com. The default web page
should read as follows:
148 DO417-RHAE2.8-en-1-20200106
Chapter 3 | Implementing Ansible Playbooks
Summary
In this chapter, you learned:
• A play is an ordered set of tasks run against hosts selected from your inventory.
• A playbook is a text file that contains a list of one or more plays to run in a specific order.
• Multiple plays can be very useful when orchestrating a complex deployment, which may involve
different tasks on different hosts.
• In Red Hat Ansible Tower, a project represents a repository that is available in a version control
system, and which holds at least one playbook.
• In Red Hat Ansible Tower, a job template represents a saved command that can be repeatedly
used to run a playbook from a project with a particular inventory, credentials, and configuration
settings.
DO417-RHAE2.8-en-1-20200106 149
150 DO417-RHAE2.8-en-1-20200106
Chapter 4
DO417-RHAE2.8-en-1-20200106 151
Chapter 4 | Managing Variables and Facts
Managing Variables
Objectives
After completing this section, you should be able to define and reference variables that affect
specific hosts or host groups, the play, or the global environment, and describe how variable
precedence works.
Variables provide a convenient way to manage dynamic values for a given environment in your
Ansible project. Examples of values that variables might contain include:
Naming Variables
Variable names must start with a letter, and they can only contain letters, numbers, and
underscores.
The following table illustrates the difference between invalid and valid variable names.
web-server
remote.file remote_file
1st_file file1
remoteserver$1 remote_server_1
remote_server1
152 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Defining Variables
You can define variables in a variety of places in an Ansible project. However, this can be simplified
to three basic scope levels:
Variable Scope
Global scope
Variables set from the command line or Ansible configuration.
Play scope
Variables set in the play and related structures.
Host scope
Variables set on host groups and individual hosts by the inventory, fact gathering, or
registered tasks.
If you define the same variable name at more than one level, the level with the highest precedence
wins. A narrow scope takes precedence over a wider scope; variables that you define in an
inventory are overridden by variables that you define by the playbook, which are overridden by
variables defined on the command line.
You can define play variables in multiple ways. One common method is to place a variable in a
vars block at the beginning of a play:
- hosts: all
vars:
user_name: joe
user_state: present
It is also possible to define play variables in external files. In this case, instead of using a vars
block in a play in the play, you can use the vars_files directive, followed by a list of names for
external variable files relative to the location of the playbook:
- hosts: all
vars_files:
- vars/users.yml
You then define the playbook variables in YAML format in those external variable files:
user_name: joe
user_state: present
DO417-RHAE2.8-en-1-20200106 153
Chapter 4 | Managing Variables and Facts
tasks:
# This line will read: Creates the user joe
- name: Creates the user {{ user_name }}
win_user:
# This line will create the user named Joe
name: "{{ user_name }}"
Important
When you use a variable as the first element to start a value, quotes are mandatory.
This prevents Ansible from interpreting the variable reference as starting a YAML
dictionary. The following message appears if quotes are missing:
win_service:
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 }}
with_items:
- "{{ foo }}"
154 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Figure 4.1 illustrates setting the ansible_user variable to devops for the win1.example.com
inventory host:
This approach has advantages and disadvantages. The advantage is that inventory variables
stored in Ansible Tower are consistent for all job templates that use that inventory. The
disadvantage is that you might find it easier to manage host-specific and group-specific variables
for a particular project by using playbook variable directories or by defining the variables in the
playbook. This section covers those approaches next.
To define group variables for the servers group, you would create a YAML file named
group_vars/servers, and then the contents of that file would set variables to values using the
same syntax as in a playbook:
user_name: joe
Likewise, to define host variables for a particular host, create a file with a name matching the host
in the host_vars directory to contain the host variables.
The following examples illustrate this approach in more detail. Consider a scenario where there are
two data centers to manage and the data center hosts are defined in the inventory:
• The datacenters group consists of the datacenter1 and datacenter2 groups; all four
hosts which are members of those groups are members of the datacenters group.
With this inventory, you can configure host_vars and group_vars files to set variables for
different hosts or groups. You do not have to have a file for a host or a group if it would be empty.
If you wanted to make settings for each host or group individually, you might have a directory
structure like this for your project:
DO417-RHAE2.8-en-1-20200106 155
Chapter 4 | Managing Variables and Facts
project
├── group_vars
│ ├── all
│ ├── datacenters
│ ├── datacenters1
│ └── datacenters2
├── host_vars
│ ├── demo1.example.com
│ ├── demo2.example.com
│ ├── demo3.example.com
│ └── demo4.example.com
└── playbook.yml
time_server: 192.168.1.254
Alternatively, you could use the all host group to affect all hosts in the inventory.
time_server: 192.168.1.254
In group_vars/datacenter2:
time_server: 192.168.2.254
smtp_relay: 192.168.1.20
156 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Note
The Ansible Tower documentation recommends defining inventory variables in the
inventory itself instead of using directories (at https://docs.ansible.com/ansible-
tower/latest/html/userguide/best_practices.html). No reason is specified.
The authors of this course believe that there are some disadvantages to that
approach. For example, there is no version control tracking changes to the inventory
fields for objects in Ansible Tower, and checking settings can involve a lot of clicking
through the user interface.
However, it is true that by setting the variable settings in the inventory itself, the
variables will be consistent between multiple projects that share the same inventory.
In the following example, the variable prototype_server is being set to true as an extra
variable in a job template.
Extra variables can be useful when you need to override the defined value for a variable for a one-
off run of a playbook.
DO417-RHAE2.8-en-1-20200106 157
Chapter 4 | Managing Variables and Facts
user1_first_name: Bob
user1_last_name: Jones
user1_full_name: Robert Richard Jones
user2_first_name: Anne
user2_last_name: Cook
user2_full_name: Anne Marie Cook
This could be rewritten as an array called users, where each user is an element in the array. Each
user is a hash, meaning that it contains a set of key-value pairs. This means that users is an array
of hashes.
users:
bjones:
first_name: Bob
last_name: Jones
full_name: Robert Richard Jones
acook:
first_name: Anne
last_name: Cook
full_name: Anne Marie Cook
You can then use the following variables to access user data:
# Returns 'Bob'
users.bjones.first_name
# Returns 'Bob'
users['bjones']['first_name']
Important
The dot notation can cause problems if the key names are the same as names of
Python methods or attributes, such as discard, copy, add, and so on. Using the
bracket notation can help avoid conflicts and errors.
Both syntaxes are valid, but to make troubleshooting easier, Red Hat recommends
that you use one syntax consistently in all files throughout any given Ansible project.
158 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
The following playbook demonstrates how to capture the results of a task for debugging purposes:
---
- name: Installs a package and prints the result
hosts: demo.example.com
tasks:
- name: Copy install package
win_copy:
src: files/7z1900-x64.exe
dest: C:\7z1900-x64.exe
- debug:
var: install_result
When you run the playbook, Ansible uses the debug module to display the value of the
install_result registered variable.
DO417-RHAE2.8-en-1-20200106 159
Chapter 4 | Managing Variables and Facts
References
Inventory — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
160 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Guided Exercise
Managing Variables
In this exercise, you will define variables and use them in a playbook.
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Note
This activity requires win2.example.com in the Default inventory
inventory. You added the host in a previous exercise. If the host is not present,
follow the instructions in the Implementing Multiple Plays guided exercise to
create it.
In the following activity, you will refactor an Ansible Playbook to use variables. The playbook
installs and configures the IIS service with a site on both hosts. A default index.html
file is transferred to the servers. The default web page is accessible at https://
gitlab.example.com/student/variables/blob/master/files/index.html.
1.1. On workstation, double-click the GitLab icon on the desktop to access your GitLab
instance.
1.2. Log in to GitLab via LDAP using student as the user name and RedHat123@! as the
password.
To access the variables repository, click student / variables in the list of projects.
DO417-RHAE2.8-en-1-20200106 161
Chapter 4 | Managing Variables and Facts
1.3. Click the manage.yml playbook to review it. The playbook installs and configures IIS.
2.1. Double-click the Visual Studio Code icon on the desktop to open the Visual Studio
Code editor.
2.2. Click View → Command Palette or press Ctrl+Shift+P to open the command
palette.
Type Git: Clone to clone a repository.
162 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
3. In this step, you will create a new folder for group variables and add a variables file for the
Windows group that defines the following variables:
• The iis_packages_name variable is a list, defining the features to install. It will contain
the following three entries:
• Web-Server
• NET-Framework-Core
• Web-Asp-Net45
• The iis_site_path variable specifies the root directory of your IIS site. Give the
variable a value of C:\sites\variables.
• The iis_site_name variable specifies the name of the IIS site (DO417-variables).
• The iis_site_port variable specifies the port that the site listens on (8080).
3.2. Right-click the group_vars folder to create a new Windows file within it.
DO417-RHAE2.8-en-1-20200106 163
Chapter 4 | Managing Variables and Facts
3.3. In the Windows file, define the iis_packages_name variable as a list to indicate to
Ansible the list of features to install as the following:
iis_packages_name:
- Web-Server
- NET-Framework-Core
- Web-Asp-Net45
3.4. Define the iis_site_path variable, which specifies the root directory of your IIS site.
Give the variable a value of C:\sites\variables.
...output omitted...
iis_site_path: C:\sites\variables
...output omitted...
iis_site_name: "DO417-variables"
...output omitted...
iis_site_port: 8080
164 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
iis_packages_name:
- Web-Server
- NET-Framework-Core
- Web-Asp-Net45
iis_site_path: C:\sites\variables
iis_site_name: "DO417-variables"
iis_site_port: 8080
Note
The completed variables file is accessible at solutions/group_vars/Windows.
4. In the following steps, you will use Visual Studio Code to edit the manage.yml playbook
and make the following changes:
The content requires both the iis_site_path variable and index.html since the
variable does not define the HTML file to install.
Parameter Variable
name iis_site_name
port iis_site_port
hostname inventory_hostname
physical_path iis_site_path
...output omitted...
- name: IIS and .Net 4.5 are installed
win_feature:
name: "{{ iis_packages_name }}"
include_management_tools: True
state: present
4.2. For the win_file module used in the Site directory is created task, replace
the value of the path parameter with the iis_site_path variable.
DO417-RHAE2.8-en-1-20200106 165
Chapter 4 | Managing Variables and Facts
...output omitted...
- name: Site directory is created
win_file:
path: "{{ iis_site_path }}"
state: directory
4.3. For the win_copy module, replace the path of the dest parameter with the
iis_site_path variable.
The content should use both the variable and index.html, as the variable does not
define the HTML file to install.
Important
Use single quotes to ensure the backslash is not interpreted as an escape sequence.
...output omitted...
- name: Index page for site is installed
# Reuse the variable for the site path
win_copy:
src: files/index.html
dest: '{{ iis_site_path }}\index.html'
4.4. For the win_iis_website module, replace the module variables as follows:
Parameter Variable
name iis_site_name
port iis_site_port
hostname inventory_hostname
physical_path iis_site_path
...output omitted...
- name: IIS site is created
win_iis_website:
name: "{{ iis_site_name }}"
state: started
port: "{{ iis_site_port }}"
ip: "*"
hostname: "{{ inventory_hostname }}"
application_pool: DefaultAppPool
physical_path: "{{ iis_site_path }}"
parameters: logfile.directory:C:\sites\logs
166 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
4.5. For the win_firewall_rule module, replace the value of the localport
parameter with the iis_site_port variable. The content should match the following:
...output omitted...
- name: Firewall rule is enabled
win_firewall_rule:
name: HTTP
localport: "{{ iis_site_port }}"
action: allow
direction: in
protocol: tcp
state: present
enabled: yes
DO417-RHAE2.8-en-1-20200106 167
Chapter 4 | Managing Variables and Facts
win_firewall_rule:
name: HTTP
localport: "{{ iis_site_port }}"
action: allow
direction: in
protocol: tcp
state: present
enabled: yes
5. Save your changes, commit the file using a message of Define variables for the
manage.yml playbook and push your changes to the remote repository.
5.2. From the Visual Studio Code side bar, select Source Control to access the list of
changes.
5.3. Hover over the manage.yml playbook to access the available options for the file. Click
Stage Changes to add your changes to the index.
5.5. In the Message text file, enter a message of Define variables for the
manage.yml playbook.
5.7. To push your local changes to the remote repository, click the synchronize button
at the bottom of the editor. This instructs Visual Studio Code to synchronize your
repository with the remote copy.
6. In Ansible Tower, edit the Run variables project job template, to use manage.yml as
the playbook.
168 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
After updating the job template, run it and review the job output. The output of the job
indicates that Ansible installed and configured the web server on the two hosts of the
default inventory. It then customized the web page for each host.
6.1. Access Ansible Tower by double-clicking Ansible Tower from your desktop. Log in to
Ansible Tower using admin as the user name and RedHat123@! as the password.
6.2. In Ansible Tower, click Templates then Run variables project job template on
the side menu.
6.3. Click the job template to edit it. Select manage.yml for the PLAYBOOK field and
click SAVE to update the job template.
6.5. The action redirects you to the job output. The output indicates that Ansible is able
to install and start the web server on win1 and win2, and create the custom DO417-
variables site on each server.
The play also opens the firewall to allow connections on port 8080.
DO417-RHAE2.8-en-1-20200106 169
Chapter 4 | Managing Variables and Facts
Note
If you are not able to access the web pages and need to clean the resources on the
hosts, run the remove-iis.yml Ansible Playbook available in the variables
project directory. The playbook removes the IIS site and the firewall rule.
After cleaning the resources, make changes to your playbook and rerun it.
170 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
DO417-RHAE2.8-en-1-20200106 171
Chapter 4 | Managing Variables and Facts
Managing Secrets
Objectives
After completing this section, you should be able to describe approaches to protecting sensitive
data used by playbooks.
There are a number of ways in which you can address this risk. Each has its own advantages and
disadvantages. Some approaches include:
• Protect structured files with the Ansible Vault tool included with Ansible on a Linux system or
container.
• Protect structured files with the Ansible Vault tool included with Ansible on a Windows system
that is installed with Windows Subsystem for Linux (WSL).
• Protect structured files with Ansible Vault by using Jordan Borean's unofficial PowerShell
cmdlets on a Windows system.
The main limitation of Ansible Vault is that the Ansible command-line tools are not currently
supported on Microsoft Windows operating systems. This means it can be a challenge to prepare
the encrypted file with Ansible Vault if you are working on a Windows-based workstation. When
you have an encrypted file, however, Ansible Tower can decrypt it when you run the job as long as
you provide the correct Vault credential as one of the credentials in the job template.
Important
Ansible Vault does not implement its own cryptographic functions but rather uses
an external Python toolkit. Files are protected with symmetric encryption using
AES256 with a password as the secret key. Note that the way this is done has not
been formally audited by a third party.
172 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
To encrypt an existing file, you can use the ansible-vault encrypt command:
You can use the ansible-vault rekey command to change the password on the file, and the
ansible-vault decrypt command to permanently decrypt the file.
The disadvantage of this approach in a Windows-centric environment is that you need to edit your
secret files on a Linux workstation.
A Vault credential is created in Ansible Tower the same way as a machine credential, except that
you select Vault for the credential type and provide the Vault password to the credential.
Include the Vault credentials and the machine credentials in the job template:
DO417-RHAE2.8-en-1-20200106 173
Chapter 4 | Managing Variables and Facts
Remember that the preferred way to manage group variables and host variables is to create
directories at the playbook level. The group_vars directory normally contains variable files
with names that match the host groups to which they apply. The host_vars directory normally
contains variable files with names that match the host names of the managed hosts to which they
apply.
However, instead of using files in group_vars or host_vars, you can also use directories for
each host group or managed host. These directories can then contain multiple variable files, all of
which are used by the host group or managed host. For example, in the following project directory
for playbook.yml, members of the webservers host group use variables in the group_vars/
webservers/vars file, and demo.example.com uses the variables in both host_vars/
demo.example.com/vars and host_vars/demo.example.com/vault:
.
├── ansible.cfg
├── group_vars
│ └── webservers
│ └── vars
├── host_vars
│ └── demo.example.com
│ ├── vars
│ └── vault
├── inventory
└── playbook.yml
In this scenario, the advantage is that you can place most variables for demo.example.com in
the vars file, but you can protect sensitive variables by placing them separately in the vault file.
Then you can use ansible-vault to encrypt the vault file and leave the vars file as plain text.
There is nothing special about the file names being used in this example inside the host_vars/
demo.example.com directory. That directory could contain more files, some encrypted by
Ansible Vault and some which are not.
174 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
You can also protect playbook variables (as opposed to inventory variables) with Ansible Vault.
You can place sensitive playbook variables in a separate file encrypted by Ansible Vault and which
is included in the playbook through a vars_files directive. This can be useful because playbook
variables take precedence over inventory variables.
If you are using multiple vault passwords with your playbook, make sure that each encrypted file
is assigned a vault ID, and that you enter the matching password with that vault ID when running
the playbook. This ensures that the correct password is selected first when decrypting the vault-
encrypted file, which is faster than forcing Ansible to try all the vault passwords you provided until
it finds the right one.
You could install the Ansible tools under the Windows Subsystem for Linux (WSL) environment on
a Windows workstation. This might work, but is unsupported and not recommended by Red Hat.
One of the Ansible developers, Jordan Borean, has written some unofficial PowerShell cmdlets
that you could use to encrypt and decrypt Ansible Vault files. The GitHub repository for his code
is at https://github.com/jborean93/PowerShell-AnsibleVault. This is code written by a member of
the open source community and is also not supported by Red Hat.
Important
Neither of these options are supported by Red Hat, but we are providing information
about them for your reference.
Custom credentials are composed of inputs and injectors. Inputs define the fields that the
credential contains, such as a user name, or a token. Injectors define how the information is made
available for use in playbooks.
Even though these are called credentials, you are not restricted to using them for authentication
purposes. For example, you could store purchased software details such as a license key, serial
number, or activation code. The following images show a simple custom credential used to store a
username and password for proxy authentication.
DO417-RHAE2.8-en-1-20200106 175
Chapter 4 | Managing Variables and Facts
• CyberArk Conjur
One of the benefits of a centralized secret service is that sensitive information is available to
members of the organization without requiring access to Ansible Tower.
176 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
The following image shows an example of the additional fields required when creating a credential
mapping to an external secret service.
References
Vault — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_vault.html
PowerShell-AnsibleVault
https://github.com/jborean93/PowerShell-AnsibleVault
DO417-RHAE2.8-en-1-20200106 177
Chapter 4 | Managing Variables and Facts
Quiz
Managing Secrets
Choose the correct answers to the following questions:
1. Which two of the following methods are unsupported ways of running Ansible Vault on
Windows? (Choose two.)
a. Ansible PyInstaller
b. Ansible PowerShell module
c. AnsiblePE
d. Bash for Windows
e. Windows Subsystem for Linux
3. Which two groups of information are required for a custom credential type? (Choose
two.)
a. Inputs
b. Pipes
c. Extractors
d. Exports
e. Injectors
4. Which five of the following secret management systems are supported by Ansible
Tower? (Choose five.)
a. Microsoft Azure Key Management System
b. HashiCorp Vault Key-Value Store
c. Cloudflare Red October
d. CyberArk Conjur
e. Lyft Confidant
f. CyberArk Application Identity Manager
g. HashiCorp Vault SSH Secrets Engine
h. Pinterest Knox
178 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Solution
Managing Secrets
Choose the correct answers to the following questions:
1. Which two of the following methods are unsupported ways of running Ansible Vault on
Windows? (Choose two.)
a. Ansible PyInstaller
b. Ansible PowerShell module
c. AnsiblePE
d. Bash for Windows
e. Windows Subsystem for Linux
3. Which two groups of information are required for a custom credential type? (Choose
two.)
a. Inputs
b. Pipes
c. Extractors
d. Exports
e. Injectors
4. Which five of the following secret management systems are supported by Ansible
Tower? (Choose five.)
a. Microsoft Azure Key Management System
b. HashiCorp Vault Key-Value Store
c. Cloudflare Red October
d. CyberArk Conjur
e. Lyft Confidant
f. CyberArk Application Identity Manager
g. HashiCorp Vault SSH Secrets Engine
h. Pinterest Knox
DO417-RHAE2.8-en-1-20200106 179
Chapter 4 | Managing Variables and Facts
Managing Facts
Objectives
After completing this section, you should be able to reference data about managed hosts using
Ansible facts, and configure custom facts on managed hosts.
• The IP addresses.
Facts are a convenient way to retrieve the state of a managed host and to determine what action
to take based on that state. For example:
• You can decide to restart a server via a conditional task, which runs or not based on a fact
containing the managed host's current kernel version.
• You can customize a database based on the available memory reported by a fact.
• You can set the IPv4 address based on the value of a fact.
Usually, every play automatically runs the setup module before the first task to gather facts.
This is reported as the Gathering Facts task in Ansible 2.3 and later, or simply as setup in
earlier versions of Ansible. By default, you do not need to have a task to run setup in your play. It is
normally run automatically for you.
To see which facts Ansible gathers for your managed hosts, you can run a short playbook that
gathers facts and uses the debug module to print the value of the ansible_facts variable.
180 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
When you run the playbook, the job output displays the facts:
The playbook displays the contents of the ansible_facts variable in JSON format as a hash
(dictionary) of variables. You can browse the output to see what facts are gathered, and to find
facts that you might want to use in your playbooks.
The following table shows some facts which Ansible might gather from a managed host and may
be useful in a playbook:
DO417-RHAE2.8-en-1-20200106 181
Chapter 4 | Managing Variables and Facts
Fact Variable
Note
Remember that when a variable's value is a hash, you can use either of two syntaxes
to retrieve the value. To take two examples from the preceding table:
When using facts in a playbook, Ansible dynamically substitutes the variable name for the fact with
its corresponding value:
---
- name: Fact usage
hosts: all
tasks:
- name: Prints various Ansible facts
debug:
msg: >
The current time on {{ ansible_facts['fqdn'] }}
is {{ ansible_facts['date_time']['time'] }}
The following output shows how Ansible is able to query the managed node and dynamically use
the system information to update the variable. You can also use facts to create dynamic groups of
hosts that match particular criteria.
PLAY ***********************************************************************
182 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Many older playbooks still use facts injected as variables, instead of the new syntax where they
appear under the ansible_facts variable.
The following table compares the old and new fact names.
ansible_facts['hostname'] ansible_hostname
ansible_facts['fqdn'] ansible_fqdn
ansible_facts['interfaces'] ansible_interfaces
ansible_facts['kernel'] ansible_kernel
Important
Currently, Ansible recognizes both the new fact naming system (using
ansible_facts) and the old pre-2.5 “facts injected as separate variables” naming
system.
...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\n
The 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...
DO417-RHAE2.8-en-1-20200106 183
Chapter 4 | Managing Variables and Facts
To disable fact gathering for a play, set the gather_facts keyword to no or false:
---
- name: This play gathers no facts automatically
hosts: large_farm
gather_facts: no
Even if gather_facts: no is set for a play, you can manually gather facts at any time by running
a task that uses the setup module:
tasks:
- name: Manually gather facts
setup:
...output omitted...
hostvars
Contains the variables for managed hosts, and can be used to get the values for another
managed host's variables. It does not include the managed host's facts if Ansible does not
gather them for that host.
group_names
Lists all groups the current managed host is in.
groups
Lists all groups and hosts in the inventory.
inventory_hostname
Contains the host name for the currently managed host as configured in the inventory. This
may be different from the host name reported by facts for various reasons.
There are a number of other “magic variables” as well. For more information, see Variable
Precedence — Ansible Documentation in the references section below. One way to get insight into
their values is to use the debug module to report on the contents of the hostvars variable for a
particular host:
...output omitted...
{
"hostvars[inventory_hostname]": {
"awx_job_template_name": "Run test-playbook project",
184 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
"ansible_windows_domain_member": true,
"tower_user_last_name": "student",
"ansible_os_product_type": "server",
"awx_user_email": "student@example.com",
"module_setup": true,
"tower_job_launch_type": "manual",
"awx_job_template_id": 9,
"gather_subset": [
"all"
],
"playbook_dir": "/var/lib/awx/projects/_7__test_playbook_repository",
"ansible_distribution_version": "10.0.17763.0",
"ansible_playbook_python": "/usr/bin/python2",
"ansible_forks": 10,
"ansible_owner_contact": "",
"ansible_facts": {
"lastboot": "2019-08-21 03:13:53Z",
"owner_contact": "",
"domain": "example.com",
"distribution_major_version": "10",
"swaptotal_mb": 0,
"kernel": "10.0.17763.0",
...output omitted...
},
"tower_user_email": "student@example.com",
"ansible_windows_domain": "example.com",
"awx_job_id": 32,
"ansible_distribution_major_version": "10",
"groups": {
"ungrouped": [
"win1.example.com"
],
"Windows": [],
"all": [
"win1.example.com"
]
},
"ansible_bios_date": "10/16/2017",
"inventory_hostname_short": "win1",
"tower_project_revision": "273396b95ae1d2724f38e4024fc4e1f7907f098f",
"omit": "__omit_place_holder__1594b921bbf58cfd665e07686cdff4ae5d1a7125",
"ansible_user_gecos": "",
"ansible_diff_mode": false,
"ansible_processor_threads_per_core": 2,
"ansible_win_rm_certificate_expires": "2022-08-19 03:00:51",
"ansible_product_name": "t3.medium",
"ansible_user_sid": "S-1-5-21-2938333969-4197073335-1435044025-500",
"ansible_run_tags": [
"all"
],
"awx_user_last_name": "student"
},
"changed": false,
DO417-RHAE2.8-en-1-20200106 185
Chapter 4 | Managing Variables and Facts
"_ansible_verbose_always": true,
"_ansible_no_log": false
}
References
setup - Gathers facts about remote hosts — Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/setup_module.html
186 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Guided Exercise
Managing Facts
In this exercise, you will gather Ansible facts from your managed hosts and use them in plays.
Outcomes
You should be able to:
• Gather facts from managed hosts using the setup, win_product_facts, and
win_disk_facts modules.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor. If you have not previously cloned the variables
repository, clone it to your workstation instance.
1.1. Click Search Windows and type code to search for and open Visual Studio Code.
1.2. Click View → Command Palette or press Ctrl+Shift+P to open the command
palette.
Type clone and select Git: Clone to clone a repository.
Use a repository URL of https://gitlab.example.com/student/
variables.git. When prompted, select the Documents folder as the repository
location. This clones the remote repository in to the C:\Users\student
\Documents\variables folder.
3. Open the facts.yml playbook to add tasks that gather system facts and create a
summary text file.
4. Modify the task named Product facts are collected to invoke the
win_product_facts module to gather Windows product and license information.
DO417-RHAE2.8-en-1-20200106 187
Chapter 4 | Managing Variables and Facts
5. Modify the task named Disk facts are collected to invoke the win_disk_facts
module to collect information about attached disks.
6. Modify the Summary is written task to write a selection of the facts in a summary text
file on the managed host's Desktop.
Use the win_copy module's content parameter to write simple content to a file.
Insert variables and facts into text using double braces {{ variable }}.
Access array values using numeric keys, as in myArray[index].
Identify the target file location with the dest parameter. Like other values,
filenames can also include dynamic variable substitution. Ansible resolves
ansible_facts['user_dir'] to C:\Users\devops.
---
- name: System summary is compiled
hosts: all
tasks:
- name: Product facts are collected
win_product_facts:
188 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
8. Save and commit the changes to your local Git repository and then push them to the
remote repository.
8.2. Navigate to the Source Control pane and click + next to facts.yml to stage the
changes.
8.3. Enter a brief commit message, then press Ctrl+Enter to commit the changes.
8.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
10. Edit the Run variables project job template to test your playbook.
10.4.Click SAVE to update the template, and then click LAUNCH to run the job.
11. Verify that the playbook completed successfully and review the log output.
11.1. When all tasks have completed, verify that the status in the DETAILS section
shows Successful. If the job was not successful, compare your playbook with the
solutions/facts.sol solution file in the variables Git repository.
DO417-RHAE2.8-en-1-20200106 189
Chapter 4 | Managing Variables and Facts
11.2. In the console output panel, click ok: [win1.example.com] under TASK [Gathering
Facts]. Observe the "ansible_facts" JSON dictionary in the modal window text
area.
11.3. In the console output panel, click ok: [win2.example.com] under TASK [Product
facts are collected]. Observe the "ansible_facts" JSON dictionary in the
modal window text area.
190 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
11.4. In the console output panel, click ok: [win1.example.com] under TASK [Disk
facts are collected]. Observe the "ansible_facts" JSON dictionary in the
modal window text area.
12. Connect to the win1.example.com managed host, and view the system summary file
that has been written to the desktop.
12.1. Click Search Windows and type remote to search for and open Remote Desktop
Connection.
12.2. Enter win1.example.com for Computer and devops for User Name and
RedHat123@! as the password. Note that devops is a local user, not a domain user, so
do not include the EXAMPLE domain.
DO417-RHAE2.8-en-1-20200106 191
Chapter 4 | Managing Variables and Facts
13. Connect to the win2.example.com managed host, and view the system summary file
that has been written to the desktop.
13.1. Click Search Windows and type remote to search for and open Remote Desktop
Connection.
13.2. Enter win2.example.com for Computer and devops for User Name and
RedHat123@! as the password.
192 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Note
This activity requires win2.example.com in the Default inventory
inventory. You added the host in a previous exercise. If the host is not present,
follow the instructions in the Implementing Multiple Plays guided exercise to
create it.
In this lab you will refactor a playbook to use group and registered variables, and to display page
file and memory information.
1. From workstation open Visual Studio Code and clone the variables repository
accessible at https://gitlab.example.com/student/variables.git to C:\Users
\student\Documents\variables, then open the folder.
2. Create a new folder for group variables if it does not exist, and a subfolder for the Windows
group. If a file named Windows exists already, then delete it first. Create a file named
vars.yml under the Windows folder that defines the pagefile variable. This variable
contains the following list of variables that control the win_pagefile module:
• remove: yes
• auto: no
3. Open review.yml for editing. Locate the task named Obtain page file
information. This task uses the win_pagefile module with no arguments to query the
DO417-RHAE2.8-en-1-20200106 193
Chapter 4 | Managing Variables and Facts
current configuration. Complete the Show original page file information task
using the debug module to display the value of the orig_pagefile_info registered
variable. Edit the Manage page files on virtual machines task to include the use
of the pagefile variables. Complete the Show new page file information task
using the debug module to display the new_pagefile_info registered variable. Complete
the Show current memory information task using the debug module to display the
ansible_facts['memtotal_mb'] fact.
4. Save the file and then commit and push your changes to the remote variables repository.
5. Open the Ansible Tower web UI and test your playbook using the Run variables
project job template. Review the job output and note the differences between the original
and new page file configuration.
6. Edit the Run variables project job template to use the review_finish.yml
playbook, then launch it to revert your changes.
194 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Note
This activity requires win2.example.com in the Default inventory
inventory. You added the host in a previous exercise. If the host is not present,
follow the instructions in the Implementing Multiple Plays guided exercise to
create it.
In this lab you will refactor a playbook to use group and registered variables, and to display page
file and memory information.
1. From workstation open Visual Studio Code and clone the variables repository
accessible at https://gitlab.example.com/student/variables.git to C:\Users
\student\Documents\variables, then open the folder.
1.2. Click View → Command Palette or press Ctrl+Shift+P to open the command
palette.
Type Git: Clone to clone a repository.
DO417-RHAE2.8-en-1-20200106 195
Chapter 4 | Managing Variables and Facts
Select the Documents folder and click Select Repository Location to clone the
variables repository to the variables folder.
2. Create a new folder for group variables if it does not exist, and a subfolder for the Windows
group. If a file named Windows exists already, then delete it first. Create a file named
vars.yml under the Windows folder that defines the pagefile variable. This variable
contains the following list of variables that control the win_pagefile module:
• remove: yes
• auto: no
2.1. Create a new group_vars folder at the top level of the project if it does not already
exist. To do so, right-click and select New Folder from the editor tree on the left side.
2.2. Create a new Windows folder in the group_vars folder. If a file named Windows exists
already, then delete it first.
2.4. In the vars.yml file, define the pagefile variable with its content being parameters
for the win_pagefile module.
---
pagefile:
remove: yes
auto: no
3. Open review.yml for editing. Locate the task named Obtain page file
information. This task uses the win_pagefile module with no arguments to query the
current configuration. Complete the Show original page file information task
using the debug module to display the value of the orig_pagefile_info registered
variable. Edit the Manage page files on virtual machines task to include the use
of the pagefile variables. Complete the Show new page file information task
using the debug module to display the new_pagefile_info registered variable. Complete
the Show current memory information task using the debug module to display the
ansible_facts['memtotal_mb'] fact.
3.1. Locate the task named Obtain page file information. This task uses the
win_pagefile module with no arguments to query the current configuration.
3.2. Complete the Show original page file information task using the debug
module to display the value of the orig_pagefile_info registered variable.
196 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
3.3. Locate the task named Manage page files on virtual machines. Replace the
instances of CHANGE_ME with the relevant pagefile variables. This task will make
changes to the page file configuration.
3.4. Complete the Show new page file information task using the debug module to
display the value of the pagefile_info registered variable.
3.5. Complete the Show current memory information task using the debug module
to display the value of the ansible_facts['memtotal_mb'] fact.
---
- name: Manage page files
hosts: Windows
tasks:
- name: Obtain page file information
win_pagefile:
register: orig_pagefile_info
DO417-RHAE2.8-en-1-20200106 197
Chapter 4 | Managing Variables and Facts
4. Save the file and then commit and push your changes to the remote variables repository.
4.2. From the Visual Studio Code side bar, select Source Control to access the list of
changes.
4.3. Hover over the review.yml playbook to access the available options for the file. Click +
to add your changes to the index.
4.4. In the Message field, enter a concise commit message and then press Ctrl+Enter.
4.5. To push your local changes to the remote repository, click the Synchronize Changes
button at the bottom of the editor. This instructs Visual Studio Code to synchronize your
repository with the remote copy.
5. Open the Ansible Tower web UI and test your playbook using the Run variables
project job template. Review the job output and note the differences between the original
and new page file configuration.
5.2. Click the name of the Run variables project job template.
5.4. Click SAVE to update the template and then click LAUNCH to run the job.
5.5. Review the output from the Show current page file information task to
confirm that the changes were successful.
...output omitted...
"orig_pagefile_info": {
"failed": false,
"automatic_managed_pagefiles": true,
"changed": false,
"pagefiles": []
}
...output omitted...
"new_pagefile_info": {
"failed": false,
"automatic_managed_pagefiles": false,
"changed": true,
"pagefiles": [
{
"caption": "C:\\ 'pagefile.sys'",
"maximum_size": 0,
"initial_size": 0,
"description": "'pagefile.sys' @ C:\\",
"name": "C:\\pagefile.sys"
}
6. Edit the Run variables project job template to use the review_finish.yml
playbook, then launch it to revert your changes.
198 DO417-RHAE2.8-en-1-20200106
Chapter 4 | Managing Variables and Facts
Summary
In this chapter, you learned:
• Variables, which have a global, play, or host scope, allow plays to be more flexible, providing
default values that can be overridden at various levels.
• When using variables in a play, you must quote them if they start the line. Unquoted variables at
the start of the line prevent the playbook from parsing.
• There are many methods for managing sensitive information in Ansible Tower Custom credential
types allow you to store non-standard credentials and keys, that are encrypted in the database.
• Ansible Tower supports integration with several centralized secret storage services from
CyberArk, HashiCorp, and Microsoft.
• Ansible Vault manages encryption of secrets and is included with Ansible, however it is only
supported on Linux. There are unsupported methods of managing Ansible Vault encrypted files
on Windows.
• Facts are pieces of information about a managed host, collected by the setup module. You can
use facts in conditional statements.
DO417-RHAE2.8-en-1-20200106 199
200 DO417-RHAE2.8-en-1-20200106
Chapter 5
DO417-RHAE2.8-en-1-20200106 201
Chapter 5 | Installing and Updating Software
Objectives
After completing this section, you should be able to ensure software is installed and up to date on
Microsoft Windows systems.
win_package
The original module for installing MSI or executable packages, which can be available locally
or remotely from a URL. There are several methods for determining whether the package
is already installed, such as creates_path and create_service, which check for the
presence of directories and services respectively. You can also specify the product_id
argument to check the registry for the installed product.
win_chocolatey
Chocolatey is a package manager for Windows, allowing you to search, install, and uninstall
packages from the Chocolatey repository. The win_chocolatey module, and its associated
sub-modules, support Chocolatey package management functions from Ansible.
win_feature
On a Windows server, roles and features are functions that you can add to a server, and that
are provided as part of the operating system. For example, to make a server provide the DHCP
service, use the Add Roles and Features wizard. The win_feature module allows you to
automate the addition and removal of roles and features.
The following example shows the win_chocolatey module installing several packages at once,
and specifies a proxy server to use with the proxy_url option.
Unlike win_feature, the win_chocolatey module does not support feedback on whether
a reboot is required. However, you can review the output of the command by capturing it with a
registered variable.
202 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
The following example shows how to install a DHCP server using the win_feature module. It
uses a registered variable to trigger the win_reboot module, if a reboot is required.
You can obtain a list of all feature names available on a system by running the Get-
WindowsFeature PowerShell command. Any features that have sub-features are listed in a tree
layout, with the sub-features indented beneath the main feature.
DO417-RHAE2.8-en-1-20200106 203
Chapter 5 | Installing and Updating Software
The following example shows how to install an MSI package using the win_package module. It
uses the creates_path parameter to test whether the package is already installed.
204 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
win_updates
This module works with the Windows Update service to automate the download and
installation of Windows updates. You may restrict the available categories from which to install
updates by providing the category_names argument. If required, this module can reboot the
system and continue installing updates, thus avoiding calls to the win_reboot module.
win_hotfix
This module manages the installation of hotfix .msu files. The package can be verified against
the identifier or the KB article, however, a mismatch on either one will prevent installation.
win_reboot
Use this module to control when a reboot occurs. For example, you could use the notify
option in a win_hotfix task to initiate a reboot handler task.
The following example shows the win_updates module. It is configured to only install critical
updates, to reboot the system if required, and to use a scheduled task instead of the become
method to escalate privileges.
This example shows the win_hotfix module. This module also supports notification of whether a
reboot is required.
The win_hotfix module can verify a hotfix package against the hotfix identifier, or the hotfix KB
article number. If verification fails, then the installation of the hotfix is aborted.
These primary modules are unlikely to be used on their own in a play. There are many other
modules that perform ancillary tasks, such as restarting services (win_service), unzipping
archives (win_unzip), or making configuration changes in the registry (win_regedit). The
modules that you require will depend on the complexity of the software being installed or updated.
DO417-RHAE2.8-en-1-20200106 205
Chapter 5 | Installing and Updating Software
References
Windows modules — Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html
206 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Guided Exercise
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From workstation, access your GitLab instance and review the updates repository.
1.1. From workstation, double-click the GitLab icon on your desktop to access your
GitLab instance.
Log in to GitLab using student as the user name, and RedHat123@! as the
password. Make sure to select LDAP as the authentication method.
1.2. The main page lists the available repositories. Select the updates repository for the
student namespace.
DO417-RHAE2.8-en-1-20200106 207
Chapter 5 | Installing and Updating Software
1.3. This repository contains a top-level updates.yml Ansible Playbook. In this playbook,
you will create two plays: one that manages the updates on your servers, and one that
runs Chocolatey for installing packages.
Click the file to inspect it.
2. Open the Visual Studio Code editor and clone the updates repository to your
workstation.
2.1. From workstation, open the Visual Studio Code editor by double-clicking the icon
on the desktop.
208 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
3. In Visual Studio Code, open the updates.yml playbook. Write the first play for managing
updates on your systems, as described in the following steps.
3.1. Update the first play by giving it a name of Manage updates on systems.
3.2. Instruct Ansible to target all hosts by using a value of all for the hosts directive
below the play name.
3.3. To support reusability, create three new variables: log_file, KB, and access_token.
The log_file variable points to a text file that contains the list of available updates.
Use a value of C:\Windows\Temp\ansible_available_updates.txt.
The KB variable contains the knowledge base number of the update that the playbook
installs. Give it a value of KB4465065.
Leave the access_token variable with an empty value. In a later step, you will
generate and pass this access token to the variable in Ansible Tower.
DO417-RHAE2.8-en-1-20200106 209
Chapter 5 | Installing and Updating Software
3.4. In the tasks section of the play, create the initial task using the win_updates module.
This initial module queries Microsoft update servers to determine if there are available
security updates. However, the task does not install them.
Name this task Microsoft update servers are queried. Use the
win_updates module with the following settings:
• Use a state of searched to search for new updates, but skip installation.
...output omitted...
tasks:
- name: Microsoft update servers are queried
win_updates:
category_names: SecurityUpdates
state: searched
log_path: "{{ log_file }}"
3.5. To display the file contents, create a new task using the win_shell module to run the
type command. The type command displays the contents of a file.
Name this task Available security updates are captured,
and use the log_file variable so that the command accesses the
ansible_available_updates.txt file.
Use the register statement to capture the output in the file_output variable. The
content of the variable is displayed in the next step.
Note
Notice the indentation. The register statement and the win_shell module are
both indented by two spaces, beneath the name of the task.
...output omitted...
- name: Available security updates are captured
win_shell: "type {{ log_file }}"
register: file_output
3.6. Create a task that uses the debug module. This module can display a message or
the content of a variable if there are available updates. The module uses the when
statement to parse the file and look for the Adding update string. Name this task
Available updates are displayed.
Note
The when statement is indented at the same level as the debug module.
210 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
...output omitted...
- name: Available security updates are captured
win_shell: "type {{ log_file }}"
register: file_output
3.7. The updates Git repository provides an .MSU file, which is an update for your servers.
The file is accessible at https://gitlab.example.com/student/updates/
raw/master/files/KB4465065.msu.
Create a task that uses the win_uri module to retrieve the file and save it to
C:\Windows\Temp\KB4465065.msu. Give it a name of MSU package is
retrieved on hosts.
Since the URL is protected by a password, use the headers parameter to pass the
access token to the request as a header. The force_basic_auth: yes variable
instructs Ansible to add a Basic authentication header to the initial request.
Reuse the KB variable, which contains the name of the file, as the src parameter.
Note
The validate_certs: no statement instructs Ansible to accept insecure
certificates. Since this is a development environment, it is acceptable to skip the
certificate verification, but is not recommended to bypass this verification in
production environments.
...output omitted...
- name: MSU package is retrieved on hosts
win_uri:
url: >
https://gitlab.example.com/student/updates/raw/master/files/{{ KB }}.msu
dest: C:\Windows\Temp\{{ KB }}.msu
validate_certs: no
force_basic_auth: yes
method: GET
headers:
PRIVATE-TOKEN: "{{ access_token }}"
3.8. The next step installs the package that the previous module retrieved. To begin,
create a new task that uses the win_hotfix module. Pass the path of the MSU file
to the module and the KB identifier (reuse the KB variable). The state: present
parameter instructs Ansible to install the package.
Name this task MSU package is installed.
DO417-RHAE2.8-en-1-20200106 211
Chapter 5 | Installing and Updating Software
...output omitted...
- name: MSU package is installed
win_hotfix:
hotfix_kb: "{{ KB }}"
source: C:\Windows\Temp\{{ KB }}.msu
state: present
3.9. Another way to install updates is the usage of the win_updates module. Create a new
task that invokes this module; name this task Security updates are applied.
The module will validate the packages to install, based on a category that is defined by
the category_name and whitelist parameters.
Add the KB4494174 and KB4346084 KB numbers to the whitelist parameter. The
module returns a Boolean in the reboot_required variable that indicates whether or
not the updates require a restart of the server.
Save the output to the updates_status variable.
...output omitted...
- name: Security updates are applied
win_updates:
category_name:
- Updates
whitelist:
- KB4494174
- KB4346084
register: updates_status
3.10.Finally, if the updates require a restart, then add a task that reboots the server. Use
a conditional based on the output of the updates_status.reboot_required
variable.
Name this task Server is rebooted.
...output omitted...
- name: Server is rebooted
win_reboot:
when: updates_status.reboot_required
After completion, the first play should look like the following:
tasks:
- name: Microsoft update servers are queried
win_updates:
category_names: SecurityUpdates
state: searched
212 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Note
The completed file is available in the updates.sol file, in the solutions
directory.
5. In this second play, you will use Chocolatey to install two packages on the managed hosts.
5.1. Update the second play in the file by giving it a name of Install packages on
systems and targeting all hosts for the play. To do so, add the hosts: all directive.
DO417-RHAE2.8-en-1-20200106 213
Chapter 5 | Installing and Updating Software
Note
Make sure to indent the hosts directive by two spaces.
...output omitted...
- name: Install packages on systems
hosts: all
5.2. Add a vars directive, and create a packages list that contains to two packages to
install:
• Putty
• Wireshark
...output omitted...
- name: Install packages on systems
hosts: all
vars:
packages:
- Putty
- Wireshark
...output omitted...
- name: Install packages on systems
hosts: all
vars:
packages:
- Putty
- Wireshark
tasks:
5.4. Create a task that invokes the win_chocolatey module. This module can install
Chocolatey, if not already present.
Name this task Chocolatey is installed.
...output omitted...
tasks:
- name: Chocolatey is installed
win_chocolatey:
name: chocolatey
state: present
5.5. Create a new task that installs the two packages in the packages list. Use the
win_chocolatey module, passing the variable to the module. The pinned
parameter instructs Chocolatey to suppress upgrades for the packages.
Name this task Packages are installed.
214 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
...output omitted...
- name: Packages are installed
win_chocolatey:
name: "{{ packages }}"
state: present
pinned: true
register: install_result
5.6. Finally, add a task to reboot the server, if needed. This task invokes the win_reboot
module and uses the when statement to determine whether to reboot or not, based
on Chocolatey return codes. The return code 3010 indicates that the server requires a
reboot.
Name this task Server is rebooted.
...output omitted...
- name: Server is rebooted
win_reboot:
when: install_result.changed and install_result.rc == 3010
After completion, the second play should look like the following:
tasks:
- name: Chocolatey is installed
win_chocolatey:
name: chocolatey
state: present
Note
The completed file is available in the updates.sol file, in the solutions
directory.
DO417-RHAE2.8-en-1-20200106 215
Chapter 5 | Installing and Updating Software
6.1. From the Visual Studio Code editor, stage the updates.yml playbook. To do so, click
the Source Control icon.
Click the + symbol for the updates.yml file to stage your changes.
6.2. In the commit message field, enter a commit message of Define updates and
Chocolatey tasks, and then click the commit button.
6.3. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
7. Create a GitLab access token that Ansible will use to retrieve a file.
7.1. In GitLab, click the icon in the upper right and select Settings to access your account
settings.
7.2. Click Access Tokens. Give the token a name of WindowsUpdates, and then select
api. Access your API as the scope. Click Create personal access token to create
the token.
The action generates a token and displays it in the Your New Personal Access Token
field. Leave this page open for now, in a later step, you will use the token.
216 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
8. Update and run the Run updates project job template in Ansible Tower.
8.1. From workstation, double-click the Ansible Tower icon on your desktop to
access Ansible Tower. Log in to Ansible Tower using admin as the user name and
RedHat123@! as the password.
8.2. Click Templates to access the Run updates project job template.
Click the template to edit it.
---
access_token: cBSC6VAe351E7J3rLz13
DO417-RHAE2.8-en-1-20200106 217
Chapter 5 | Installing and Updating Software
8.4. Click LAUNCH to launch a job from the job template. Ansible Tower redirects you to
the job output.
Inspect the output as Ansible Tower runs the first play that retrieves the list of available
security updates, installs the MSU package, and install the two KBs. The second play
installs Chocolatey and the two packages. Notice the warning that if Chocolatey is not
present on the system, then Ansible installs it.
Ansible may skip the tasks that reboot the servers, which is expected if a package or an
update is already present.
9.1. From workstation, open the remote desktop client. Select Show Options to display
extra options. Use a computer name of win1.example.com and a user name of
devops.
When prompted, accept the self-signed certificate, and use RedHat123@! as the
password.
218 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
9.2. Open File Explorer and navigate to C:\Windows\Temp. From the warning that
displays, click Continue to access the protected Temp directory. Open the
ansible_available_updates.txt text file, created by Ansible. This file contains
the list of available security updates.
DO417-RHAE2.8-en-1-20200106 219
Chapter 5 | Installing and Updating Software
9.4. Close the RDP session to win1.example.com, and rerun the RDP client. Use a
computer name of win2.example.com and a user name of devops.
When prompted, accept the self-signed certificate, and use RedHat123@! as the
password.
9.5. To ensure that Putty is installed, click the magnifying glass icon and type Putty. The
search returns one result that confirms that Putty has been successfully installed.
Note
If the package is not visible in the search results, then restart the server.
220 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
9.6. Repeat the same steps for the Wireshark package. The search returns one result.
DO417-RHAE2.8-en-1-20200106 221
Chapter 5 | Installing and Updating Software
Objectives
After completing this section, you should be able to inspect the Windows Registry and ensure that
registry keys are correctly configured.
The registry is used to store configuration information for the operating system and most software
packages. Although it is not a requirement that software stores its configuration in the registry,
it is recommended. In the Windows Registry, you can also find information such as service
configuration and start mode, software license state, information specific to the current user and
all users, and configuration and handlers for various file types.
Registry Terms
Hive
The registry is physically stored in several files called hives. A hive is used for data that is
related, for example software installed on the local machine.
Key
Keys provide the hierarchy, as a key can contain values or other keys. You can equate keys to
directories in a file system.
Value
A value has a name and a type. The type defines how the data it contains will be interpreted.
The following list describes the possible data types.
• String: a series of characters
• Binary: true or false, yes or no, 1 or 0
• Dword or Qword: 32 or 64 bit values
• Multi-String: a value that may contain data with multiple lines of strings
• Expandable String: the same as a multi-string but can contain variables which are expanded,
such as environment variables like %HOMEPATH%
The registry hives are stored under C:\Windows\System32\Config, assuming that Windows
is installed on the first drive. The files are named for the type of configuration they hold, such as
SOFTWARE, SYSTEM, SAM, SECURITY, and DEFAULT. In the preceding list, SAM is short for the
Security Account Manager, and this hive holds user account information.
222 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Windows provides the regedit tool for editing the registry. In earlier versions of Windows there
was a tool called regedt32 which was the first 32 bit version, this has now been deprecated and
simply launches regedit instead.
Some of the common tasks are to verify that a key exists, or to return the sub-keys and values for
the key, or to return a specific value. The win_reg_stat module is designed for this purpose, and
performs a similar function to the stat module.
The following example shows the use of win_reg_stat to obtain licensing information. The
registered variable allows any following tasks to be performed conditionally.
DO417-RHAE2.8-en-1-20200106 223
Chapter 5 | Installing and Updating Software
Following on from the previous example, the application is registered based on the value stored in
myapp_license_type.
If there are too many registry values to manage individually, then it may be simpler to export a
registry key from a system in the desired state and then merge it into the registry of other systems.
Note
Be aware that files exported using regedit may contain a Byte Order Mark as
the first character. A Byte Order Mark at the start of a file indicates the Unicode
encoding and endianness for the file. This character will need to be deleted to use
the exported file as a template.
This module does not force registry settings to match the exported file. You must delete the
affected key first as shown in the following example.
224 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
References
win_reg_stat – Get information about Windows registry keys — Ansible
Documentation
https://docs.ansible.com/ansible/latest/modules/win_reg_stat_module.html#win-
reg-stat-module
win_regmerge – Merges the contents of a registry file into the windows registry
— Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/win_regmerge_module.html#win-
regmerge-module
DO417-RHAE2.8-en-1-20200106 225
Chapter 5 | Installing and Updating Software
Guided Exercise
Outcomes
You should be able to inspect the Windows Registry and ensure that registry keys are
correctly configured.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Note
In this exercise, you will configure the Windows Time service to synchronize
to an external time source. Configuring the Windows Time service to
synchronize to an external time source is not usually performed on a machine
that is a domain member. Domain members normally synchronize time to a
Domain Controller automatically, which prevents authentication issues.
1.1. Click Search Windows, search for mstsc, and then open Remote Desktop
Connection.
Note
The Remote Desktop Connection program is also known as the Microsoft Terminal
Services Client (mstsc.exe).
1.2. To connect to the Remote Desktop, enter win1.example.com for the Computer
and devops for the User Name, and RedHat123@! as the password. Note that
devops is a local user, not a domain user, so do not include the EXAMPLE domain in the
username field.
When prompted, access the insecure certificate.
1.3. Click Search Windows, and then type regedit. Open the registry editor. When
prompted, click Yes to open the registry editor.
226 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
An administrator can also set a service to Delayed Start using the Services applet,
or by editing the registry.
Verify that the value of Parameters\NtpServer references a 169.254.x.x address,
Parameters\Type is AllSync, Config\AnnounceFlags is 0xa or 10 decimal, and
Config\MaxPosPhaseCorrection is set to the maximum possible value for 32 bits.
1.5. Close the registry editor and disconnect the remote session.
2. Launch the Visual Studio Code editor. If you have not previously cloned the updates
repository, clone it to your workstation instance.
2.1. Click Search Windows, search for code, and then open Visual Studio Code.
4. Open the time.yml playbook, and then complete the tasks in the file. Note the variable
time_key has been set for you.
DO417-RHAE2.8-en-1-20200106 227
Chapter 5 | Installing and Updating Software
4.1. Modify the task named Configure time server type to set the server type to
NTP. This modifies the Parameters\Type value in the W32Time key.
4.2. Modify the task named Configure AnnounceFlags to set the value to 5. This
modifies the Config\AnnounceFlags value in the W32Time key.
4.3. Modify the task named Enable NTP time provider to enable the NTP provider.
This modifies the TimeProviders\NtpServer\Enabled value in the W32Time key.
4.5. Modify the tasks named Configure positive time correction and
Configure negative time correction to set the maximum time correction to
3600 seconds. This modifies the Config\MaxPosPhaseCorrection and Config
\MaxPosPhaseCorrection values in the W32Time key.
228 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
5. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
5.2. Navigate to the Source Control pane, and then click + for the time.yml file to stage
the changes.
5.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
5.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
7. Test your playbook by using the Run updates project job template.
7.2. Click the Run updates project job template to edit it.
7.4. Click SAVE to update the template, and then click LAUNCH to run the job.
8. Once all tasks have completed, verify that the STATUS in the DETAILS section shows
Successful. If the job is not successful, compare your playbook with the solutions/
time.sol solution file in the updates Git repository.
9. Connect to the win1.example.com managed host and verify the changes to the
W32Time service.
9.1. Click Search Windows, search for mstsc, and then open the Remote Desktop
Connection.
DO417-RHAE2.8-en-1-20200106 229
Chapter 5 | Installing and Updating Software
9.2. Enter win1.example.com for the Computer and devops for User Name, and
RedHat123@! as the password. Note that devops is a local user, not a domain user, so
do not include the EXAMPLE domain.
9.3. Launch the registry editor then navigate to the W32Time key. Note that the values
viewed at the start of the exercise have changed, as a result of the tasks in the
time.yml playbook file. Close the registry editor.
9.4. Click Search Windows, search for cmd, and then open the command shell.
9.5. Run the W32tm /query /peers command to view time synchronization status.
Peer: windc.example.com
State: Active
Time Remaining: 28.3535922s
Mode: 1 (Symmetric Active)
Stratum: 3 (secondary reference - syncd by (S)NTP)
PeerPoll Interval: 17 (out of valid range)
HostPoll Interval: 6 (64s)
Peer: 0.rhel.pool.ntp.org,0x1
State: Active
Time Remaining: 748.3535922s
Mode: 1 (Symmetric Active)
Stratum: 3 (secondary reference - syncd by (S)NTP)
PeerPoll Interval: 17 (out of valid range)
HostPoll Interval: 6 (64s)
9.6. Exit the command shell, and then disconnect from win1.example.com
10. Switch back to the Ansible Tower web UI. Revert your changes by updating the Run
updates project job template.
Note
This step is required to prevent possible authentication issues in future exercises.
10.4.Click SAVE to update the template, and then click LAUNCH to run the job.
230 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Lab
Outcomes
You should be able to:
• Write an Ansible Playbook that installs Chocolatey packages and merges data into the
Windows registry.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From the Windows workstation, open the Visual Studio Code editor and clone
the updates repository, available at https://gitlab.example.com/student/
updates.git, to C:\Users\student\Documents\updates if the folder is not already
present.
2. Add the updates folder to Visual Studio Code workspace, and make the following changes
to the review.yml playbook:
• Define the package_name variable with a value of Atom. This is the name of the
Chocolatey package for installing the Atom text editor.
• Create a task that retrieves the Atom source package, as defined by the package_url
variable. Use the package_local_path for the path where the package is saved.
DO417-RHAE2.8-en-1-20200106 231
Chapter 5 | Installing and Updating Software
• Create a task that invokes the win_chocolatey module to install the Atom package.
Configure the task so that it uses the package_name variable as the name of the package
to install, and package_local_path as the package location.
• Create a task that uses the win_uri module to retrieve the RedHatTraining.reg
registry file, available at https://gitlab.example.com/student/updates/
blob/master/files/RedHatTraining.reg. Name the task Registry file is
retrieved.
Since the URL is protected by a password, use the headers parameter to pass the
PRIVATE-TOKEN header with the access_token Ansible variable. In a later step, you will
generate this token.
• Create a task that invokes the win_regmerge module to update the registry by merging
the values specified in the registry file.
Note
The completed file is available at solutions/review.sol in the updates folder.
3. Save your changes, and then commit the file with the Configure Atom on managed
hosts message.
Push your changes to the master branch of the updates repository.
4. Access your GitLab instance at https://gitlab.example.com, and then log in using
student and RedHat123@! as the password.
Generate a token for student that has API access. Name the token UpdatesReview.
5. From your workstation, access Ansible Tower at https://tower.example.com. Log in
using admin as the user name and RedHat123@! as the password.
Update the Run updates project job template as follows:
• Pass the access_token as an extra variable. Give it the value of the GitLab token that
you generated during the previous step.
6. Run the Run updates project job template and ensure that is runs successfully.
7. From workstation, open your RDP client and connect to win1.example.com using
devops as the user name and RedHat123@! as the password. When prompted, accept the
insecure certificate.
Ensure that Atom is installed. You can look for the desktop icon.
Access the registry to ensure that the RedHat key is available in HKCU:\Software.
232 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Solution
Outcomes
You should be able to:
• Write an Ansible Playbook that installs Chocolatey packages and merges data into the
Windows registry.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From the Windows workstation, open the Visual Studio Code editor and clone
the updates repository, available at https://gitlab.example.com/student/
updates.git, to C:\Users\student\Documents\updates if the folder is not already
present.
Note
The following steps describe how to clone the updates repository. If you already
cloned the repository in a previous step, you can skip these steps.
1.1. From the Windows workstation, open Visual Studio Code by double-clicking the
desktop.
1.2. To clone the updates repository, open the command palette by navigating to View →
Command Palette or by pressing Ctrl+Shift+P.
Type clone and select Git: Clone to clone a repository.
Use a repository URL of https://gitlab.example.com/student/updates.git.
When prompted, select the Documents folder in the home directory of the training
user as the repository location. This clones the remote repository into the updates
folder.
DO417-RHAE2.8-en-1-20200106 233
Chapter 5 | Installing and Updating Software
2. Add the updates folder to Visual Studio Code workspace, and make the following changes
to the review.yml playbook:
• Define the package_name variable with a value of Atom. This is the name of the
Chocolatey package for installing the Atom text editor.
• Create a task that retrieves the Atom source package, as defined by the package_url
variable. Use the package_local_path for the path where the package is saved.
• Create a task that invokes the win_chocolatey module to install the Atom package.
Configure the task so that it uses the package_name variable as the name of the package
to install, and package_local_path as the package location.
• Create a task that uses the win_uri module to retrieve the RedHatTraining.reg
registry file, available at https://gitlab.example.com/student/updates/
blob/master/files/RedHatTraining.reg. Name the task Registry file is
retrieved.
Since the URL is protected by a password, use the headers parameter to pass the
PRIVATE-TOKEN header with the access_token Ansible variable. In a later step, you will
generate this token.
• Create a task that invokes the win_regmerge module to update the registry by merging
the values specified in the registry file.
2.1. In Visual Studio Code, open the review.yml playbook and make the following changes:
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
...output omitted...
234 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
package_url: https://chocolatey.org/api/v2/package/Atom/1.39.1
...output omitted...
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
package_url: https://chocolatey.org/api/v2/package/Atom/1.39.1
package_local_path: C:\Windows\Temp\atom.nupkg
...output omitted...
4. Create a task that retrieves the Atom source package, as defined by the
package_url variable, using the win_uri module. Save the package to the path
defined by the package_local_path variable.
Give the task a name of Atom package is retrieved on managed hosts.
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
package_url: https://chocolatey.org/api/v2/package/Atom/1.39.1
DO417-RHAE2.8-en-1-20200106 235
Chapter 5 | Installing and Updating Software
package_local_path: C:\Windows\Temp\atom.nupkg
tasks:
- name: Atom package is retrieved on managed hosts
win_uri:
url: "{{ package_url }}"
dest: "{{ package_local_path }}"
method: GET
5. Create a task that invokes the win_chocolatey module to install the Atom
package, from the file that you retrieved. Name the task Atom is installed
from a local source.
Configure the task so that it uses the package_name variable as the name of
the package to install, and the package_local_path variable as the package
location.
Note
If you need to reinstall the package, pass the force: yes parameter to the
win_chocolatey module.
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
package_url: https://chocolatey.org/api/v2/package/Atom/1.39.1
package_local_path: C:\Windows\Temp\atom.nupkg
tasks:
- name: Atom package is retrieved on managed hosts
win_uri:
url: "{{ package_url }}"
dest: "{{ package_local_path }}"
method: GET
236 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
gitlab.example.com/student/updates/blob/master/files/
RedHatTraining.reg. Name the task Registry file is retrieved.
Since the URL is protected by a password, use the headers parameter to pass the
PRIVATE-TOKEN header with the access_token Ansible variable. In a later step,
you will generate this token.
Save the file to C:\Windows\Temp\RedHatTraining.reg.
Note
Notice the extra indentation of the header data.
...output omitted...
- name: Registry file is retrieved
win_uri:
url: >
https://gitlab.example.com/student/updates/blob/master/files/
RedHatTraining.reg
dest: C:\Windows\Temp\RedHatTraining.reg
validate_certs: no
force_basic_auth: yes
method: GET
headers:
PRIVATE-TOKEN: "{{ access_token }}"
7. Create a task that invokes the win_regmerge module to update the registry, by
merging the values specified in the registry file.
Give the task a name of Registry is updated.
The task should look like the following:
...output omitted...
- name: Registry file is retrieved
win_uri:
url: >
https://gitlab.example.com/student/updates/blob/master/files/
RedHatTraining.reg
dest: C:\Windows\Temp\RedHatTraining.reg
validate_certs: no
force_basic_auth: yes
method: GET
DO417-RHAE2.8-en-1-20200106 237
Chapter 5 | Installing and Updating Software
headers:
PRIVATE-TOKEN: "{{ access_token }}"
---
- name: Install Atom using Chocolatey and update the registry
hosts: all
vars:
package_name: Atom
package_url: https://chocolatey.org/api/v2/package/Atom/1.39.1
package_local_path: C:\Windows\Temp\atom.nupkg
tasks:
- name: Atom package is retrieved on managed hosts
win_uri:
url: "{{ package_url }}"
dest: "{{ package_local_path }}"
method: GET
Note
The completed file is available at solutions/review.sol in the updates folder.
3. Save your changes, and then commit the file with the Configure Atom on managed
hosts message.
Push your changes to the master branch of the updates repository.
238 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
3.1. From Visual Studio Code, save the file and stage it. Access the Source Control panel
and click + next to review.yml to stage your changes.
3.2. In the commit message field, type Configure Atom on managed hosts and click
the Commit button, or press Ctrl+Enter to commit your changes.
3.3. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
4.1. From workstation, double-click the GitLab desktop icon. Log in to GitLab using
student as the user name and RedHat123@! as the password. Make sure that the
LDAP tab is selected.
4.2. To generate an API token, click the icon on the upper-right corner and click Settings to
access the user settings.
DO417-RHAE2.8-en-1-20200106 239
Chapter 5 | Installing and Updating Software
4.3. Click the Access Tokens entry from the side bar. Create a token according to the
following information.
• Name: UpdatesReview
• Scopes: API
Do not close the page. In the next step, you will use the token.
• Pass the access_token as an extra variable. Give it the value of the GitLab token that
you generated during the previous step.
5.1. From workstation, double-click the Ansible Tower desktop icon. Log in to Ansible
Tower using admin as the user name and RedHat123@! as the password.
240 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
5.3. Update the job template by selecting review.yml as the Ansible Playbook. In the
LIMIT field, enter win1.example.com. Finally, in the EXTRA VARIABLES field, add
the access_token whose value is the GitLab token that you created in the previous
step.
---
access_token: "juU8gSuEHgczFy7DCNza"
6. Run the Run updates project job template and ensure that is runs successfully.
6.2. This action redirects you to the job output. Notice the output of the different tasks as
they execute. Ansible retrieves the Atom package and installs it, and then retrieves the
registry file before merging it.
DO417-RHAE2.8-en-1-20200106 241
Chapter 5 | Installing and Updating Software
7. From workstation, open your RDP client and connect to win1.example.com using
devops as the user name and RedHat123@! as the password. When prompted, accept the
insecure certificate.
Ensure that Atom is installed. You can look for the desktop icon.
Access the registry to ensure that the RedHat key is available in HKCU:\Software.
7.1. From workstation, open the remote desktop client. Select Show Options to display
extra options. Use a computer name of win1.example.com and a user name of
devops. When prompted, accept the self-signed certificate, and use RedHat123@! as
the password.
242 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
7.2. To ensure that Atom is installed, locate the desktop icon. You can also run the choco
list --local-only PowerShell command.
DO417-RHAE2.8-en-1-20200106 243
Chapter 5 | Installing and Updating Software
Note
If you did not complete the previous activities in the chapter, your output may be
different.
7.3. Click the magnifying glass icon and type Registry Editor to access the registry.
When prompted, click Yes to allow the editor to make changes.
244 DO417-RHAE2.8-en-1-20200106
Chapter 5 | Installing and Updating Software
Summary
In this chapter, you learned:
• You can run the Get-WindowsFeature PowerShell command to obtain a list of all feature
names that are available on a system.
• You can use the win_updates, win_hotfix, and win_reboot Ansible modules to update
your systems.
• You can use the win_regedit, win_reg_stat, and win_regmerge Ansible modules to
manage the Windows registry.
DO417-RHAE2.8-en-1-20200106 245
246 DO417-RHAE2.8-en-1-20200106
Chapter 6
DO417-RHAE2.8-en-1-20200106 247
Chapter 6 | Implementing Task Control
Objectives
After completing this section, you should be able to write plays efficiently using loops, and use
conditions to control when tasks run.
Ansible supports iterating a task over a set of items using the loop keyword. You can configure
Ansible loops to repeat a task using:
• Items in a list.
• The content of each file in a list.
• A generated sequence of numbers.
• More complex structures.
This section covers simple loops that iterate over a list of items. For more advanced looping
scenarios consult the Loops — Ansible Documentation link listed in the references section.
Consider the following snippet that invokes the win_chocolatey module three times to install a
set of software packages using Chocolatey:
248 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
You can rewrite these three tasks using a loop in a single task. The loop iterates over the three
packages:
You can also define a variable for the list and pass it to the loop. In the following example, the
packages variable contains the list of packages to install:
vars:
packages:
- jre8
- javaruntime-preventasktoolbar
- dropbox
tasks:
- name: Installing Java and Dropbox
win_chocolatey:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
In the following example, each item in the list is a dictionary, and each dictionary defines three
keys: name, description, and groups. You can retrieve each key in the current item variable by
using the item.name, item.desc, and item.grp variables, respectively.
You can rewrite the dictionary using the YAML format as the following:
DO417-RHAE2.8-en-1-20200106 249
Chapter 6 | Implementing Task Control
The task ensures that the itadmin user is present with a description of New admin user and
is a member of the Administrators group. It also ensures that ituser1 and ituser2 are
present and are members of the Users group.
Keyword Description
with_items Behaves the same as the loop keyword for simple lists such as a list of
strings or a list of dictionaries. Unlike loops, if you use nested lists with
with_items, Ansible will flatten them into a single-level list. The item
loop variable holds the current list item used during each iteration.
with_file This keyword requires a list of files. The item loop variable holds the
content of a corresponding file from the file list during each iteration.
vars:
packages:
- jre8
- javaruntime-preventasktoolbar
- dropbox
tasks:
- name: Installing Java and Dropbox
win_chocolatey:
name: "{{ item }}"
state: present
with_items: "{{ packages }}"
250 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Important
Since Ansible 2.5, the recommended way to write loops is to use the loop keyword.
However, you should still understand the earlier syntax, especially with_items,
because it is widely used in existing playbooks. You are likely to encounter playbooks
and roles that continue to use with_ keywords for looping.
You can convert any task that uses the earlier syntax to use the loop keyword in conjunction with
Ansible filters. You do not need to know how to use Ansible filters to do this. For more information
on how to convert loops to the new syntax and how to loop over items that are not simple lists,
consult the Migrating from with_X to loop — Ansible Documentation page listed in the references
section.
Note
Advanced looping techniques are beyond the scope of this course. You can
implement all iteration tasks in this course with either the with_items or the loop
keyword.
---
- name: Loop register test
hosts: windows
tasks:
- name: Executing commands and registering output in the variable "output"
win_shell: "{{ item }}"
loop:
- whoami
- hostname
register: output
DO417-RHAE2.8-en-1-20200106 251
Chapter 6 | Implementing Task Control
The output variable is a dictionary of three keys, each of which has a value: changed, msg,
and results. (Ansible does not use a list here because order of those keys is unimportant.)
The results key contains the results of the task. For this loop, the result is a list of
dictionaries. Lists are enclosed in brackets '[ ]', and dictionaries are enclosed in braces '{ }'.
252 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Each list item is a dictionary of key-value pairs for each item in the loop, in order. Both list
items and key-value pairs are separated by commas.
Marks the beginning of the task metadata for the first item. The metadata consists of a set
of key-value pairs, and the item key has as its value the item from the list. The output of the
whoami and hostname commands is stored in the stdout key.
The start of task result metadata for the second item.
The closing square bracket (]) character indicates the end of the output list.
In the previous example, the results key contains a list. In the following example, the playbook is
modified such that the second task iterates over a list.
DO417-RHAE2.8-en-1-20200106 253
Chapter 6 | Implementing Task Control
Conditionals allow you to differentiate between managed hosts and assign them functional roles
based on the conditions that they meet. Playbook variables, registered variables, and Ansible facts
or custom facts can all be tested with conditionals. You can use operators such as greater than (>)
or less than (<) to compare strings, numerical data, or Boolean values.
• Define a hard limit in a variable (for example, min_memory for the minimum amount of memory
that is required) and compare it against the available memory on a managed host.
• Capture the output of a command and evaluate it to determine whether to take further action.
For example, you can instruct Ansible to copy an index.html file only if the IIS web server is
properly installed and configured.
• Use Ansible facts to determine the managed host network configuration and decide which
template file to send.
• Compare a registered variable with a predefined variable to determine if a service changed. For
example, test the MD5 checksum of a service configuration file to see if the service changed.
A simple condition that you can test is whether a Boolean variable equals true or false. The
when statement in the following example causes the first task to run only if run_my_task equals
true. In the second task, the system only restarts if the win_feature.reboot_required
variable is equal to true.
254 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
The following example is a bit more sophisticated, and tests whether the my_service variable
has a value. If it does, Ansible uses the value of my_service variable as the package to install. If
the my_service variable is not defined, Ansible skips the task.
Operation Example
DO417-RHAE2.8-en-1-20200106 255
Chapter 6 | Implementing Task Control
Operation Example
The last entry in the preceding table might be confusing at first. The following example illustrates
how it works.
Important
Notice the indentation of the when statement. Because the statement is not a
module variable, you must place it outside the module by indenting it at the top-
level of the task.
A task is a YAML hash or dictionary, and the when statement is simply one more
key in the task similar to the task's name and the module that it uses. A common
convention consists of placing any when keyword after the task's name and the
module and module arguments.
256 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
• If a conditional statement should be met when either condition is true, then you should use
the or operator. For example, the following condition is met if the machine is running either
Microsoft Windows Server 2016 Datacenter or Microsoft Windows Server 2012 Datacenter
edition.
• With the and operator, both conditions have to be true for the entire conditional statement to
be true. For example, the following condition is met if the remote host is a Microsoft Windows
Server 2016 Datacenter host with a 64-bit architecture:
The when keyword also supports a list to describe a set of conditions. When you provide a list
to the keyword, Ansible combines all the conditionals using the and operator. The following
example demonstrates another way to combine multiple conditional statements using and.
when:
- ansible_facts['distribution'] == "Microsoft Windows Server 2016 Datacenter"
- ansible_facts['architecture'] == "64-bit"
• You can express more complex conditional statements by grouping conditions with parentheses.
This ensures that Ansible correctly interprets them.
For example, the following conditional statement is met if the machine is running either
Microsoft Windows Server 2016 Datacenter or Microsoft Windows Server 2012 Datacenter and
has a 64-bit architecture.
when: >
( ansible_facts['distribution'] == "Microsoft Windows Server 2016 Datacenter"
or
ansible_facts['distribution'] == "Microsoft Windows Server 2012 Datacenter" )
and
ansible_facts['architecture'] == "64-bit"
DO417-RHAE2.8-en-1-20200106 257
Chapter 6 | Implementing Task Control
- dropbox
tasks:
- name: Install packages
win_chocolatey:
name: "{{ item }}"
state: present
loop: "{{ my_package }}"
when:
- ansible_facts['distribution'] == "Microsoft Windows Server 2016 Core"
- ansible_facts['architecture'] == "64-bit"
Important
When you use the when statement in a loop, Ansible evaluates the condition for
each item in the loop.
References
Loops — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
258 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Guided Exercise
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Open the Visual Studio Code editor and clone the control repository to workstation.
1.2. Click View → Command Palette or type Ctrl+Shift+P to open the command
palette.
Type clone and select Git: Clone to clone a repository.
1.4. In the lower right corner, click Open to open the project.
2. Open the loops.yml playbook and review its contents. Notice the long list of repetitive
tasks. Each task uses the win_feature module to ensure that an IIS web server feature
is present. In the next steps you will refactor the playbook to improve readability and
maintainability.
3. Group all of the extra debugging features into a single task with a loop. Replace all of the
tasks except for the task named IIS is installed with the updated task as follows:
---
- name: IIS and debugging tools installed
hosts: win1.example.com
tasks:
DO417-RHAE2.8-en-1-20200106 259
Chapter 6 | Implementing Task Control
Each iteration of the loop sets the value of the item variable to the next element in
the loop list.
Consolidation of the features to install into a simple list.
4. Modify the playbook to only install the extra debugging tools when there is enough space
available on the disk.
4.1. Insert a task directly before the Debug tools are installed task that gathers
facts about the disks that are present on the managed host.
4.2. Add the when and vars parameters to the Debug tools are installed task as
follows. Indent with six spaces to align the when and vars parameters with the loop
parameter.
Ansible evaluates the when clause on each iteration of the loop. If the
size_remaining variable is greater than or equal to the minimum_bytes
variable then Ansible invokes the win_feature module to ensure that the
feature is present.
Declare variables for the task to improve the readability of the conditional logic.
For simplicity, select the space available from the first volume of the first partition
of the first disk on our classroom managed host.
260 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
---
- name: IIS and debugging tools installed
hosts: win1.example.com
tasks:
- name: IIS is installed
win_feature:
name: Web-Server
state: present
6. Save and commit the changes to your local Git repository, then push them to the remote
repository.
6.2. Navigate to the Source Control pane, and then click the + for the loops.yml file to
stage the changes.
6.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
6.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
DO417-RHAE2.8-en-1-20200106 261
Chapter 6 | Implementing Task Control
8.4. Click SAVE to update the template, and then click LAUNCH to run the job.
9. Verify that the playbook completed successfully and review the log output.
9.1. After all tasks have completed, verify that the status in the DETAILS section
shows Successful. If the job was not successful, compare your playbook with the
solutions/loops.sol solution file in the control Git repository.
9.2. Review the log output and notice that the Debug tools are installed task
executes with multiple changes.
10. Connect to the win1.example.com managed host to confirm the presence of the IIS web
management tools.
10.1. Click Search Windows, and then type remote to search for and open Remote
Desktop Connection.
262 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
10.3.In the win1.example.com remote session, click Search Windows, and then type
IIS to search for and open Internet Information Services (IIS) Manager.
11. Run the cleanup-loops.yml playbook from the Run control project job template.
11.2. Click the name of the Run control project job template.
11.4. Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 263
Chapter 6 | Implementing Task Control
Implementing Handlers
Objectives
After completing this section, you should be able to implement handlers that run only when
another task makes a change on the managed host and notifies them.
Introducing Handlers
Ansible modules are designed to be idempotent. This means that you can run the playbook and its
tasks multiple times without changing any component on the managed host unless you instruct
Ansible to make a change to get the managed host to the state that you desire.
However, sometimes when a task does make a change to the system, you may need to run further
tasks. For example, if you install a new feature or package on your server or if you join a server to a
domain, you might need to restart the server so that the installation can complete or changes can
be applied successfully.
Handlers are tasks that respond to a notification that other tasks trigger. Tasks only notify their
handlers when the task changes something on a managed host. Each handler has a globally unique
name and triggers at the end of a block of tasks in a playbook. If no task notifies the handler by
name then the handler does not run. If one or more tasks notify the handler, the handler runs
exactly once after all other tasks in the play complete. Because handlers are tasks, you can use
the same modules in handlers that you would use for any other task. You typically use handlers to
restart hosts or services.
You can think of handlers as inactive tasks that trigger when they are invoked by a changed task
that has a notify statement. The following example shows how the reboot server handler
runs when Ansible installs a new package in a task.
handlers:
- name: reboot server
win_reboot:
264 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
In the previous example, the reboot server handler triggers when the win_chocolatey task
notifies Ansible that a change occurred. A task may call more than one handler in its notify
section. Ansible treats the notify statement as an array and iterates over the handler names.
The following example shows how the task invokes two handlers; the initial handler prints a
message, and the second handler restarts the server.
handlers:
- name: printing message
debug:
msg: Installation is done, rebooting the server now
- name: reboot server
win_reboot:
• Handlers always run in the order specified by the handlers section of the play. They do not
run in the order in which they are listed by notify statements in a task, or in the order in which
tasks notify them.
• In a simple play with a single section, handlers run after all other tasks in the play complete. A
handler called by a task in the tasks part of the playbook does not run until Ansible runs all
tasks. More complex plays that use pre_tasks and post_tasks sections, or roles, will trigger
handlers after each section.
• Handler names exist in a per-play namespace. If two handlers have the same name, Ansible will
only run the last one.
• Even if more than one task notifies a handler, the handler only runs once. If no task notifies it, a
handler does not run.
• If a task that includes a notify statement does not report a changed result (for example, if a
package is already installed and the task reports that no further action is required), the handler
is not notified. Ansible skips the handler unless another task notifies it. Ansible notifies handlers
only if the task reports a status of changed.
Important
Handlers are meant to perform an extra action when a task makes a change to a
managed host. You should not use them as a replacement for regular tasks.
DO417-RHAE2.8-en-1-20200106 265
Chapter 6 | Implementing Task Control
The order of these sections in a play does not modify the order of execution, as given above. For
example, if you write the tasks section before the roles section, Ansible still executes the roles
before the tasks in the tasks section. However, for readability, it is good practice to organize your
play in the following order of execution:
1. pre_tasks
2. roles
3. tasks
4. post_tasks
5. handlers
Ansible executes and flushes the handlers that the tasks notify at several points during a run:
after the pre_tasks section, after the include_roles and tasks sections, and after the
post_tasks section. This means that a handler can run more than once at different times during
the play execution if tasks notify it in multiple sections.
References
Handlers: Running Operations On Change — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/
playbooks_intro.html#handlers-running-operations-on-change
266 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Guided Exercise
Implementing Handlers
In this exercise, you will write a play that uses a handler to run a task if another task makes a
change to the managed host.
Outcomes
You should be able to implement tasks that run only when another task makes a change on
the managed host.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Open the Visual Studio Code editor and clone the control repository to your
workstation.
1.1. On workstation, open the Visual Studio Code editor by double-clicking its icon on
the desktop.
1.2. Open the command palette by navigating to View → Command Palette or by typing
Ctrl+Shift+P.
Type clone and select Git: Clone to clone a repository.
1.4. In the lower right corner, click Open to open the project.
2. Create a playbook named handlers.yml that uses the win_updates Ansible module to
install Windows security updates on the win1.example.com server.
---
- name: System updated and restarted
hosts: win1.example.com
tasks:
- name: Security updates applied
win_updates:
category_names: SecurityUpdates
state: installed
DO417-RHAE2.8-en-1-20200106 267
Chapter 6 | Implementing Task Control
3. Below the tasks section, add a handler that uses the win_reboot module that you can
notify to reboot the server. Even though this module provides a reboot parameter, this
exercise creates a handler to manage that action, allowing you to execute the reboot when
most appropriate for your use case.
---
- name: System updated and restarted
hosts: win1.example.com
tasks:
- name: Security updates applied
win_updates:
category_names: SecurityUpdates
state: installed
handlers:
- name: Server is rebooted
win_reboot:
4. Add a notify statement to your task to invoke the handler when the task changes the
state of the target host.
---
- name: System updated and restarted
hosts: win1.example.com
tasks:
- name: Security updates applied
win_updates:
category_names: SecurityUpdates
state: installed
notify:
- Server is rebooted
handlers:
- name: Server is rebooted
win_reboot:
5. Save and commit the changes to your local Git repository, then push them to the remote
repository.
5.2. Navigate to the Source Control pane, then click the + next to handlers.yml to
stage the changes.
5.3. Enter a brief commit message, then press Ctrl+Enter to commit the changes.
5.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
268 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
7. In the navigation pane, click Projects. Click the synchronize button to fetch the latest
changes to the control project.
8.2. Click the Run control project job template to edit it.
8.4. Click SAVE to update the template, and then click LAUNCH to run the job.
9. Verify that the playbook completed successfully and review the log output.
9.1. After all tasks have completed, verify that the status in the DETAILS section
shows Successful. If the job was not successful, compare your playbook with the
solutions/handlers.sol solution file in the control Git repository.
9.2. Review the log output and notice that the Security updates applied task
executes, reports a status of CHANGED, and notifies the Server is rebooted
handler.
DO417-RHAE2.8-en-1-20200106 269
Chapter 6 | Implementing Task Control
10. Run the same playbook a second time. Compare the log output and notice that the
Security updates applied task executes, reports an OK status, but does not notify
the Server is rebooted handler, because it made no changes.
270 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Objectives
After completing this section, you should be able to control what happens when a task fails,
recover from task failure, and control what conditions cause a task to report failure.
However, sometimes you might want to have play execution continue even if a task fails. For
example, you might expect that a particular task could fail, and you might want to recover by
running some other task conditionally. There are several Ansible features that can be used to
manage task errors.
The following example illustrates how to use ignore_errors in a task to continue playbook
execution on the host even if the task fails. For example, if notafeature is not a valid feature, the
feature installation fails, but having ignore_errors set to true instructs Ansible to continue.
The following example illustrates how to use the force_handlers keyword in a play to force
execution of the handler even if a task fails:
DO417-RHAE2.8-en-1-20200106 271
Chapter 6 | Implementing Task Control
win_chocolatey:
name: dotnet4.6.1
state: present
notify:
- reboot server
handlers:
- name: reboot server
win_reboot:
Note
Remember that handlers are notified when a task reports a result of changed but
are not notified when tasks report either ok or failed.
For example, you can indicate the update of a Windows Server as failed only if a
failed_update_count variable is defined and is greater than 0.
You can also use the fail module to force a task failure. You can rewrite the previously mentioned
scenario as two tasks:
272 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
reboot_timeout: 600
register: update_result
ignore_errors: true
The fail module allows you to provide a clear failure message for the task. This approach also
enables delayed failure, allowing you to run intermediate tasks to complete or roll back other
changes.
The following example shows how to define a block in which the win_updates module runs.
You can also use blocks for handling errors through the rescue and always statements. If any
task in a block fails, Ansible executes the tasks in a rescue block to recover the execution of the
play. After the tasks in the block clause run, or the tasks in the rescue clause in case of failure,
then Ansible runs all the tasks in the always clause.
To summarize:
The following example shows how to implement a block in a playbook. Even if the tasks in the
block clause fail, Ansible runs the tasks in the rescue and always clauses.
DO417-RHAE2.8-en-1-20200106 273
Chapter 6 | Implementing Task Control
win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
state: installed
reboot: true
reboot_timeout: 600
register: update_result
failed_when:
- update_result.failed_update_count is defined
- update_result.failed_update_count > 0
rescue:
# ... these tasks only run if the tasks in the block fail.
- name: Showing up a failure message
debug:
msg: The Critical and Security Updates has failed.
always:
# However, these tasks always run
- name: Updating mandatory ServicePacks and FeaturePacks
win_updates:
category_names:
- ServicePacks
- FeaturePacks
state: installed
reboot: true
reboot_timeout: 600
Important
The when condition of a block clause also applies to its rescue and always
clauses if they are present.
Use the changed_when keyword to control when a task reports a changed result. The following
example shows how the win_shell is being used to run a command on servers. It would usually
always report changed when the module runs. To modify this behavior set changed_when to
false so that Ansible only reports an ok or failed status.
274 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
References
Blocks — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html
DO417-RHAE2.8-en-1-20200106 275
Chapter 6 | Implementing Task Control
Guided Exercise
Outcomes
You should be able to customize how Ansible identifies and handles errors and status output.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Open the Visual Studio Code editor and clone the control repository to workstation.
1.1. From workstation open the Visual Studio Code editor by double-clicking its icon on
the desktop.
1.4. In the lower right corner, click Open to open the project.
3. With Ansible, you can use conditionals for tasks that verify the implementation of features
that are not yet available.
Add a task that installs a custom feature named Team-Application that your team
intends to add to the environment at a later time. Ensure that this task does not halt
playbook execution until the feature is created by adding the argument ignore_errors:
yes.
276 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
4. Ansible can ensure that the content in your environment matches expected outputs and
mitigate any discrepancies. Use a registered variable to capture task output, then use it
conditionally execute foloowing tasks.
4.1. Add a task that reads the contents of the win1.example.com home page text and
stores it in the index variable.
4.2. Add another line to the task that uses the conditional failed_when statement to
compare the home page output stored in the index variable with the string "Ansible
is great". This comparison will fail when the index content does match this phrase.
---
- name: Install the IIS web service
hosts: win1.example.com
tasks:
DO417-RHAE2.8-en-1-20200106 277
Chapter 6 | Implementing Task Control
win_uri:
url: http://win1.example.com
return_content: yes
register: index
failed_when: index.content != "Ansible is great"
5. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
5.2. Navigate to the Source Control pane, and then click the + next to the install-
iss.yml file to stage the changes.
5.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
5.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
7.4. Click SAVE to update the template, and then click LAUNCH to run the job.
7.5. Because the error is ignored for the task Team-Application is installed, it is
reported as a failure but playbook execution continues. Because the content of the
homepage is not correctly set, the job fails on the task Homepage index is set.
278 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
8.1. In Visual Studio Code, locate the existing task named Website index.html
created and update the content to have it set the home page on the
win1.example.com server to Ansible is great.
8.2. Save, commit, and synchronize your work in Visual Studio Code. Rerun the job in
Ansible Tower. With the proper homepage content set, your playbook runs to a
successful completion.
DO417-RHAE2.8-en-1-20200106 279
Chapter 6 | Implementing Task Control
280 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Lab
Outcomes
You should be able to manage task flow by using conditional tests and handlers.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Red Hat Ansible
Tower and GitLab from the Windows workstation.
For this lab, use the Run control project job template to execute your playbook within
Ansible Tower.
Note
This activity requires win2.example.com in the Default inventory
inventory. You added the host in a previous exercise. If the host is not present,
follow the instructions in the Implementing Multiple Plays guided exercise to
create it.
DO417-RHAE2.8-en-1-20200106 281
Chapter 6 | Implementing Task Control
8. Add a conditional task for the win2.example.com system to install all Windows security
updates. Notify the Machine is restarted handler.
9. Add a when statement for each task in the playbook that uses an Ansible fact to match the
host name. This addition should have the playbook perform the designated tasks only on the
target machine specified by the lab instructions.
10. In Visual Studio Code, save, commit, and synchronize your file into the control repository.
In Red Hat Ansible Tower, refresh the files for the control repository project.
Launch a job from the Run control project job template.
11. Verify that both systems are in their expected configuration.
282 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
Solution
Outcomes
You should be able to manage task flow by using conditional tests and handlers.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Red Hat Ansible
Tower and GitLab from the Windows workstation.
For this lab, use the Run control project job template to execute your playbook within
Ansible Tower.
Note
This activity requires win2.example.com in the Default inventory
inventory. You added the host in a previous exercise. If the host is not present,
follow the instructions in the Implementing Multiple Plays guided exercise to
create it.
2.1. If you need to add this configuration, navigate to the Inventories page in Ansible Tower,
add the win2.example.com host, and place this host in the default inventory.
3.1. On workstation, double-click the desktop icon named Visual Studio Code.
Click View → Command Palette or type Ctrl+Shift+P to open the command
palette.
DO417-RHAE2.8-en-1-20200106 283
Chapter 6 | Implementing Task Control
3.3. In the lower right corner, click Open to open the project.
4.1. In Visual Studio Code, click the New File icon next to CONTROL and name the file
review.yml.
5. Write a playbook that uses the default inventory containing both the win1.example.com
and win2.example.com machines.
6. For the win1 system, install the Web-Server feature and ensure that the web service is
running. Use a loop to add the additional Web-Security, Web-Basic-Auth, and Web-
IP-Security features to the system and update the server home page to display the host
name of the machine.
---
- name: Control review lab
hosts: all
tasks:
7. Write a handler named Machine is restarted that reboots the server and add it to each
of the feature installation tasks.
284 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
---
- name: Control review lab
hosts: all
tasks:
handlers:
8. Add a conditional task for the win2.example.com system to install all Windows security
updates. Notify the Machine is restarted handler.
---
- name: Control review lab
hosts: all
tasks:
DO417-RHAE2.8-en-1-20200106 285
Chapter 6 | Implementing Task Control
win_feature:
name: Web-Server
state: present
notify: Machine is restarted
handlers:
9. Add a when statement for each task in the playbook that uses an Ansible fact to match the
host name. This addition should have the playbook perform the designated tasks only on the
target machine specified by the lab instructions.
---
- name: Control review lab
hosts: all
tasks:
286 DO417-RHAE2.8-en-1-20200106
Chapter 6 | Implementing Task Control
handlers:
10. In Visual Studio Code, save, commit, and synchronize your file into the control repository.
In Red Hat Ansible Tower, refresh the files for the control repository project.
Launch a job from the Run control project job template.
10.1. In Visual Studio Code, save your file, add a brief commit message, and synchronize your
changes into the control repository.
10.2.In Red Hat Ansible Tower, click Get latest SCM revision on the Projects page next to
the control repository project.
10.3.Selec the Run control project job template from the Templates page to edit it.
Select review.yml from the PLAYBOOK the list, and click Launch.
11.1. Inspect the job output within Ansible Tower to ensure that all tasks completed
successfully.
DO417-RHAE2.8-en-1-20200106 287
Chapter 6 | Implementing Task Control
Summary
In this chapter, you learned:
• Loops are used to iterate over lists of values, such as a simple list of strings or a complex list of
dictionaries.
• Conditionals are used to execute tasks only when certain conditions have been met.
• Handlers are special tasks that execute at the end of a section if notified by tasks within that
section.
• Handlers are only notified when a task reports that it changed something on the managed host.
• Tasks can ignore failures, call handlers even if a task fails, mark tasks as failed even if they
succeed, or override the behavior that causes a task to be marked as changed.
• Blocks are used to group tasks as a unit and to execute other tasks depending on whether or not
all the tasks in the block succeed.
288 DO417-RHAE2.8-en-1-20200106
Chapter 7
DO417-RHAE2.8-en-1-20200106 289
Chapter 7 | Deploying Files to Managed Hosts
Objectives
After completing this section, you should be able to create, install, edit, and remove files on
managed hosts, and configure file permissions and other characteristics.
The Windows modules library includes modules that allow you to accomplish most tasks related to
Windows file management, such as creating, copying, editing, searching, and removing files, and
modifying ACLs and other file attributes.
The following table provides a list of the main file management modules:
win_acl Adds or removes rights and permissions to the specified file, folder, or
registry key for a given user or group.
win_copy Copies files from local control nodes to remote managed nodes.
290 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
The following example demonstrates how to create a directory, and required parent directories, if
they do not exist.
Note
Use the win_tempfile module to create temporary files and directories.
If you do not specify a location for the temporary file, then the module uses the
default system temporary directory defined by the %TEMP% environment variable.
"testfile": {
"changed": false,
"failed": false,
DO417-RHAE2.8-en-1-20200106 291
Chapter 7 | Deploying Files to Managed Hosts
"stat": {
"attributes": "Archive",
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"creationtime": 1567356109.3531778,
"exists": true,
"extension": ".conf",
"filename": "test.conf",
"hlnk_targets": [],
"isarchive": true,
"isdir": false,
"ishidden": false,
"isjunction": false,
"islnk": false,
"isreadonly": false,
"isreg": true,
"isshared": false,
"lastaccesstime": 1567356109.3531778,
"lastwritetime": 1567356195.2883112,
"nlink": 1,
"owner": "BUILTIN\\Administrators",
"path": "C:\\Temp\\test.conf",
"size": 0
}
}
The following task demonstrates changing the ownership of the C:\Temp\folder directory. If
you want to change the owner of all the files and directories in the C:\Temp\folder directory,
then use the recurse: true option, which is set to false by default.
292 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Note
For more information about Windows file system permissions, visit the
FileSystemRights Enum page accessible at https://msdn.microsoft.com/en-
us/library/system.security.accesscontrol.filesystemrights.aspx
By default this module assumes that the force: yes parameter is set. This parameter forces the
module to overwrite the remote file if it exists and contains content that is different from the file
being copied. If force is set to no, then Ansible only copies the file to the managed host if it does
not already exist.
In the following example, Ansible copies the file test.conf from the files directory where the
playbook resides, to C:\Temp\test.conf on the Microsoft Windows managed hosts.
Note
If you are copying large files, consider hosting them on a web server and using the
win_get_url module, instead of the win_copy module. The win_copy module
runs over WinRM which is not a very efficient transport mechanism.
DO417-RHAE2.8-en-1-20200106 293
Chapter 7 | Deploying Files to Managed Hosts
- debug:
msg: '{{ version }}'
The following example uses the win_find module to search for all files with names matching
a specific pattern. This specific pattern instructs Ansible to locate all log files, and command or
execution output. All files must be one gigabyte or more in size, and hidden files are included.
Unzipping Files
Use the win_zip module to unzip compressed files and archives. This module natively supports
.zip files. If the PowerShell Community Extensions (PSCX) module is installed, then
the win_zip module supports all files that 7zip supports. Additionally, installation of the PSCX
module is required in order to use the recurse option.
The following example uses the win_psmodule to install the PSCX module:
The next example invokes the win_unzip module to recursively unzip compressed files and
delete the ZIP archive when complete:
294 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Indicates the icon to use. The file name is followed by a comma and the number in the library
file (.dll), or use 0 for an image file.
References
Windows modules — Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html
DO417-RHAE2.8-en-1-20200106 295
Chapter 7 | Deploying Files to Managed Hosts
Guided Exercise
Outcomes
You should be able to:
• Create a shortcut.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Red Hat
Ansible Tower and GitLab from the Windows workstation.
1. Open the Visual Studio Code editor and clone the managing-files repository to your
workstation.
1.1. From workstation, open the Visual Studio Code editor from the icon on the desktop.
Alternatively, click Search Windows, search for code, and then open Visual Studio
Code.
1.2. To open the command palette, navigate to View → Command Palette or press
Ctrl+Shift+P.
Type clone, and then select Git: Clone to clone a repository.
2. Open the unzip.yml playbook, and then add tasks to deploy the contents of a zip file to
the win1 managed host.
296 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
2.1. Add a new Temp directory created task that uses the win_file module to
ensure that the C:\Temp\DO417\payload directory exists. Ansible will create the
directory if it does not exist.
2.2. Add a second task that transfers the files/example.zip file from the clone of the
managing-files Git repository on Red Hat Ansible Tower, to the C:\Temp\DO417
directory on the managed host.
2.3. Add a final Zip archive is unzipped task to unzip the example.zip archive into
the C:\Temp\DO417\payload directory.
2.4. Review the YAML file and verify that your playbook matches the tasks below.
---
- name: Example archive deployed and permissions set
hosts: win1.example.com
tasks:
- name: Temp directory created
win_file:
path: C:\Temp\DO417\payload
state: directory
3. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
DO417-RHAE2.8-en-1-20200106 297
Chapter 7 | Deploying Files to Managed Hosts
3.2. Navigate to the Source Control pane and stage the changes.
3.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
3.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
4. From workstation, access your Red Hat Ansible Tower instance at http://
tower.example.com. Connect as the student user with RedHat123@! as the password.
5. Run your playbook using the Run managing-files project job template.
5.4. Click SAVE to update the template, and then click LAUNCH to run the job.
5.5. After all tasks have completed, verify that the status in the DETAILS pane displays
Successful.
6.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
6.2. Enter win1.example.com as the computer, devops as the user name, and
RedHat123@! as the password. Note that the devops user is a local user, not a
domain user, so do not include the EXAMPLE domain.
6.3. When prompted, click Yes to accept the insecure certificate used in your classroom
environment.
298 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
6.5. Right-click on the example.txt file, select Properties, and then click on Security.
6.6. Review the file permissions for the various users and groups. Notice that the SYSTEM
and Administrators groups have Full control permissions.
DO417-RHAE2.8-en-1-20200106 299
Chapter 7 | Deploying Files to Managed Hosts
7. Edit the unzip.yml playbook to copy the files to the desktop, create a shortcut for the
text file, and modify permissions and ownership.
7.1. Return to Visual Studio Code and open the unzip.yml playbook.
7.2. Add a new task, Payload is copied to the Desktop, to copy files in the C:
\Temp\DO417\payload directory to the C:\Users\devops\Desktop\example
directory using RoboCopy.
7.3. Add a Shortcut created task to create a shortcut on the desktop that links to the
text file in the example directory.
7.4. Add a task that invokes the win_acl module to deny write permission to the
example.txt text file.
300 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
7.5. Use the win_acl module to add a ReadAndExecute deny rule, denying permission to
open and execute the not-runnable.ps1 PowerShell script.
7.6. Finally, add a task that invokes the win_owner module to change the owner of the
runnable.ps1 PowerShell script.
7.7. Review the completed YAML file and verify that your playbook matches the tasks
below.
---
- name: Example archive deployed and permissions set
hosts: win1.example.com
tasks:
- name: Temp directory created
win_file:
path: C:\Temp\DO417\payload
state: directory
DO417-RHAE2.8-en-1-20200106 301
Chapter 7 | Deploying Files to Managed Hosts
delete_archive: yes
8. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
8.2. Navigate to the Source Control pane, and then stage the changes.
8.3. Enter a brief commit message, and then commit the changes.
8.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
9. Return to Red Hat Ansible Tower and execute your playbook again.
9.2. Click the rocket icon in the Run managing-files project job template row to re-
execute the job with the updated playbook.
302 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
9.3. After all tasks are complete, verify that the status in the DETAILS pane displays
Successful. If the job was not successful, compare your work with the solutions/
unzip.sol solution file in the managing-files Git repository.
10. Reconnect to the win1.example.com managed host to review the file modifications.
10.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
10.2.Enter win1.example.com for the computer, devops as the user name, and
RedHat123@! as the password. Note that the devops user is a local user, not a
domain user, so do not include the EXAMPLE domain.
10.3.When prompted, click Yes to accept the insecure certificate used in your classroom
environment.
10.4.Double-click on the example-txt shortcut on the Desktop to open the text file
located in the example folder. Close the Notepad application after confirming that the
file opens correctly.
DO417-RHAE2.8-en-1-20200106 303
Chapter 7 | Deploying Files to Managed Hosts
10.5.Open the example folder on the Desktop and observe that the files from our
example.zip archive are all present.
304 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Select the devops user and notice that the Write permission is denied.
10.7. Double-click the example.txt file to open it in Notepad. Validate that the file is not
writable by attempting to save the file. In Notepad, select File → Save and then click
Save to save the file.
DO417-RHAE2.8-en-1-20200106 305
Chapter 7 | Deploying Files to Managed Hosts
Click Yes to confirm your intention to replace the example.txt file. When prompted,
click Yes.
A window displays a message that you do not have permission to write to the file, which
is the expected behavior.
306 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Important
Ansible directed the managed host to deny write permissions to the example.txt
file. The error indicates that Windows blocked the write action and that the Ansible
task was successful.
10.8.Inspect the file permissions for the not-runnable.ps1 PowerShell script. Right-click
on the file, select Properties, and then click Security.
Notice the informational warning that displays: "You must have Read permissions to
view the properties of this object." This warning is expected, because Ansible denied
the devops user permission to ReadAndExecute the file.
DO417-RHAE2.8-en-1-20200106 307
Chapter 7 | Deploying Files to Managed Hosts
Click Advanced, and then click Continue to view a list of the applied permissions.
Notice that the permission entry for the devops user displays a deny rule for Read &
execute access.
308 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
PowerShell starts and then closes with no action. This is expected successful behavior.
Important
Ansible directed the managed host to deny the devops user permission to open and
execute the not-runnable.ps1 PowerShell script. No action is expected.
10.10.Validate the file ownership of the runnable.ps1 PowerShell script. Right-click on the
file, select Properties, and then click on Security.
DO417-RHAE2.8-en-1-20200106 309
Chapter 7 | Deploying Files to Managed Hosts
310 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
10.11.Verify that Windows executes the runnable.ps1 PowerShell script. Right-click on the
runnable.ps1, and then select Run with PowerShell from the menu.
11. Clean up your work by running the cleanup-unzip.yml playbook from the Run
managing-files project job template.
11.2. Click the Run managing-files project job template to open it.
11.4. Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 311
Chapter 7 | Deploying Files to Managed Hosts
312 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Objectives
After completing this section, you should be able to use Jinja2 templates to deploy customized
files to managed hosts.
Templating Files
Ansible has a number of modules that can be used to modify existing files. These include
win_lineinfile and assemble, among others. However, they are not always easy to use
effectively and correctly.
A much more powerful way to manage files is to template them. With this method, you write a
template configuration file that is automatically customized for the managed host when the file
is deployed, using Ansible variables and facts. This approach is easier to manage and less error-
prone than manually authoring each file.
Introducing Jinja2
Ansible uses the Jinja2 templating system for template files. Ansible also uses Jinja2 syntax to
reference variables in playbooks, so you already have some familiarity with it.
Using Delimiters
Variables and logic expressions are placed between tags, or delimiters. For example, Jinja2
templates use {% EXPR %} for expressions or logic (for example, loops), and use {{ EXPR }}
for outputting the results of an expression or a variable to the end user. The latter tag, when
rendered, is replaced with a value or values and is seen by the end user. Use {# COMMENT #}
syntax to enclose comments that should not appear in the final file.
In the following example, the first line includes a comment that is excluded in the final file. The
values of referenced system facts replace the variable references in the second line.
Note
Remember that output from the setup module facilitates reviewing the facts
associated with managed hosts, because this module runs and gathers facts by
default. For more information review Managing Facts.
DO417-RHAE2.8-en-1-20200106 313
Chapter 7 | Deploying Files to Managed Hosts
The following example shows how to create a template for an HTML file with variables and facts
retrieved by Ansible from managed hosts. When the associated playbook is executed, any facts are
replaced by their values in the managed host being configured.
Note
A file containing a Jinja2 template does not require any specific file extension
(for example, .j2). However, providing such a file extension can make it easier to
recognize the template file.
<!doctype html>
<!-- {{ ansible_managed }} -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Info</title>
</head>
<body>
<h1>{{ ansible_facts['hostname'] }}</h1>
<ul>
<li>IP: {{ ansible_facts['ip_addresses'][0] }}</li>
<li>OS: {{ ansible_facts['os_name'] }}</li>
<li>Data Center: {{ data_center }}</li>
</ul>
</body>
</html>
Use the following syntax when working with the win_template module. The value associated
with the src key specifies the source Jinja2 template; in this example, the source is the
templates directory relative to the playbook. The value associated with the dest key specifies
the file to create on the destination hosts.
tasks:
- name: template render
win_template:
src: templates/info.j2
dest: C:\Inetpub\wwwroot\info.html
314 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
Note
By default, the win_template module automatically ensures that the processed
template output follows the Windows standard carriage return line feed newline
sequence. Ansible converts Linux or MacOS template files with \n newline
sequences to \r\n Windows line endings.
One way to do this is to use the “Ansible managed” string set in the ansible_managed directive.
This is not a normal variable, but can be used as one in a template. Set the ansible_managed
directive in the ansible.cfg file:
To include the ansible_managed string inside a Jinja2 template, use the following syntax:
{{ ansible_managed }}
In the following example, the value of the result variable is placed in the deployed file only if the
value of the finished variable is True.
{% if finished %}
{{ result }}
{% endif %}
DO417-RHAE2.8-en-1-20200106 315
Chapter 7 | Deploying Files to Managed Hosts
The following example template uses a for statement to run through all the values in the users
variable, replacing myuser with each value, except when the value is Administrator.
{# for statement #}
{% for myuser in users if not myuser == "Administrator" %}
User number {{ loop.index }} - {{ myuser }}
{% endfor %}
The loop.index variable expands to the index number on which the loop is currently running. It
has a value of 1 the first time the loop executes, and it increments by 1 through each iteration.
As another example, this template also uses a for statement, and assumes a myhosts variable is
defined in the current inventory file. This variable contains a list of hosts to be managed. With the
following for statement, all hosts in the myhosts group from the inventory are listed in the file.
For a more practical example, you can use this approach to dynamically generate a C:\Windows
\System32\drivers\etc\hosts file from host facts. Assume that you have the following
playbook:
The following three line templates/hosts.j2 template constructs the file from all hosts in the
group all. In this example, the middle line in the template is extremely long, due to the length
of the variable names. Ansible iterates over each host in the group to get three facts for the C:
\Windows\System32\drivers\etc\hosts file.
Important
You can use Jinja2 loops and conditionals in Ansible templates, but not in Ansible
Playbooks.
316 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
{{ output | to_json }}
{{ output | to_yaml }}
Additional filters are available, such as the to_nice_json and to_nice_yaml filters, which
format a human readable output in either JSON or YAML format.
{{ output | to_nice_json }}
{{ output | to_nice_yaml }}
Both the from_json and from_yaml filters expect strings in either JSON or YAML format,
respectively, to parse them.
{{ output | from_json }}
{{ output | from_yaml }}
References
win_template - Templates a file out to a remote server — Ansible
Documentation
https://docs.ansible.com/ansible/latest/modules/win_template_module.html
DO417-RHAE2.8-en-1-20200106 317
Chapter 7 | Deploying Files to Managed Hosts
Guided Exercise
Outcomes
You should be able to use Jinja2 templates to deploy dynamic content to managed hosts.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Red Hat
Ansible Tower and GitLab from the Windows workstation.
1. Open the Visual Studio Code editor and clone the managing-files repository to your
workstation.
1.1. From workstation, double-click the Visual Studio Code editor desktop icon.
Alternatively, click Search Windows, search for code, and then open Visual Studio
Code.
1.2. To open the command palette, navigate to View → Command Palette or press
Ctrl+Shift+P.
Type clone and select Git: Clone to clone a repository.
3. Replace the CHANGE_ME text on the first line with a template expression that evaluates to
the host name of the managed host.
318 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
# Host: {{ ansible_facts['hostname'] }}
4. Replace the CHANGE_ME text on the second line with a template expression that evaluates
to the current date and time.
5. Update the hosts.j2 template to resolve the custom host names to the IPs of the win1
and win2 managed hosts. Replace 127.0.0.1 on each line with a template expression
wrapped in double curly braces, as follows:
{{ hostvars['win1.example.com'].ansible_facts.ip_addresses[0] }} www1.example.com
{{ hostvars['win2.example.com'].ansible_facts.ip_addresses[0] }} www2.example.com
Note
The name of this dictionary can also use square bracket notation throughout, for
example:
hostvars['host']['ansible_facts']
However, to avoid line wraps in the example text, this syntax is not used in this
exercise.
6. Verify that the final hosts.j2 file matches the following Jinja2 template, and then select
File → Save or press Ctrl+S to save the file.
# Host: {{ ansible_facts['hostname'] }}
# Updated At: {{ now() }}
{{ hostvars['win1.example.com'].ansible_facts.ip_addresses[0] }} www1.example.com
{{ hostvars['win2.example.com'].ansible_facts.ip_addresses[0] }} www2.example.com
7. Open the hosts.yml playbook. Add tasks to update the IIS Web Server content, and then
deploy the templates/hosts.j2 template to the Windows managed host.
---
- name: Web server with custom hosts file deployed
hosts: all
tasks:
- name: IIS Web Server started
win_feature:
DO417-RHAE2.8-en-1-20200106 319
Chapter 7 | Deploying Files to Managed Hosts
name: Web-Server
state: present
Task invoking the win_copy module to create an index.html file and write a host-
specific message.
Task invoking the win_template module to process the Jinja2 template and write
the output to a file.
Declares the template location using the src parameter.
Adds a dest parameter to specify a destination on the managed Windows hosts.
Because the destination is a Windows managed host, use a path with the appropriate
backslashes and any required escape characters.
Add the backup parameter to save a time-stamped backup of the file.
8. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
8.2. Navigate to the Source Control pane, and then click + to stage the changes to both
hosts.yml and hosts.j2.
8.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
8.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
9. From workstation, access your Red Hat Ansible Tower instance at http://
tower.example.com. Login as the student user with the RedHat123@! password.
10. Use the Run managing-files project job template to run your playbook.
320 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
10.4.Click SAVE to update the template, and then click LAUNCH to run the job.
11. After all tasks have completed, verify that the status in the DETAILS pane displays
Successful. If the job was not successful, compare your work with the solutions/
hosts.sol and solutions/templates/hosts.j2.sol solution files in the
managing-files Git repository.
12. Connect to the win1.example.com managed host to verify the deployment of the hosts
file.
12.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
12.2. Enter win1.example.com for the computer, devops as the user name, and
RedHat123@! as the password. Note that devops is a local user, not a domain user, so
do not include the EXAMPLE domain.
12.3. When prompted, click Yes to accept the insecure certificate used in your classroom
environment.
DO417-RHAE2.8-en-1-20200106 321
Chapter 7 | Deploying Files to Managed Hosts
12.6. Navigate to www2.example.com and confirm that the domain resolves correctly to
the WIN2 host.
322 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
13. Connect to the win2.example.com managed host, and then verify deployment of the
hosts file on the win2 managed host.
13.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
13.2. Enter win2.example.com for the computer, devops as the user name, and
RedHat123@! as the password. Note that devops is a local user, not a domain user, so
do not include the EXAMPLE domain.
13.3. When prompted, click Yes to accept the insecure certificate used in your classroom
environment.
DO417-RHAE2.8-en-1-20200106 323
Chapter 7 | Deploying Files to Managed Hosts
13.6. Navigate to www2.example.com and confirm that the domain resolves correctly to
the WIN2 host.
14. Run the cleanup-hosts.yml playbook from the Run managing-files project job
template to clean up your work.
324 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
14.4.Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 325
Chapter 7 | Deploying Files to Managed Hosts
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From the Windows workstation, open the Visual Studio Code editor and clone the
managing-files repository, https://gitlab.example.com/student/managing-
files.git, to C:\Users\student\Documents\managing-files, if the folder is not
already present.
2. Update the templates/index.html.j2 Jinja2 template to display information about the
managed host as follows:
• The HTML comment at the top of the file inserts the ansible_managed variable.
• Deny Users on the managed hosts Write access to the index.html file.
326 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
DO417-RHAE2.8-en-1-20200106 327
Chapter 7 | Deploying Files to Managed Hosts
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From the Windows workstation, open the Visual Studio Code editor and clone the
managing-files repository, https://gitlab.example.com/student/managing-
files.git, to C:\Users\student\Documents\managing-files, if the folder is not
already present.
Note
The following instructions describe how to clone the managing-files repository.
If you cloned the repository in a previous exercise, then you can skip this step.
1.1. From the Windows workstation, double-click the desktop icon to open Visual Studio
Code.
1.2. To clone the updates repository, navigate to View → Command Palette or press
Ctrl+Shift+P to open the command palette.
Type clone, and then select Git: Clone to clone a repository.
When prompted, provide a repository URL of https://gitlab.example.com/
student/managing-files.git and select the Documents folder in the home
directory of the training user as the repository location. This clones the remote
repository into the managing-files folder on the workstation instance.
Click Open from the window that displays after cloning.
328 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
• The HTML comment at the top of the file inserts the ansible_managed variable.
Open the index.html.j2 Jinja2 template file in the templates folder, and then modify it
to insert variables and facts as follows:
<!doctype html>
<!-- {{ ansible_managed }} -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Info</title>
<style type="text/css">
dt { font-weight: bold; }
</style>
</head>
<body>
<h1>{{ ansible_facts['hostname'] }}</h1>
<dl>
<dt>OS</dt>
<dd>{{ ansible_facts['os_name'] }}</dd>
<dt>Memory</dt>
<dd>{{ ansible_facts['memtotal_mb'] }}</dd>
<dt>Processor vCPUs</dt>
<dd>{{ ansible_facts['processor_vcpus'] }}</dd>
<dt>Processor Cores</dt>
<dd>{{ ansible_facts['processor_cores'] }}</dd>
</dl>
</body>
</html>
• Deny Users on the managed hosts Write access to the index.html file.
DO417-RHAE2.8-en-1-20200106 329
Chapter 7 | Deploying Files to Managed Hosts
3.1. Open the review.yml playbook file and modify it to insert content as follows.
---
- name: Deploying Files to Managed Hosts Lab
hosts: all
tasks:
- name: IIS Web Server started
win_feature:
name: Web-Server
state: present
Enable the IIS Web Server feature, which will serve the index.html web page.
Invoke the win_template module to deploy the index.html.js template to the
managed host. Use the backup: yes argument to create a time stamped backup.
Add a permission rule that denies the Users group write access to the
index.html file.
4.1. From Visual Studio Code, save and stage the files. Navigate to the Source Control
panel, and then click + to stage all changes.
4.2. Type Deploys web page from template as the commit message, and then click
Commit or press Ctrl+Enter to commit your changes.
4.3. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
5. From workstation, access your Red Hat Ansible Tower instance at http://
tower.example.com. Log in as the student user the RedHat123@! password.
Add the win2.example.com host to the Default inventory inventory in Ansible Tower
if not added in a previous exercise.
5.1. From workstation, double-click the Ansible Tower desktop icon. Log in to Ansible
Tower using student as the user name and RedHat123@! as the password.
330 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
5.5. If win2.example.com is not already listed in the hosts table, click + to add a new host
to the group. Select New Host from the list.
Field Value
6. Launch your review.yml playbook using the Run managing-files project job
template.
6.4. Click SAVE to update the template, and then click LAUNCH to run the job.
7. Verify that the Run managing-files project job executes successfully. Navigate to
http://win1.example.com and http://win2.example.com to confirm that the web
page is correctly rendered and served.
7.1. Verify that the status in the DETAILS pane displays Successful. Observe the tasks in
the log that indicate changes have occurred on the managed hosts.
DO417-RHAE2.8-en-1-20200106 331
Chapter 7 | Deploying Files to Managed Hosts
7.2. In Chrome, open a new tab and navigate to http://win1.example.com/. The web
server on the win1 managed host returns the generated index.html web page.
7.3. In Chrome, open a new tab and navigate to http://win2.example.com/. The web
server on the win2 managed host returns the generated index.html web page.
332 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
8.1. Click Search Windows, search for remote, and then open Remote Desktop
Connection.
8.2. Enter win1.example.com for the computer, devops as the user name, and
RedHat123@! as the password. Note that devops is a local user, not a domain user, so
do not include the EXAMPLE domain.
8.3. When prompted, click Yes to accept the insecure certificate used in your classroom
environment.
8.4. In the remote win1.example.com session, click Search Windows and then type C:
\Inetpub\wwwroot to search for the web server root directory. Click the file folder to
open it.
DO417-RHAE2.8-en-1-20200106 333
Chapter 7 | Deploying Files to Managed Hosts
8.5. Right-click on the index.html file, select Properties, and then click on the Security
tab.
8.6. Select Users (WIN1\Users) in the Group or user names panel, and verify that the
Deny is selected for Write permissions.
334 DO417-RHAE2.8-en-1-20200106
Chapter 7 | Deploying Files to Managed Hosts
9.4. Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 335
Chapter 7 | Deploying Files to Managed Hosts
Summary
In this chapter, you learned:
• Ansible includes a number of modules for Microsoft Windows file management, such as creating,
copying, and editing files, as well as management of ACLs and file ownership.
• You can use Jinja2 templates to dynamically construct files for deployment.
• A Jinja2 template is usually composed of two elements: variables and expressions. Those
variables and expressions are replaced with values when the Jinja2 template is rendered.
• Jinja2 filters transform template expressions from one kind or format of data to another.
336 DO417-RHAE2.8-en-1-20200106
Chapter 8
DO417-RHAE2.8-en-1-20200106 337
Chapter 8 | Interacting with Users and Domains
Objectives
After completing this section, you should be able to automate the creation and management of
local user and group accounts.
- name: Add new user to the development machine and assign the appropriate groups.
win_user:
name: devops_user
password: plain_text_password
state: present
groups:
- Users
- Developers
groups_action: replace
338 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
The state parameter instructs the machine to remove the user account if it exists on the
system.
Parameter Comments
account_locked Takes a Boolean value of yes or no. When set to no, unlocks
a user account if locked.
user_cannot_change_password Takes a Boolean value of Yes or No. Prevents the user from
changing their password if the value is set to yes.
DO417-RHAE2.8-en-1-20200106 339
Chapter 8 | Interacting with Users and Domains
when the state is set to present, set the username parameter to a valid account name.
When the state parameter set to present, the machine creates or updates the user
account.
When the state is set to present, the username parameter must be set to a valid account
name.
When the state parameter set to absent, the machine removes the user profile.
The following example illustrates removing an existing local user profile for a deleted account.
The name parameter must be set to a valid profile name. Be aware that when the state is set
to absent, and the username is not set, the module removes any profiles contained in the
profile path for the name value.
The state parameter set to absent instructs the machine to remove the user profile.
Important
Remember the important distinction between the win_user_profile module
name and username parameters. The name parameter is the base name for the
profile path. The username parameter is the account name of the security identifier
(SID) for the profile.
Local Groups
The win_group module lets you manage local groups on a Windows host. You can create or
remove a local group with this module.
340 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
DO417-RHAE2.8-en-1-20200106 341
Chapter 8 | Interacting with Users and Domains
• All local, domain, and service user types as username, favoring domain lookups if the host is in a
domain.
The name parameter defines the name of the local group to modify.
The members parameter contains a list of possible local users, domain users or domain
groups that should be removed from the local group.
The state parameter set to absent tells the machine to remove the specified members
from the local group.
References
Windows modules — Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html
342 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Guided Exercise
Outcomes
You should be able to create a new local user, as well as modify the group membership of an
existing local user.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor and clone the ad repository to your workstation
instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
1.2. Click View → Command Palette or press Ctrl+Shift+P to open the command
palette.
Type clone, and then select Git: Clone to clone a repository.
Use a repository URL of https://gitlab.example.com/student/ad.git. When
prompted, select the Documents folder in the home directory of the training user
as the repository location, and then click Select Repository Location. This clones
the remote repository in to the ad folder.
Optionally, select Open from the window that displays after cloning to view the files,
and then skip the next step.
3. Edit the localuser.yml file, and then commit your changes. Modify this file so that it
targets all hosts, and uses the win_user module to create a local user John Snow with
RedHat123@! as the password.
3.1. Select the localuser.yml file, and then change the task name and the details for
the new local user that you want to create.
...output omitted...
hosts: all
tasks:
DO417-RHAE2.8-en-1-20200106 343
Chapter 8 | Interacting with Users and Domains
4. Edit the localuser.yml file, and then commit your changes. Add a new task to the
playbook that adds the new local user to the Print operators group. For this task use
the win_group_membership module.
4.1. Select the localuser.yml file, and then change the name of the second task and
the details for the new group to which you want to add the user.
...output omitted...
- name: John Snow added to the Print operators group
win_group_membership:
name: Print operators
members:
- John Snow
state: present
4.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master
indicating that changes were made.
4.3. Change to the Source Control view, and then click + for localuser.yml to stage
the changes.
4.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
4.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
Click Yes or Ask Me Later when prompted.
5. Access the Ansible Tower web console. Use the Run ad project job template to test
your modified Ansible Playbook.
5.1. Double-click the desktop shortcut labeled Ansible Tower and authenticate with the
user admin and RedHat123@! as the password.
5.3. From the list of templates, select the Run ad project template.
5.5. Select the PROMPT ON LAUNCH check box near the LIMIT option.
5.7. In the RUN AD PROJECT window, type in the win1.example.com host name. Click
NEXT, and then click LAUNCH.
344 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
5.9. Verify that the status of the job in the DETAILS pane displays Successful.
5.10. Click Log Out to exit the Ansible Tower web interface.
DO417-RHAE2.8-en-1-20200106 345
Chapter 8 | Interacting with Users and Domains
Objectives
After completing this section, you should be able to create an Active Directory domain if it does
not exist, and configure host membership, users, and groups in that domain.
- name: Creates a new Windows domain in a new forest with specific parameters
win_domain:
create_dns_delegation: yes
database_path: C:\Windows\NTDS
dns_domain_name: EXAMPLE.COM
domain_mode: Win2012R2
domain_netbios_name: EXAMPLE
forest_mode: Win2012R2
safe_mode_password: plain_text_password
sysvol_path: C:\Windows\SYSVOL
register: domain_install
346 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
The safe_mode_password parameter sets the safe mode password. This parameter is
required. The password value is written in plain text.
The sysvol_path parameter sets the path to the directory where the Sysvol file is
created.
The register parameter registers the state of the outcome; depending on the state, a
handler might be triggered. In this example, when the state changes, the handler triggers a
reboot.
The dns_domain_name parameter specifies the DNS name of the domain for which the host
is promoted as a domain controller.
The domain_admin_user parameter is required. The parameter specifies the name of the
domain administrative user.
The domain_admin_password parameter is required, and specifies the password for the
user in the domain_admin_user parameter. The password value is written in plain text.
The safe_mode_password parameter is required when promoting a server to a domain
controller. This parameter sets the safe mode password for the controller. The password value
is written in plain text.
The state parameter set to domain_controller instructs Ansible to promote the server
to a domain controller.
The register parameter is used to register the state of the outcome; depending on the
state, a handler might be triggered. In this example, when the state changes, the handler
triggers a reboot.
Depending on your local environment configuration, this Ansible module configures the server as
a read-write domain controller in the existing domain, or it can promote the server as an additional
read-only replica of the existing domain. In order to create a read-only domain controller, you must
add the read_only parameter to the playbook, and set it to yes.
DO417-RHAE2.8-en-1-20200106 347
Chapter 8 | Interacting with Users and Domains
The name parameter is the only requirement for the module. This parameter specifies which
of the available Windows roles or features to install.
When set to yes, this option adds all the available sub-features of the specified feature.
When set to yes, this option adds all management tools of the corresponding specified
feature.
The dns_domain_name parameter specifies the domain from which the server will be
demoted.
The domain_admin_user parameter is required. The parameter specifies the name of the
domain administrative user.
The domain_admin_password parameter is required. This parameter specifies the
password for the user in the domain_admin_user parameter. The password value is written
in plain text.
The local_admin_password parameter is required when demoting a server to a domain
member. This parameter sets the local administrator password for the server. The password
value is written in plain text.
The state parameter set to member instructs Ansible to demote the server from a domain
controller to a domain member.
348 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
The workgroup_name parameter sets the name for the workgroup of which the server will
be a part.
The domain_admin_user parameter is required. The parameter specifies the name of the
domain administrative user.
The domain_admin_password parameter is required. This parameter specifies the
password for the user in the domain_admin_user parameter. The password value is written
in plain text.
The state parameter set to workgroup instructs Ansible to remove the server from a
domain.
DO417-RHAE2.8-en-1-20200106 349
Chapter 8 | Interacting with Users and Domains
The name parameter is required. The parameter sets the name of the user to create, remove
or modify.
The firstname parameter sets the user's first name.
The lastname parameter sets the user's last name.
The company parameter set the user's company name.
The password parameter specifies the password for the user. The password value is written
in plain text.
The state parameter defines what type of action that Ansible should perform. When set
to present, Ansible creates or updates the user if the account exists. When set to absent,
Ansible deletes the user account from the domain. When set to query Ansible retrieves the
user account details without making any changes.
The groups parameter adds or removes the user from a list of groups.
Additional details about the user can be specified and stored in your domain.
To remove a user account from the domain, the module requires only two parameters. These
parameters are the proper name of the account to delete, and the state parameter set to
absent.
350 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
DO417-RHAE2.8-en-1-20200106 351
Chapter 8 | Interacting with Users and Domains
References
Ansible Documentation — Windows Modules
https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html
352 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Guided Exercise
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor. If you have not previously cloned the ad repository,
then clone it to your workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
3. Edit the join-ad.yml file, and then commit and push your changes. Modify the file
so that it targets all hosts, and uses the win_domain_membership module to join the
win2.example.com server to the existing example.com AD domain.
3.1. Select the join-ad.yml file, and then change the task name and the details that are
needed for a server to join the example.com domain.
DO417-RHAE2.8-en-1-20200106 353
Chapter 8 | Interacting with Users and Domains
...output omitted...
hosts: all
vars:
domainname: EXAMPLE.COM
dnsname: example.com
domain_admin: Administrator@example.com
tasks:
- name: Joining the "{{ domainname }}" domain
win_domain_membership:
dns_domain_name: "{{ dnsname }}"
domain_admin_user: "{{ domain_admin }}"
domain_admin_password: "{{ password }}"
state: domain
register: domain_state
...output omitted...
Note
Note that the domain_admin_password uses a variable that is not set in the
playbook. For security reasons, the password is not stored in the playbook itself.
Instead, you will create a survey in Ansible Tower to set the value for that variable in
a later step.
3.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master,
indicating that changes were made.
3.3. Change to the Source Control view, and then click + for join-ad.yml to stage the
changes.
3.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
3.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
Click Yes or Ask Me Later when prompted.
Note
More details about Ansible Tower Surveys are discussed in a later chapter. Surveys
prompt users with customized questions. This method supports prompts for
user input of extra variable values that are more user-friendly than those in the
PROMPT ON LAUNCH method.
4.1. Log in to the Ansible Tower interface. Click Templates in the navigation pane.
4.2. In the list of available templates, click Run ad project to edit the job template.
354 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
4.4. On the next screen, supply the following information in the EXTRA VARIABLES text
field at the bottom of the window:
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Selected
4.5. Click +ADD to add this Survey Prompt to the survey. A preview of your survey displays.
Important
Before saving, make sure that the ON/OFF switch in the Survey editor window is
set to ON.
5.3. Click the GROUPS tab then select the Windows group.
5.4. Click the HOSTS tab to access the list of hosts in the group.
5.5. Click + and select New host to add a new host to the group.
Field Value
6. Use the Run ad project job template to test your modified Ansible Playbook.
6.2. From the list of templates, select the Run ad project template.
DO417-RHAE2.8-en-1-20200106 355
Chapter 8 | Interacting with Users and Domains
Note
To select a project for editing, click its name.
6.4. Make sure that the PROMPT ON LAUNCH check field for the LIMIT option is
selected.
6.5. Click SAVE to update the job template, then click LAUNCH to begin execution.
6.6. In the RUN AD PROJECT window, enter win2.example.com as the host name. Click
NEXT.
6.8. Observe the live output of the running job. Joining the domain requires a reboot of the
win2.example.com server. The playbook contains a handler that is triggered when
the host domain settings are changed, causing Ansible to reboot the server. The status
of the job changes after the server successfully restarts.
6.9. Verify that the status of the job in the DETAILS pane displays Successful.
7. Edit the second-ad-server.yml file, and then commit and push your changes. Modify
this file so that it targets all hosts, and uses the win_domain_controller module to
promote the win2.example.com server to a domain controller. You can use this same
module to create a completely new Active Directory domain.
7.1. Select the second-ad-server.yml file, and then change the task name and the
details that are needed for promoting the win2.example.com server to a domain
controller.
...output omitted...
hosts: all
vars:
domainname: EXAMPLE.COM
dnsname: example.com
domain_admin: Administrator@example.com
safe_password: RedHat123@!
tasks:
- name: Promoting the server to an AD controller
win_domain_controller:
dns_domain_name: "{{ dnsname }}"
domain_admin_user: "{{ domain_admin }}"
domain_admin_password: "{{ password }}"
safe_mode_password: "{{ safe_password }}"
state: domain_controller
register: domain_state
...output omitted...
356 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Note
Note that the domain_admin_password uses a variable that is not set in the
playbook. For security reasons, the password is not stored in the playbook itself.
Instead, survey in Ansible Tower is used to set the value for that variable.
7.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master
indicating that changes were made.
7.3. Change to the Source Control view, and then select + for second-ad-server.yml
to stage the changes.
7.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
7.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
Click Yes or Ask Me Later when prompted.
8. Use the Run ad project job template to test your modified Ansible Playbook.
8.2. From the list of templates, select the Run ad project template.
Note
To select a project for editing, click its name.
8.4. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is
selected.
8.6. In the RUN AD PROJECT window, use win2.example.com as the host name. Click
NEXT.
8.8. Observe the live output of the running job. Joining the domain requires a reboot of the
win2.example.com server. The playbook contains a handler that is triggered when
the host domain settings are changed, causing Ansible to reboot the server. The status
of the job changes after the server successfully restarts.
8.9. Verify that the status of the job in the DETAILS pane displays Successful. It takes
some time for the Active Directory Domain Services to complete the status update.
DO417-RHAE2.8-en-1-20200106 357
Chapter 8 | Interacting with Users and Domains
9. Edit the domain-mod.yml file, and then commit and push your changes. Use this file to
create a new domain group, and a domain user who is a member of that new group.
9.1. Select the domain-mod.yml file, and then change the task name and the details that
are needed for creating the new group and the new user.
...output omitted...
hosts: all
...output omitted...
user_password: RedHat123@!
tasks:
- name: Creating a new group in the {{ domainname }} domain
win_domain_group:
name: Test Group
scope: domainlocal
category: security
attributes:
mail: helpdesk@example.com
wWWHomePage: www.example.com
ignore_protection: yes
9.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master
indicating that changes were made.
9.3. Change to the Source Control view, and then select + for domain-mod.yml to stage
the changes.
9.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
9.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
Click Yes or Ask Me Later when prompted.
358 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
10. Add the windc.example.com server to the Default inventory inventory in Ansible
Tower.
10.4.Click + to add a new host to the group. Select New Host from the list that displays.
10.5.Change the authentication method that Ansible uses for the windc.example.com
server to Kerberos to configure centralized authentication. On the next screen, fill in
the details as follows:
Field Value
10.6.Click SAVE.
Field Value
NAME AD Administrator
ORGANIZATION Default
USERNAME Administrator
PASSWORD RedHat123@!
11.4. Leave the other fields untouched, and click SAVE to create the new credential.
12. Use the Run ad project job template to test your modified Ansible Playbook.
12.2. From the list of templates, select the Run ad project template.
DO417-RHAE2.8-en-1-20200106 359
Chapter 8 | Interacting with Users and Domains
12.4. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is
selected.
12.7. In the RUN AD PROJECT window, choose the AD Administrator credentials and
click NEXT.
12.8. In the LIMIT text field, type the windc.example.com hostname, and then click
NEXT.
12.11. Verify that the status of the job in the DETAILS pane displays Successful.
13. Edit the Run ad project job template and turn off the survey.
Note
To select a project for editing, click its name.
13.4. At the top of the Survey editor window, toggle ON/OFF and set it to OFF.
14. Click Log Out to exit the Ansible Tower web interface.
360 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Objectives
After completing this section, you should be able generate an Ansible inventory dynamically in
Red Hat Ansible Tower, based on Active Directory domain membership.
Dynamic Inventories
When Ansible runs a playbook, it uses an inventory to determine against which hosts the plays
should run. Both Ansible and Ansible Tower make it easy to set up a static inventory of hosts that
you specify explicitly in an inventory.
However, these static lists require manual administration to keep them up to date. This can be
inconvenient or challenging, especially when an organization wants to run the playbooks against
hosts that are dynamically created in a virtualization or cloud computing environment.
In this scenario, using a dynamic inventory is preferable. Dynamic inventories are scripts that, when
run, dynamically determine which hosts and host groups should be in the inventory, based on
information from some external source. External sources can include the API for cloud providers,
Cobbler, LDAP directories, or other third-party configuration management database (CMDB)
software. Using a dynamic inventory is a recommended practice in a large and quickly changing IT
environment, where systems are frequently deployed, tested, and then removed.
By default, Ansible Tower comes with built-in dynamic inventory support for a number of external
inventory sources (or cloud inventory sources), including:
• VMware vCenter
• OpenStack
In addition, custom dynamic inventory scripts can direct Ansible Tower to access inventory
information from other sources. Ansible Tower can retrieve those scripts from a project that uses a
repository like Git as a source.
The remainder of this section examines two examples of dynamic inventory configuration in
Ansible Tower. The first example illustrates the built-in support for Microsoft Azure Resource
Manager. The second example investigates how you can use a custom dynamic inventory scripts
with Active Directory.
DO417-RHAE2.8-en-1-20200106 361
Chapter 8 | Interacting with Users and Domains
The basic process for configuring dynamic inventories is similar when using any of the built-in
cloud sources:
1. Create a credential to authenticate to the cloud data source you intend to use; the credential
type must match the source.
3. In the new inventory, create a Source with one of the built-in dynamic inventory sources
(instead of Manual). Use the new credential to authenticate to that source. You might also
want to set other options, like having it automatically update upon launch.
This process works for Microsoft Azure based dynamic inventories. Figure 8.1 illustrates how to
create credentials for use by an Microsoft Azure Resource Manager dynamic inventory, including
the information that you must provide:
Some of these items will be familiar from working with other objects in Ansible Tower, including
Name, Description and Organization. The only new item is the Credential Type. You must
choose the appropriate credential type for the product that you are using. In this example, the
product is Microsoft Azure Resource Manager.
Username
The user who can connect to the Microsoft Azure account.
Password
The password for the user.
362 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Subscripton ID (required)
Subscription UUID in an Azure construct, which is mapped to a username.
Client ID
The Azure client ID.
Client Secret
The Azure client secret.
Tenant ID
The Azure client tenant ID.
The Ansible Tower synchronization mechanism uses these newly created credentials. After
creating the credentials, select Inventories in the navigation pane. As Figure 8.2 illustrates, you
must create a new Inventory:
Give the new inventory a unique name, and assign it to an existing organization. After saving the
new inventory configuration, click SOURCES to create a new source for the inventory. Ansible
Tower uses this source in conjunction with the existing Microsoft Azure Resource Manager scripts
and the previously created credentials. Figure 8.3 shows an example of such a source:
DO417-RHAE2.8-en-1-20200106 363
Chapter 8 | Interacting with Users and Domains
This new source uses the built-in Ansible Tower support for Microsoft Azure Resource Manager
as the SOURCE, and the new credentials for your Microsoft Azure environment as the
CREDENTIAL. There are three UPDATE OPTIONS from which to choose:
Overwrite
If this option is selected, then the inventory update process deletes all child groups and hosts
from the local inventory that not found on the external source. By default, this option is not
active, which means that all child hosts and groups not found on the external source remain
untouched.
Overwrite Variables
If this option is not selected, then Ansible Tower merges local variables with those found on
the external source. Ansible Tower removes all variables not found on the external source.
Update on Launch
If this option is activated, then each time a job runs using this inventory, Ansible Tower
refreshes this inventory from the external source before the job tasks are executed.
In the source list for the inventory, the small cloud icon to the left of the source name shows
the status of the dynamic inventory synchronization for that source. When it is disabled, no
status is available. To start the synchronization process, click the syncronize button. When the
synchronization finishes, the status of the cloud icon changes to green if the synchronization is
successful, or red if it failed.
After a successful synchronization with the external source, review the child groups and hosts
which have been created in Ansible Tower using information from the external source. The child
groups contain the hosts visible on the HOSTS lists. Click the group name to display the contents
of that group, and then review each child group including a list of the associated hosts. This
inventory is updated every time you synchronize it with the external source. You can perform the
synchronization manually, schedule it using Ansible Tower mechanisms, or set it to automatically
update each time a job runs using that inventory.
364 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Many examples of custom inventory scripts for use with various external sources have been
contributed by the community the Git repository for Ansible at https://github.com/ansible/
ansible/tree/devel/contrib/inventory/.
If you want to write your own custom inventory script, information is available at
Developing Dynamic Inventory Sources [http://docs.ansible.com/ansible/dev_guide/
developing_inventory.html] in the Ansible Developer Guide. When you invoke the dynamic
inventory script with the --list option, it must output the inventory in JSON format.
{
"databases" : {
"vars" : {
"example_db" : true
},
"hosts" : [
"db1.demo.example.com",
"db2.demo.example.com"
]
},
"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"
]
}
As demonstrated in the preceding example, each group contains a list of hosts, potential child
groups, possible group variables, or a list of hosts.
DO417-RHAE2.8-en-1-20200106 365
Chapter 8 | Interacting with Users and Domains
Note
When called with the option --host hostname, the script prints a JSON hash/
dictionary of the variables for the specified host (potentially an empty JSON hash
or dictionary if there are no variables provided).
Optionally, if the --list option returns a top-level element called _meta, all host
variables can be returned in one script call, which improves script performance. In
that case, --host calls are not made.
To upload a custom inventory script into Ansible Tower, select Inventories Scripts in the
navigation pane of the Ansible Tower web interface. Click the + button to add a new custom
inventory script.
Define a new name for the custom inventory script in the NAME field, select an organization in the
ORGANIZATION field, and then paste the actual script into the CUSTOM SCRIPT text box. Click
the SAVE button.
After importing and defining the dynamic inventory script in Ansible Tower, configure it just like any
of the built-in dynamic inventories:
1. Create a new source in an existing inventory for the dynamic inventory. Set the SOURCE to
Custom Script, and provide the name of the custom script in the CUSTOM INVENTORY
SCRIPT field; this is the name you gave the script when importing it into Ansible Tower.
2. Synchronize the source with the inventory source, for example from your Active Directory
server.
366 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Figure 8.5: Adding new custom script as a source for a dynamic inventory
References
Ansible Tower User Guide
https://docs.ansible.com/ansible-tower/latest/html/userguide/
DO417-RHAE2.8-en-1-20200106 367
Chapter 8 | Interacting with Users and Domains
Guided Exercise
Outcomes
You should be able to add a custom inventory script and use it to populate a Dynamic
Inventory in Tower.
Open your RDP client and connect to the Windows workstation system using training
as the user name. Use the unique password that is displayed on the Online Lab tab of the
ROL interface to connect to workstation over RDP.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. From workstation, click the Ansible Tower icon on your desktop to access Ansible
Tower.
Log in to the web console using admin, and RedHat123@! as the password.
Field Value
NAME ldap-inventory.py
ORGANIZATION Default
368 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
2.4. Launch the Visual Studio Code editor, navigate to File → Open Folder, and then
select the C:\Users\student\Documents\ad folder to open the ad repository.
Copy the contents of the ldap-inventory.py script into the CUSTOM SCRIPT
field.
Field Value
ORGANIZATION Default
• ansible_connection: winrm
• ansible_winrm_server_cert_validation: ignore
• ansible_winrm_transport: kerberos
Field Value
4.4. For UPDATE OPTIONS, select the OVERWRITE option. This option instructs Ansible
Tower to overwrite the hosts if they are already present in the inventory.
DO417-RHAE2.8-en-1-20200106 369
Chapter 8 | Interacting with Users and Domains
5.1. Scroll down and click the synchronize button for Custom Script, and then wait until
the cloud becomes green and static.
5.2. Click HOSTS to ensure that the inventory now contains four hosts, all of them
associated with a new windows group.
6. Switch back to Visual Studio Code, and then edit the add-computers.yml file. Modify
this file so that it targets all hosts, and uses the win_domain_membership module to join
the win2.example.com server to the existing example.com AD domain. When you are
finished, commit and push your changes.
6.1. Select the add-computers.yml file, and then change the task name and the details
that are needed for a server to join the example.com domain.
...output omitted...
- name: A new Linux host is added to the "{{ domainname }}"" AD domain
win_domain_computer:
name: LINUX1
dns_hostname: linux1.{{ dnsname }}
ou: "CN=Computers,DC=example,DC=com"
description: Linux server example
enabled: yes
state: present
- name: A new Windows host is added to the "{{ domainname }}" AD domain
win_domain_computer:
name: WIN_TEST
sam_account_name: win_test$
dns_hostname: win_test.{{ dnsname }}
ou: "CN=Computers,DC=example,DC=com"
description: Windows server example
state: present
Warning
Make sure that the name in the sam_account_name: option ends with a $ sign.
SAM accounts must always end with the $ sign.
6.2. Click Save. Note the status icons in the lower left. There is an asterisk next to master
indicating that changes have been made.
6.3. Change to the Source Control view, and then click + for add-computers.yml to
stage the changes.
6.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
Click Yes or Ask Me Later when prompted.
370 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
7. Switch to the Ansible Tower web interface, and then use the Run ad project job
template to test your modified Ansible Playbook.
Note
To select a project for editing, click its name.
7.4. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is
selected.
7.5. Make sure that the PROMPT ON LAUNCH check box for the CREDENTIAL option is
selected.
7.6. Select the PROMPT ON LAUNCH check box for the INVENTORY option.
7.8. In the RUN AD PROJECT window, select Dynamic inventory. Click NEXT.
7.9. From the list of available credentials, choose the AD Administrator credentials. Click
NEXT.
Note
The AD Administrator credentials were created in the previous exercise. If you do
not have these credentials, follow the instructions from the previous guided exercise
(Step 11) to create them.
DO417-RHAE2.8-en-1-20200106 371
Chapter 8 | Interacting with Users and Domains
7.10. In the LIMIT field type the windc.example.com hostname. Click NEXT then click
LAUNCH.
7.12. Observe the live output of the running job. The status of the job changes after the
server successfully restarts.
7.13. Verify that the status of the job in the DETAILS pane displays Successful.
8. Synchronize the host list from Active Directory using the dynamic inventory, and verify that
the two new hosts are present in the inventory.
8.4. Click the synchronize button for Custom Script, and then wait until the cloud
becomes green and static.
8.5. Click HOSTS, and then verify that the linux1.example.com and
win_test.example.com hosts added to Active Directory are now in the inventory.
372 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Edit the localuser-review.yml playbook in the ad repository, and make the indicated
changes. Commit and push your changes to the Git repository, using a commit message of of
Adds users and manage group membership. Comments in the playbook indicate the
changes to make.
Give the first task a name of Two local users are created.
• Rename the second task to The Review User1 user is added to the Print
Operators group.
• Update the first task with the correct Ansible module, and the module options to add two
local users.
• Update the second task with the correct Ansible module and the module options to add
the Review User1 user to the Print Operators local group.
2. Update the Run ad project job template to use the modified localuser-review.yml
Ansible Playbook. Update the template to instruct Ansible Tower to prompt you for the host
to target, and the credentials and inventory to use.
Launch a job using the template, and when prompted use win1.example.com as the target
host, DevOps as the credentials, and Default inventory as the inventory.
DO417-RHAE2.8-en-1-20200106 373
Chapter 8 | Interacting with Users and Domains
Note
You created the AD Administrator credentials in a previous exercise. If you do
not have these credentials, follow the instructions in the Managing Active Directory
Domains guided exercise to create them. The steps are also displayed in the solution
for this lab.
374 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Edit the localuser-review.yml playbook in the ad repository, and make the indicated
changes. Commit and push your changes to the Git repository, using a commit message of of
Adds users and manage group membership. Comments in the playbook indicate the
changes to make.
Give the first task a name of Two local users are created.
• Rename the second task to The Review User1 user is added to the Print
Operators group.
• Update the first task with the correct Ansible module, and the module options to add two
local users.
• Update the second task with the correct Ansible module and the module options to add
the Review User1 user to the Print Operators local group.
1.1. Launch the Visual Studio Code editor. Navigate to File → Open Folder, and then
select the c:\Users\student\Documents\ad folder to open the c:\Users
\student\Documents\ad directory.
DO417-RHAE2.8-en-1-20200106 375
Chapter 8 | Interacting with Users and Domains
• The first task should use the win_user module to create the Review User1 and
Review User2 users.
• The second task should use the win_group_membersip module to add Review
User1 to the Print operators group.
---
hosts: all
tasks:
- name: Two local users are created
win_user:
name: "{{ item }}"
password: RedHat123@!
state: present
groups:
- Users
loop:
- Review User1
- Review User2
- name: The Review User1 user is added to the Print operators group
win_group_membership:
name: Print operators
members:
- Review User1
state: present
1.3. Save your changes. Note the status icons in the lower left. There will be an asterisk next
to Master to indicate that there are new changes
1.4. Change to the Source Control view, and then click + for the localuser-review.yml
playbook to stage the changes.
1.5. Enter a commit message of Adds users and manage group membership, and
then press Ctrl+Enter to commit the changes.
1.6. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
2. Update the Run ad project job template to use the modified localuser-review.yml
Ansible Playbook. Update the template to instruct Ansible Tower to prompt you for the host
to target, and the credentials and inventory to use.
Launch a job using the template, and when prompted use win1.example.com as the target
host, DevOps as the credentials, and Default inventory as the inventory.
2.1. Double-click the Ansible Tower desktop icon to access Ansible Tower.
376 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
2.3. From the list of templates, select the Run ad project template.
Note
To select a project for editing, click its name.
2.5. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is selected.
2.6. Make sure that the PROMPT ON LAUNCH check box for the CREDENTIAL option is
selected.
2.7. Make sure that the PROMPT ON LAUNCH check box for the INVENTORY option is
selected.
2.9. In the RUN AD PROJECT window, choose the Default inventory and then click
NEXT.
2.10. In the RUN AD PROJECT window, choose the DevOps credentials and then click
NEXT.
2.11. In the LIMIT field, type win1.example.com as the host name, click NEXT, and then
click LAUNCH.
DO417-RHAE2.8-en-1-20200106 377
Chapter 8 | Interacting with Users and Domains
2.13. Verify that the status of the Job in the DETAILS pane displays Successful.
3.1. From Visual Studio Code, open the domain-mod-review.yml playbook in the ad
project and update it. Use the win_domain_group module for the first task, to create a
new group in the EXAMPLE.COM domain.
---
- name: Creating AD groups and users
hosts: all
vars:
domainname: EXAMPLE.COM
user_password: RedHat123@!
tasks:
- name: New group in the "{{ domainname }}" is created
win_domain_group:
name: Review Group
scope: global
3.2. Update the second task to use win_domain_user to create a new user in the domain.
The groups parameter allows you to manage group membership for the user.
...output omitted...
- name: New user in the "{{ domainname }}" is created
win_domain_user:
name: oliver
firstname: Oliver
lastname: Stone
password: "{{ user_password }}"
state: present
groups:
- Domain Users
- Review Group
3.3. Save your changes. Note the status icons in the lower left. There is an asterisk next to
Master, indicating that changes have been made.
3.4. Change to the Source Control view, then click + for domain-mod-review.yml to
stage the changes.
3.5. Enter a commit message of Create new group in domain and user, and then
press Ctrl+Enter to commit your changes.
378 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
3.6. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
4. Update the Run ad project job template in Ansible Tower to use the domain-mod-
review.yml Ansible Playbook. Update the job template so that it prompts you at launch for
the credential, the inventory, and the host to target.
Launch a job using the template, and when prompted select Dynamic inventory as the
inventory, AD Administrator as the credentials, and windc.example.com as the host.
Note
You created the AD Administrator credentials in a previous exercise. If you do
not have these credentials, follow the instructions in the Managing Active Directory
Domains guided exercise to create them. The steps are also displayed in the solution
for this lab.
4.2. If you have not yet created the AD Administrator credentials, click Credentials in
the navigation pane.
Field Value
NAME AD Administrator
ORGANIZATION Default
USERNAME Administrator
4.5. Leave the other fields untouched, and click SAVE to create the credential.
4.7. From the list of templates, select the Run ad project template.
Note
To select a project for editing, click its name.
4.9. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is selected.
DO417-RHAE2.8-en-1-20200106 379
Chapter 8 | Interacting with Users and Domains
4.10.Make sure that the PROMPT ON LAUNCH check box for the CREDENTIAL option is
selected.
4.11. Make sure that the PROMPT ON LAUNCH check box for the INVENTORY option is
selected.
4.13. In the RUN AD PROJECT window, choose the Dynamic inventory, and then click
NEXT.
4.15. In the LIMIT field, type the windc.example.com hostname, and then click NEXT.
4.17. Verify that the status of the job in the DETAILS pane displays Successful.
4.18. Click Log Out to exit the Ansible Tower web interface.
380 DO417-RHAE2.8-en-1-20200106
Chapter 8 | Interacting with Users and Domains
Summary
In this chapter, you learned:
• You can use the win_user Ansible module to manage local user accounts, including passwords
and groups.
• You can create and modify local and domain groups with the win_group and
win_domain_group modules.
• You can use the win_group_membership module to manage users from local groups.
• A dynamic inventory is an inventory that automatically updates its list of members and groups
from an external data source, such as a cloud service's API, a database, or another CMDB
provider.
• Red Hat Ansible Tower includes built-in support for some dynamic inventory sources, and scripts
can be imported to support others.
DO417-RHAE2.8-en-1-20200106 381
382 DO417-RHAE2.8-en-1-20200106
Chapter 9
Automating Windows
Administration Tasks
Goal Automate common Windows Server administration
tasks.
DO417-RHAE2.8-en-1-20200106 383
Chapter 9 | Automating Windows Administration Tasks
Objectives
After completing this section, you should be able to run arbitrary PowerShell commands, configure
PowerShell modules, and set up scheduled tasks on managed hosts with Ansible Playbooks.
For example, win_user is a module designed to perform a particular task: managing local users.
However, there are a number of modules that you can use to run commands from the command
line or through scripts. In this section, we will look at four of these modules:
• win_command runs a command, but does not use the Windows shell.
• win_shell runs a command using a Windows shell, and supports variable expansion and other
shell features.
The command to run. This example invokes wbadmin to create a backup of the operating
system in C:\backup.
The context for the command, such as the directory in which Ansible runs the command.
chdir instructs Ansible to run the command from the specified directory. This is the
equivalent of running cd before running the command.
creates instructs Ansible to verify if the specified resource exists before running the
command. In this example, Ansible runs the command only if C:\backup is not present on
the system.
384 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
This demonstrates how you can pass multiple lines to the module. In this example, Ansible
uses the Test-Connection PowerShell function to send ICMP packets to the server-1
server.
Important
The win_psexec module requires that PsExec is available on the Ansible managed
hosts on which the task runs. However, PsExec need not be present on the servers
that PsExec itself targets.
In addition, using this module with a certain set of privileges (for example, a
credential) assumes that you configured the privileges on the servers that PsExec
targets.
This is a useful module when running a set of commands on multiple hosts managed by Ansible,
when Ansible cannot access the hosts directly. For example, if the hosts are on a protected
network, they might not be directly accessible. You can configure software or update the network
configuration of your environment using this command. Use the hostnames parameter to define
the list of servers to which to connect.
This instructs Ansible to connect to each server in the list and run the command. This
example is equivalent to the following commands:
DO417-RHAE2.8-en-1-20200106 385
Chapter 9 | Automating Windows Administration Tasks
In the example, the password is set in the task, but Ansible Tower can prompt the user to
enter a value for the password variable.
Defines a list of hosts to target. Ansible connects to the managed host, then runs PsExec
against the hosts defined in the list. You can use either a DNS name, or an IP address, to
connect to the managed hosts. If you use a DNS name, the managed host must be able to
resolve the name. To run against all computers in the current domain use \\*.
When set to no, this option allows you to run the remote command as a limited user, stripping
Administrator privileges from the process or command. When set to yes, PsExec runs the
remote command as a privileged user.
Use this parameter to define a process priority level from among the following six levels:
• Realtime
• High
• Above normal
• Normal
• Below normal
• Low
Like the other modules, you can set the context for the execution of the script, such as the
directory in which Ansible must run the script.
This module is useful if you have a script that the control node can access, but that the managed
hosts cannot. This is also useful if you have legacy scripts that cannot be converted to Ansible
modules.
Important
When using Ansible Tower, put your scripts in the repository that contains the
playbooks to run, and use a relative path to access the scripts. This allows Ansible to
access the scripts without the need to access your Ansible Tower instance and make
changes.
Defines the local path to a script; that is, a path on the host that runs Ansible. In this example,
the local path is a Linux directory that contains Windows scripts in the repository.
386 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Instructs Ansible to abort the execution of the script if the resource that you define in the
creates parameter exists on the remote system.
Instructs Ansible to use the shell that you define here to run the script.
Moreover, Ansible always returns a status of changed, even if the command does not make a
change to the system. One mitigation strategy is to use changed_when, which allows you to
implement your own logic to decide what constitutes a change. Operations that do not change
anything on your systems return a status of OK.
In short, these modules can have some unexpected and dangerous effects. Some possible
situations you might encounter these effects include:
• A component depends on a file that is recreated every time you run a playbook, such as a TLS
certificate.
• The task restores a database each time that you run a play.
Note
Be careful when using these modules, and choose Ansible modules designed
for specific tasks whenever possible. This saves time by reducing the need for
conditionals to check the system before and after running tasks, and makes your
plays more robust.
Comparing Modules
The following table compares and contrasts the various modules.
DO417-RHAE2.8-en-1-20200106 387
Chapter 9 | Automating Windows Administration Tasks
Note
The block style indicator (>) allows you to use multiline statements, which are
concatenated at execution. This is a useful syntax for passing multiple parameters to
a command.
tasks:
- name: Interface index is retrieved
win_shell: >
(Get-NetIpInterface "{{ net_adapter }}" |
Select-Object -ExpandProperty InterfaceIndex -last 1 |
Out-String)
register: net_index
handlers:
- name: restart_server
win_reboot:
388 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
The trim filter strips the output for characters, such as carriage returns.
This command notifies the restart_server handler, which instructs the server to reboot if
the command updates the network device.
Note
In this example, the trigger always runs and the server restarts every time. One
way to improve this playbook is to add an extra task that verifies whether the DNS
entries are already set. Doing so prevents the server from restarting if there is no
change to DNS entries.
Ansible skips the backup if the log file exists, as defined by the creates variable. The
failed_when statement instructs Ansible to abort the play if Robocopy returns an exit code
other than 0.
Note
Although you can use the win_robocopy Ansible module, it does not support all
Robocopy options.
Optionally, you can use win_shell to send an email to administrators about the failure.
DO417-RHAE2.8-en-1-20200106 389
Chapter 9 | Automating Windows Administration Tasks
For more sophisticated automation, you can run the following PowerShell script when the backup
fails. The PowerShell scripts supports the usage of external SMTP servers with authentication.
function Send-ToEmail([string]$email){
$message = new-object Net.Mail.MailMessage;
$message.From = "backup_server@acme.org";
$message.To.Add($email);
$message.Subject = "Backup did not complete";
$message.Body = "Backup did not complete on the backup server. Please review the
logs";
The playbook queries the certificates store and the configuration of the default IIS website, and
then runs additional verifications to determine the actions to take.
tasks:
- name: Certificate is retrieved
win_shell: dir cert:\localmachine\my\
register: result_output
390 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
win_shell: >
New-SelfSignedCertificate
-DnsName "{{ inventory_hostname }}"
-CertStoreLocation cert:\LocalMachine\My
-KeyExportPolicy Exportable
failed_when: cert_creation.rc != 0
when: 'dns_name not in result_output.stdout'
The task checks for the presence of a certificate in the SSL store, and then saves the output
in the result_output variable.
The task generates an SSL certificate whose name matches the dns_name variable.
The task aborts the play if the command fails, that is, if the return code is other than 0.
Ansible instructs the system to create the certificate only if it is not present in the store. For
this verification, the task inspects the output of the result_output variable.
The task invokes the Get-IISSiteBinding cmdlet to verify if the default IIS site has an
SSL binding.
The task retrieves the thumbprint of the SSL certificate, and then saves the output in the
cert_thumbprint variable.
Finally, the playbook creates a binding that associates the SSL certificate to the IIS site.
Ansible passes the standard output that is in the cert_thumbprint variable to the
certificate_hash parameter.
The when statement instructs Ansible to skip the task if the binding is present.
Important
To use this module, you must allow connections through the TCP port 45 and UDP
port 137 on the servers to which PsExec connects.
DO417-RHAE2.8-en-1-20200106 391
Chapter 9 | Automating Windows Administration Tasks
To interact with PsExec, use the win_psexec module. This module supports various options, such
as the credentials to use, whether to interact with the desktop on the remote systems, and setting
a priority for the process.
The following example shows how to configure the firewall for two web servers, and how to retrieve
a file from these servers after the command runs. The return code allows Ansible to abort the play
if the PsExec command does not succeed.
Note
The hostname parameter defines a list of hosts that PsExec connects to, and
on which commands are run. They can be different from the hosts that Ansible
manages.
tasks:
- name: Firewall rule is added
win_psexec:
command: >-
netsh advfirewall firewall
add rule name="Open Port 80" dir=in
action=allow protocol=TCP localport=80"
executable: C:\PsTools\PsExec.exe
hostnames:
- web-001
- web-002
- web-003
elevated: yes
username: Administrator
password: 'D3m0$'
priority: realtime
register: psexec_command
failed_when: psexec_command.rc != 0
392 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
The >- sign instructs Ansible to remove the new line at the end of the command.
Instructs Ansible to connect to each server in the list, and run the netsh command to open
the firewall port 80. The psexec_command variable stores the result of the command.
Defines the location of the PsExec utility. This is a useful setting as PsExec can run from
anywhere.
Defines a list of hosts to target. Ansible connects to the managed host, as defined by the
hosts parameter, and then runs PsExec against the hosts that you define in the list. You can
use either a DNS name, or an IP address, to connect to the managed hosts. The managed
host must be able to either resolve or access the server.
Note
To run against all computers in the current domain use \\*.
Retrieves a file from the web servers, after PsExec configured the firewall on those servers.
The item keyword instructs Ansible to loop over the three web servers.
Adds the Certificate Authority (CA) to the certificate store of the local machine.
Use Ansible to download new modules from module galleries, such as the PowerShell Gallery,
available at https://www.powershellgallery.com/.
PowerShell repositories describe the endpoints that host these modules; after adding a repository,
use the Install-Module cmdlet to install that repository.
Ansible offers two modules for managing your PowerShell repositories and modules:
• win_psmodule
Supports installing or removing a PowerShell module from the list of configured repositories or a
custom gallery.
• win_psrepository
Supports managing your PowerShell modules repository. It takes a name and a source as
parameters to either add or remove a repository.
The following example shows how to add a custom repository, and install a PowerShell module
from that repository, using Ansible.
tasks:
- name: Repository is added
win_psrepository:
source: https://www.powershellgallery.com/api/v2/
name: PowerShell Gallery
state: present
DO417-RHAE2.8-en-1-20200106 393
Chapter 9 | Automating Windows Administration Tasks
This task creates the PowerShell Gallery repository. It then saves the output to the
ps_gallery variable. Use state: absent to remove the repository, which is what the
Unregister-PSRepository PowerShell cmdlet does.
This is the API endpoint of the repository.
This task invokes the Get-PSRepository cmdlet to ensure that the repository is present. If
not, the play fails.
This task instructs the system to install a set of modules from the repository. To remove
these modules, give the state parameter a value of absent. This is equivalent to the
Uninstall-Module PowerShell cmdlet.
You can run many tasks, such as running a program, executing a PowerShell script, sending an
email, installing a service, and so on. You can create tasks for the following:
There are many ways to interact with the task scheduler, such as using the interface, or
programmatically via PowerShell, using C++, or C# code for your Windows applications.
A powerful way to use the task scheduler is the invocation of PowerShell as an action, which then
runs a script via the -F option. This allows you to create advanced scripts for managing your
systems, and to use the task scheduler to run them at intervals that you define.
394 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
win_scheduled_task has many options, such as the list of actions to configure for the task (the
arguments, the working directory, and a path for the executable), whether to run the task using the
Run command or the Context menu, the schedule for the task, and the task priority.
Note
For the list of all parameters, consult win_scheduled_task — Ansible Documentation
listed in the references section.
The following example shows how to create a scheduled task that runs a PowerShell script when
the server starts, and when the user that owns the task logs on. The script iterates over a list of
servers and attempts to reach them.
tasks:
- name: A scheduled task is created
win_scheduled_task:
name: QueryHosts
description: >
Run a PowerShell script that uses ping to reach the servers
in the environment
DO417-RHAE2.8-en-1-20200106 395
Chapter 9 | Automating Windows Administration Tasks
author: sylvia@acme.org
enabled: true
hidden: true
actions:
- path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
arguments: >
-ExecutionPolicy Unrestricted
-NonInteractive -File C:\Scripts\pingHosts.ps1
triggers:
- type: boot
- type: logon
priority: 1
state: present
When hidden is set to true, the task does not appear in the task manager console. By
default, hidden is set to false.
Creates a new action; in this example, that action is a task that invokes PowerShell.
The arguments parameters defines a list of optional arguments. The task scheduler passes
these arguments to the command.
Defines the list of triggers; in this example, the scheduled task runs when the system starts,
and when the owner of the task logs in.
Defines a priority for the task, which accepts a value between 0-10. See TaskSettings.Priority
property — Windows Documentation listed in the references section for a list of possible
priorities.
After executing the play, the task is visible in the task scheduler interface.
396 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Use the win_scheduled_task_stat module to retrieve information about the scheduled tasks
on the system. The module returns information such as the actions, the owner of the task, or the
triggers.
tasks:
- name: Information about QueryHosts is retrieved
win_scheduled_task_stat:
name: QueryHosts
The output is a JSON dictionary that contains detailed information about the task:
The state JSON dictionary contains information about the execution of the scheduled task. You
can further parse this data to determine the success or failure of the job.
{
...output omitted...
"principal": {
"display_name": null,
"logon_type": "TASK_LOGON_INTERACTIVE_TOKEN",
"user_id": "WIN1\\devops",
"group_id": null,
"id": "Author",
"run_level": "TASK_RUNLEVEL_HIGHEST"
},
"task_exists": true,
...output omitted...
"state": {
"status": "TASK_STATE_READY",
"last_task_result": 0,
"next_run_time": "1899-12-30T00:00:00",
"last_run_time": "2019-09-25T17:08:16",
"number_of_missed_runs": 0
},
{
"hide_app_window": false,
"arguments": "-ExecutionPolicy Unrestricted -NonInteractive -File C:\
\Scripts\\pingHosts.ps1",
"path": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"working_directory": null,
"type": "TASK_ACTION_EXEC",
"id": null
}
],
"registration_info": {
"description": "Run a PowerShell script that uses ping to reach the
servers in the environment",
"author": "sylvia@acme.org",
DO417-RHAE2.8-en-1-20200106 397
Chapter 9 | Automating Windows Administration Tasks
"documentation": null,
"uri": "\\QueryHosts",
"source": null,
"version": null,
"date": null,
"security_descriptor": null
},
"settings": {
"run_only_if_network_available": false,
"execution_time_limit": "PT72H",
"idle_settings": {
"wait_timeout": "PT1H",
"idle_duration": "PT10M",
"stop_on_idle_end": true,
"restart_on_idle": false
...output omitted...
Note
Use this module to obtain information about your scheduled task and how to further
tweak it.
References
win_scheduled_task — Ansible Documentation
https://docs.ansible.com/ansible/latest/modules/win_scheduled_task_module.html
PowerShell Gallery
https://www.powershellgallery.com/
398 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Guided Exercise
Outcomes
You should be able to:
• Write an Ansible Playbook to generate an SSL certificate, and configure an IIS site to use
it.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Open Visual Studio Code, and then clone the windows repository available at https://
gitlab.example.com/student/windows.git.
1.1. Click the Visual Studio Code desktop icon to open the editor.
2. Open the powershell-modules.yml Ansible Playbook. The following steps describe the
changes to make to the playbook in order to configure a PowerShell repository and install a
set of modules.
DO417-RHAE2.8-en-1-20200106 399
Chapter 9 | Automating Windows Administration Tasks
The playbook contains placeholders that you must change. Do not update the first
task, which clears any existing repositories.
2.2. Create two variables in the vars section of the playbook as follows:
2.3. Next, create a task that registers a new PowerShell repository. Use the
win_psrespository module to accomplish this task. The module requires a source,
a name, and a state. Use the powershell_repo_endpoint as the module source
parameter.
...output omitted...
tasks:
- name: Current repositories are unregistered
win_shell: Unregister-PSRepository "{{ item }}"
ignore_errors: true
loop:
- PowerShell Gallery
- PSGallery
2.4. Add a task to ensures that the PowerShell repository is present. The task captures the
output in the repo_status variable, and then fails if the command does not return 0.
The changed_when: false statement instructs Ansible to return a status of ok,
because the task does not make any changes to the system.
Note
Notice the indentation. Because register, failed_when, and changed_when
are not part of the module parameters, you must indent them at the same level as
the module name.
400 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
...output omitted...
- name: Repository is queried
win_shell: Get-PSRepository "PowerShell Gallery"
register: repo_status
failed_when: repo_status.rc != 0
changed_when: false
2.5. Add a task for installing the PowerShell modules listed in the powershell_modules
list. Use the win_psmodule module to accomplish this task. Because there is more
than one package, create a loop to iterate over the elements in the list.
Note
Because the variable is a list, you can pass it to the loop as is.
...output omitted...
- name: PowerShell modules are installed
win_psmodule:
name: "{{ item }}"
state: present
loop: "{{ powershell_modules }}"
tasks:
- name: Current repositories are unregistered
win_shell: Unregister-PSRepository "{{ item }}"
ignore_errors: true
loop:
- PowerShell Gallery
- PSGallery
DO417-RHAE2.8-en-1-20200106 401
Chapter 9 | Automating Windows Administration Tasks
changed_when: false
Note
The completed playbook is available in the solutions directory of the project.
3.3. In the commit message field, type the commit message Register PowerShell
repository and install modules, and then click commit above the message
field, or press Ctrl+Enter.
3.4. Click Synchronize Changes in the lower left corner of the editor. This action
synchronizes your changes with GitLab.
4. Access Ansible Tower, and then update the Run windows project template. Use the
powershell-modules.yml Ansible Playbook.
4.1. From workstation, double-click Ansible Tower to access the web console.
Log in to Ansible Tower using admin as the user name and RedHat123@! as the
password.
4.2. Click Templates to access the list of templates, and then select Run windows
project to edit it.
4.3. Select powershell-modules.yml in the PLAYBOOK field. Leave the other values
as is and click SAVE.
402 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
4.5. Observe the output as Ansible Tower clears any existing repositories, registers the
repository that you have defined, and installs the two PowerShell modules.
5.1. Access the Remote Desktop Connection client available from the Start menu.
The client is accessible from the Windows Server applications list.
Access win1 using devops as the user name. Click Connect to initiate the
connection. Use a password of RedHat123@!, and then click OK.
When prompted, click Yes to accept the self-signed certificate.
DO417-RHAE2.8-en-1-20200106 403
Chapter 9 | Automating Windows Administration Tasks
5.2. Click Windows PowerShell from the Start menu to open a PowerShell console.
5.5. Repeat the preceding two steps to import the Get-PSGoodFirstIssue module, and
query the available options. Exit the RDP connection when finished.
404 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
6. Return to Visual Studio Code and open the IIS-ssl.yml Ansible Playbook. The playbook
has initial tasks that configure the IIS site.
The following steps describe the list of changes to make to the playbook in order to
configure an IIS website on win1.example.com with a self-generated SSL certificate.
6.1. Append a task that verifies whether the IIS site has an SSL binding on port 8888. In a
later step, you configure that port to serve the website over TLS.
The task uses the Get-IISSiteBinding cmdlet to retrieve the SSL binding of the
DO417-windows IIS site, and then saves the output to the iis_ssl_stat variable.
Because the task does not make any changes to the system, add the changed_when:
false statement.
...output omitted...
## DO NOT EDIT ABOVE THIS LINE ##
6.2. Add a task that checks the presence of an SSL certificate for win1.example.com.
Save the result in a variable and use the ignore_errors: true statement to ensure
that the play runs even if the certificate does not exist.
Because the command does not make any change to the system, add
changed_when: False.
...output omitted...
- name: SSL is queried
win_shell: dir cert:\localmachine\my\
ignore_errors: True
changed_when: False
register: ssl_status
6.3. If the preceding task does not return any matching value for a certificate, then add a
task that generates the SSL certificate.
The task invokes the New-SelfSignedCertificate cmdlet to generate a self-
signed certificate with a host name of win1.example.com; Ansible substitutes
inventory_hostname with the server host name.
DO417-RHAE2.8-en-1-20200106 405
Chapter 9 | Automating Windows Administration Tasks
...output omitted...
- name: SSL certificate is generated
win_shell: >
New-SelfSignedCertificate
-DnsName "{{ inventory_hostname }}"
-CertStoreLocation cert:\LocalMachine\My
-KeyExportPolicy Exportable
when: "'win1' not in ssl_status.stdout"
6.4. Add a block clause that instructs Ansible to configure IIS with an SSL certificate if the
SSL binding is absent. It performs the following tasks:
Add a when statement to instruct Ansible to run the block if the SSL binding is not
present.
...output omitted...
- name: IIS site is configured
block
...output omitted...
- name: IIS site is configured
block:
- name: Certificate thumbprint is retrieved
win_shell: >
(Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object
{$_.Subject -match "{{ inventory_hostname }}"}).Thumbprint;
register: cert_thumbprint
6.6. Add a second task in the block that configures the SSL binding of the DO417-
windows IIS site. Name the task SSL binding is added. This task reuses the
cert_thumbprint variable in the certificate_hash parameter. The trim filter
removes any line continuation.
...output omitted...
- name: SSL binding is added
win_iis_webbinding:
name: DO417-windows
protocol: https
port: 8888
ip: "*"
certificate_hash: "{{ cert_thumbprint.stdout | trim }}"
state: present
406 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
6.7. Finally, add a task named IIS site is restarted to restart the IIS site. It uses the
win_iis_website module to restart the site, and then defines a new entry for IIS.
...output omitted...
- name: IIS site is restarted
win_iis_website:
name: DO417-windows
state: started
The updated playbook displays as follows: Tasks that are already included in the playbook
are omitted from the output.
tasks:
...output omitted...
- name: IIS binding is retrieved
win_shell: Get-IISSiteBinding "DO417-windows"
changed_when: false
register: iis_ssl_stat
DO417-RHAE2.8-en-1-20200106 407
Chapter 9 | Automating Windows Administration Tasks
Note
The completed playbook is available in the solutions directory of the project.
9. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
10. Access Ansible Tower and update the Run windows project template. Select IIS-
ssl.yml as the Ansible Playbook for the job template.
10.1. From workstation, access Ansible Tower. Navigate to Templates from the side
menu to access the templates.
Click Run windows project to edit the job template.
408 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
10.3.Click LAUNCH to run the job. Ansible redirects you to the job output. The output
indicates that Ansible configures the IIS site, generates the SSL certificate, and
updates the IIS site.
11. From workstation, open a new Google Chrome tab and access https://
win1.example.com:8888. Click the Not secure button at the top to review the
certificate information This confirms that the site is properly running with a self-signed
security certificate.
12. Return to Visual Studio Code and open the scheduled-tasks.yml Ansible Playbook.
This playbook creates a scheduled task that runs a PowerShell script. The script iterates
over a list of two servers and attempts to reach them.
The following steps describe the list of changes to make to the playbook in order to
schedule a task in the Windows scheduler.
DO417-RHAE2.8-en-1-20200106 409
Chapter 9 | Automating Windows Administration Tasks
12.1. Define a ps_script variable in the vars section of the playbook. Give it a value of
pingHosts.ps1
12.2. Define the first task that uses the win_file module. The task creates the scripts
directory on the managed host.
tasks:
- name: Script directory is created
win_file:
path: C:\Scripts\
state: directory
12.3. Create a task that uses the win_copy module to transfer the PowerShell script to the
managed host in C:\Scripts. Reuse the ps_script variable for the src parameter.
Note
Make sure to use slashes and not backslashes Because the file is located on the
Ansible Tower host.
...output omitted...
- name: PowerShell script is transferred
win_copy:
src: "files/{{ ps_script }}"
dest: C:\Scripts\
12.4. Create a task that uses the win_scheduled_task module to create the scheduled
task. Use the following information:
• Give the task a description of Run a PowerShell script that uses ping
to reach servers in the environment.
• Invoke PowerShell in non-interactive mode, and use the -File option to pass the
pingHosts.ps1 PowerShell script as the argument.
• Define two triggers for the task: one that instructs the scheduled task to run when
the system starts, and one that instructs the task to run when the user logs in.
• Define a priority of 1.
410 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Note
Some values are already pre-filled to help with the completion of the task.
...output omitted...
- name: A scheduled task is created
win_scheduled_task:
name: QueryHosts
description: >
Run a PowerShell script that uses ping to reach a servers
in the environment
author: student@example.com
enabled: true
actions:
- path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
arguments: >
-ExecutionPolicy Unrestricted
'-NonInteractive -File C:\Scripts\{{ ps_script }}'
triggers:
- type: boot
- type: logon
priority: 1
state: present
12.5. Add a final task that uses the win_scheduled_task_stat module to retrieve some
information about that the scheduled task. The module dumps a JSON dictionary that
is accessible from the Ansible Tower job output. Give the name of the scheduled task
to the name parameter.
Use a changed_when: False statement Because the task does not make any
change to the system.
...output omitted...
- name: Status of the task is retrieved
win_scheduled_task_stat:
name: QueryHosts
changed_when: False
tasks:
- name: Script directory is created
win_file:
path: C:\Scripts\
state: directory
DO417-RHAE2.8-en-1-20200106 411
Chapter 9 | Automating Windows Administration Tasks
Note
The completed playbook is available in the solutions folder of the project.
13. Save and commit your changes, then synchronize the repository.
13.2. Click the + symbol for the scheduled-tasks.yml file to stage your changes.
13.3. In the commit message field, type a commit message of Configure a scheduled
task, and then click commit or press Ctrl+Enter.
13.4. Click Synchronize Changes in the lower left corner of the editor. This action
synchronizes your changes with GitLab.
14. Access Ansible Tower and update the Run windows project template. Use the
scheduled-tasks.yml Ansible Playbook.
14.1. From workstation, access Ansible Tower. Navigate to Templates to access the
templates.
Click Run windows project to edit the job template.
412 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
14.3.Click LAUNCH to run the job. Ansible redirects you to the job output. The output
indicates that Ansible installs the PowerShell script to the scripts directory and
creates a new scheduled task.
14.4.From the job output, click the ok: [win1.example.com] entry for the Status of
the task is retrieved task to read the information about the scheduled task.
Review the JSON dictionary that contains information about the scheduled task run
level, task arguments, and other information about the task.
DO417-RHAE2.8-en-1-20200106 413
Chapter 9 | Automating Windows Administration Tasks
15. From workstation, open the remote desktop client to connect to win1.example.com.
Launch the task scheduler to confirm the present of the scheduled task.
15.1. Access the Remote Desktop Connection client, available from the Start menu.
The client is accessible from the Windows Server applications list.
Access win1 using devops as the user name. Click Connect to initiate the
connection. Use a password of RedHat123@!, and then click OK.
When prompted, click Yes to accept the self-signed certificate.
15.2. Click the magnifying glass icon and type Task Scheduler to access the task
scheduler.
15.3. From the Active Tasks panel, double-click the QueryHosts entry.
Note
If you do not see the task, navigate to Action → Refresh to update the list of
scheduled tasks.
15.4. Click through the tabs to review the various options that the task uses. Exit the RDP
connection when finished.
414 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
DO417-RHAE2.8-en-1-20200106 415
Chapter 9 | Automating Windows Administration Tasks
Objectives
After completing this section, you should be able to automate configuration of storage devices on
managed hosts.
win_defrag
When a volume has a lot of activity, the files can become fragmented, meaning that they are
spread over different areas of the file system. Fragmented files can have slower read/write
speeds due to the increase in the number of seeks required. A seek is when the drive moves
the head to the start of the data to be read. When a file is fragmented, the drive must seek
each chunk before reading or writing.
After a file system has been defragmented, all the chunks of each file are contiguous, meaning
that they are next to each other on the disk; this results in fewer seeks. File systems on solid
state drives do not require defragmenting, as there are no physical heads to move.
Using the win_defrag module, administrators can decide exactly when defragmentation
should occur, as disk performance will be impacted during the operation. The module
has several useful parameters, such as parallel, which enables all drives to be
defragmented at the same time; exclude_volumes is used to exclude a drive from the
defragmentation operation. You can also specify priority to reduce the performance hit,
and freespace_consolidation, which may be useful when a drive needs to be reduced.
win_disk_facts
Before enacting changes to disk partitions and file systems, you must ensure that the storage
configuration on the managed host is suitable. This module retrieves the storage system
information from the managed host as facts, which are then included in the ansible_facts
variable under the disks array.
416 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
The output includes a wide variety of information, including bus type, manufacturer, whether
the partition is MBR or GPT style, as well as physical and virtual disk attributes. Testing fields
in the ansible_facts['disks'] array enables running tasks conditionally.
win_disk_image
Provides the ability to mount a disk image, which can also be classified as a storage task.
Images in ISO, VHD, or VHDX format are supported, allowing operations such as software
installation from an ISO image, or manipulation of virtual machine disks.
win_format
Formats a new or existing Windows volume, with a choice of FAT, FAT32, EXFAT, NTFS, or
ReFS file systems. Specify only one of the drive_letter, path, or label parameters when
using this module. Other available parameters include compress to enable compression, and
full to perform a full format.
win_mapped_drive
Supports mapping Windows shares to drive letters.
Note
The username and password parameters of this module are only useful for testing
a mapped drive connection; you must use the win_credential module to store
credentials persistently.
win_partition
Defines MBR style partitions of type FAT12, FAT16, extended, huge, IFS, or FAT32. GPT style
partitions can be any of the following: system_partition, microsoft_reserved, basic_data,
or microsoft_recovery types. Other parameters include active to make an MBR partition
bootable, and hidden to prevent the OS from seeing the partition.
win_share
Defines shared folders and the access permitted; this module is a partner to
win_mapped_drive, Parameters for access control include change, deny, full, list, and
read.
The following example shows the win_defrag module in use. The system drive is excluded, and
all other drives are defragmented in parallel, but with a low priority.
This example demonstrates using the win_disk_facts module to extract information for a
specific disk.
---
- name: System disk firmware versions are printed
hosts: demo.example.com
tasks:
- name: Populate disk facts
win_disk_facts:
DO417-RHAE2.8-en-1-20200106 417
Chapter 9 | Automating Windows Administration Tasks
The following example demonstrates the win_disk_image module mounting an ISO. The debug
module is used to display the drive letter on which the ISO is mounted.
The following example uses the win_format module to perform a full format of drive E:.
The following example demonstrates using the win_mapped_drive module to map a drive with
credentials persistently.
418 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Note
Note the use of win_credential to persistently store the service account
credentials. Also, notice the use of *_become variables that enable access to the
user's credential store.
The following example uses the win_share module to share a company forms folder.
Common use cases will likely require several of these modules working together. For
example, using win_disk_facts to determine the exact storage configuration, followed by
win_partition and win_format to create a formatted drive. Another example is using
win_share to create a shared folder, followed by win_credential and win_mapped_drive to
persistently map a drive letter to the share on client machines.
References
Windows modules — Ansible documentation
https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html
DO417-RHAE2.8-en-1-20200106 419
Chapter 9 | Automating Windows Administration Tasks
Guided Exercise
Outcomes
You should be able to create and format new partitions, and create Windows shares.
Open your RDP client and connect to workstation using example.com as the domain,
student as the user name and RedHat123@! as the password.
You can find the connection information to your systems in the email that you received.
1. Launch the Visual Studio Code editor. If you have not previously cloned the windows
repository, clone it to your workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
Note
The Second disk extracted as standalone fact task uses an advanced
filter method to obtain the facts for the second disk. This method will not be
discussed in this course, but is required for this exercise. For further information,
please see the References section in the Configuring and Managing Storage section.
3.1. Complete the Second disk size printed task to display the value of the
second_disk[0]['size'] variable.
420 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
3.2. Modify the Partition is created on second disk task to set the following
values:
• Disk number 1
• Drive F
• Sized at 1 GiB
3.3. Complete the New partition is formatted task to create an NTFS volume
named data on drive F:. The task will run conditionally, depending on whether the
previous task resulted in changed resolving to true.
3.4. Complete the Share folder is created task to create the F:\shares\forms
folder.
3.5. Complete the Content added to forms folder task to create the F:\shares
\forms\leave_requests.txt file. This task uses the win_copy module.
3.6. Complete the task named Forms folder is shared to share the F:\shares
\forms folder. Administrators require full access, Domain Users require read access,
and listing must be enabled. This task uses the win_copy module.
DO417-RHAE2.8-en-1-20200106 421
Chapter 9 | Automating Windows Administration Tasks
---
- name: Configure local storage
hosts: win1.example.com
tasks:
- name: Disk facts are populated
win_disk_facts:
422 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
content: 'All leave requests are now handled by our Intranet site:
https://intranet.example.com/forms'
dest: F:\shares\forms\leave_requests.txt
4. Save and commit the changes to your local Git repository, and then push them to the
remote repository.
4.2. Navigate to the Source Control pane, and then click + for the storage.yml file to
stage the changes.
4.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
4.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
6. Test your playbook using the Run windows project job template.
6.4. Click SAVE to update the template, and then click LAUNCH to run the job.
7. After all tasks complete, verify that the status in the DETAILS pane shows Successful.
If the job is not successful, compare your playbook with the solutions/storage.sol
solution file in the windows Git repository.
8. Browse to the new share to verify that the playbook was successful.
8.1. Click Search Windows, search for run, and then open the Run window.
8.3. The forms share is displayed. Open the share, and then open the
leave_requests.txt file to verify that the content matches the playbook.
DO417-RHAE2.8-en-1-20200106 423
Chapter 9 | Automating Windows Administration Tasks
9. Switch back to the Ansible Tower web UI. Edit the Run windows project template to
revert your changes and use the revert_storage.yml playbook, and then launch a job.
9.4. Click SAVE to update the template, and then click LAUNCH to run the job.
424 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Lab
Outcomes
You should be able to create and format a disk partition and map it to a drive letter, schedule
a task to defragment the file system on that device, add a PowerShell Gallery repository, and
install a PowerShell module on managed hosts using Ansible.
Open your RDP client and connect to workstation using example.com as the domain,
student as the user name and RedHat123@! as the password.
Find the connection information to your systems in the email that you received.
1. Launch the Visual Studio Code editor. If you did not previously clone the windows repository,
clone it to your workstation instance.
2. Select File → Open Folder, and then select the C:\Users\student\Documents
\windows folder to display the contents.
3. Open the review.yml playbook, and then complete the tasks so that they result in the
following outcomes.
• Create and format a 2 GiB NTFS partition on the second disk as the S: drive.
• Schedule a task named DefragDBDrive to defragment the new drive every Sunday.
• Add the PowerShell Gallery repository.
• Install the SqlServer PowerShell module.
4. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
5. From workstation, access your Ansible Tower instance available at http://
tower.example.com. Connect as the student user and RedHat123@! as the password.
6. To test your playbook, modify the Run windows project job template to use the
review.yml playbook, and then launch a job.
7. After all tasks complete, verify that the status in the DETAILS pane shows Successful. If
the job is not successful, compare your playbook with the solutions/review.sol solution
file in the windows Git repository.
DO417-RHAE2.8-en-1-20200106 425
Chapter 9 | Automating Windows Administration Tasks
Note
If you did not exit the PowerShell console in the previous step then running this
playbook will fail.
426 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Solution
Outcomes
You should be able to create and format a disk partition and map it to a drive letter, schedule
a task to defragment the file system on that device, add a PowerShell Gallery repository, and
install a PowerShell module on managed hosts using Ansible.
Open your RDP client and connect to workstation using example.com as the domain,
student as the user name and RedHat123@! as the password.
Find the connection information to your systems in the email that you received.
1. Launch the Visual Studio Code editor. If you did not previously clone the windows repository,
clone it to your workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
• Create and format a 2 GiB NTFS partition on the second disk as the S: drive.
• Schedule a task named DefragDBDrive to defragment the new drive every Sunday.
• Add the PowerShell Gallery repository.
• Install the SqlServer PowerShell module.
3.1. Modify the task named Partition is created on second disk to set the
following values.
DO417-RHAE2.8-en-1-20200106 427
Chapter 9 | Automating Windows Administration Tasks
• Disk number 1
• Drive letter S
• Sized at 2 GiB
3.2. Complete the New partition is formatted task to create an NTFS volume named
db on the S: drive. This task will run conditionally depending on whether the previous
task resulted in changed resolving to true.
3.3. Complete the task that creates the scheduled defragmentation task.
3.4. Complete the task that registers a new PowerShell repository. Use the
powershell_gallery_endpoint variable as the module source parameter.
...output omitted...
- name: Current repositories are unregistered
win_shell: Unregister-PSRepository "{{ item }}"
ignore_errors: true
loop:
428 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
- PowerShell Gallery
- PSGallery
3.5. Complete the task that queries the PowerShell Gallery repository. This task captures the
output in the repo_status variable, and then fails if the command does not return 0.
The changed_when: false statement indicates to Ansible to return a status of ok,
because the task does not make any changes to the system.
3.6. Complete the task to install the PowerShell modules listed in the
powershell_modules list. To complete this task, use the win_psmodule module.
---
- name: Configure database host
hosts: win1.example.com
vars:
db_drive_letter: S
powershell_gallery_endpoint: https://www.powershellgallery.com/api/v2/
powershell_modules:
- SqlServer
tasks:
- name: Disk facts are populated
win_disk_facts:
DO417-RHAE2.8-en-1-20200106 429
Chapter 9 | Automating Windows Administration Tasks
win_partition:
disk_number: 1
drive_letter: "{{ db_drive_letter }}"
partition_size: 2 GiB
register: partition_task
430 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
win_psmodule:
name: "{{ item }}"
state: present
loop: "{{ powershell_modules }}"
4. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
4.2. Navigate to the Source Control pane, and then click + to stage the changes to the
time.yml file.
4.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
4.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
6.4. Click SAVE to update the template, and then click LAUNCH to run the job.
7. After all tasks complete, verify that the status in the DETAILS pane shows Successful. If
the job is not successful, compare your playbook with the solutions/review.sol solution
file in the windows Git repository.
8. Inspect win1 to verify the success of the playbook.
8.2. Launch Explorer, and then verify that the S: drive exists.
8.3. Open the Task Scheduler, click Task Scheduler Library, and then verify that the
DefragDBDrive task is listed with the correct settings.
DO417-RHAE2.8-en-1-20200106 431
Chapter 9 | Automating Windows Administration Tasks
8.4. Launch a PowerShell console, import the SqlServer module, and then display its
commands. Exit the PowerShell console when finished.
PS C:\Users\devops>
9. Switch back to the Ansible Tower web UI. To revert your changes, edit the Run windows
project template to use the revert_review.yml playbook, and then launch a job.
Note
If you did not exit the PowerShell console in the previous step then running this
playbook will fail.
9.4. Click SAVE to update the template, and then click LAUNCH to run the job.
432 DO417-RHAE2.8-en-1-20200106
Chapter 9 | Automating Windows Administration Tasks
Summary
In this chapter, you learned:
• There are several modules for running commands on Windows, such as the win_command,
win_shell, and win_psexec modules.
• The win_psexec module is useful when Ansible does not have direct access to the target
hosts. To manage hosts on an isolated network, use the win_psexec module on a jump host.
• For more complex commands, the script module allows you to transfer and execute a script.
• Ansible provides the win_scheduled_task module to create and manage scheduled tasks on
managed nodes.
• A wide variety of Ansible modules are available that can be used to get information about
storage devices, to partition, format, and defragment disks, and to map devices to drive letters.
DO417-RHAE2.8-en-1-20200106 433
434 DO417-RHAE2.8-en-1-20200106
Chapter 10
DO417-RHAE2.8-en-1-20200106 435
Chapter 10 | Managing Large Projects
Objectives
After completing this section you should be able to manage large playbooks by importing or
including other playbooks or tasks from external files, either unconditionally or based on a
conditional test.
When you include content, it is a dynamic operation. Ansible processes included content during the
run of the playbook.
When you import content, it is a static operation. Ansible preprocesses imported content when the
playbook is initially parsed before the run starts.
Importing Playbooks
The import_playbook directive allows you to import external files containing lists of plays into
a playbook. In other words, you can have a master playbook that imports one or more additional
playbooks.
Because the content being imported is a complete playbook, you can only use the
import_playbook feature at the top-level of a playbook, but not inside a play. If you import
multiple playbooks, then they are imported and run in order.
The following example shows shows how a master playbook imports two additional playbooks:
You can also interleave plays in your master playbook with imported playbooks. In the following
example, the Play to install IIS Web Server play runs first, followed by the plays of the
imported deploy-site.yml Ansible Playbook.
436 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
The following is an example of importing tasks from the windows_tasks.yml task file into a play:
tasks:
- name: Importing external task file
import_tasks: windows_tasks.yml
When you import a task file, the tasks in that file are directly inserted when the playbook is parsed.
Because import_tasks statically imports the tasks when the playbook is parsed, there are some
constraints:
• When using the import_tasks feature, conditional statements set on the import, such as
when, are applied to each of the tasks that are imported.
DO417-RHAE2.8-en-1-20200106 437
Chapter 10 | Managing Large Projects
• If you use a variable to specify the name of the file to import, then you cannot use a host or
group inventory variable.
The following is an example of including tasks from the windows_tasks.yml task file into a play:
The include_tasks feature does not process content in the playbook until the play is running
and that part of the play is reached. The order in which playbook content is processed impacts how
the include tasks feature works:
• You can use loops with the include_tasks statement. The included tasks or role are executed
once for each item in the loop.
• When using the include_tasks feature, conditional statements set on the include, such as
when, determine whether the tasks are included in the play.
• You cannot use a notify statement to trigger a handler name that is in an included task file.
You can trigger a handler in the main playbook that includes an entire task file, in which case all
tasks in the included file run.
Note
You can find a more detailed discussion of the differences in behavior between
import_tasks and include_tasks when conditionals are used in the
Conditionals chapter in the Ansible User Guide at https://docs.ansible.com/ansible/
latest/user_guide/playbooks_conditionals.html#applying-when-to-roles-imports-
and-includes.
• If new servers require complete configuration, then administrators could create various sets
of tasks for creating users, installing features, configuring services, configuring privileges,
setting up access to a shared file system, hardening the servers, installing security updates, and
installing a monitoring agent. Each of these sets of tasks could be managed through a separate,
self-contained task file.
• If developers collectively manage servers, the system administrators, and the database
administrators, then every organization can write their own task file, which can then be reviewed
and integrated by the system manager.
• If a server requires a particular configuration, then it can be integrated as a set of tasks that
execute based on a conditional. In other words, tasks are included and executed only if specific
criteria are met.
438 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
• If a group of servers must run a particular task or set of tasks, then the tasks might only run on a
server if it is part of a specific host group.
For example, the following task installs the feature needed for a web service, and then starts the
necessary service.
If you parameterize the feature and service elements as shown in the following example, then you
can also use the task file for the installation and administration of other features and their services,
rather than exclusively for a web service.
Subsequently, when incorporating the task file into a playbook, define the variables to use for the
task execution as follows:
DO417-RHAE2.8-en-1-20200106 439
Chapter 10 | Managing Large Projects
...output omitted...
tasks:
- name: Import task file and set variables
import_tasks: task.yml
vars:
package: Web-Server
svc: W3Svc
Ansible makes the passed variables available to the tasks imported from the external file.
You can use the same technique to make play files more reusable. When incorporating a play file
into a playbook, pass the variables to use for the play execution as follows:
...output omitted...
- name: Import play file and set the variable
import_playbook: play.yml
vars:
package: Web-Server
Important
Earlier versions of Ansible used an include feature to include both playbooks
and task files, depending on the context. This functionality is still available, but
considered deprecated for a number of reasons.
Prior to Ansible 2.0, include operated like a static import. In Ansible 2.0 it was
changed to operate dynamically, but this created some limitations. In Ansible 2.1 it
became possible for include to be dynamic or static depending on task settings,
which was confusing and error-prone. There were also issues with ensuring that
include worked correctly in all contexts.
Thus, include was replaced in Ansible 2.4 with new directives such as
include_tasks, import_tasks, and import_playbook. You might find
examples of include in older playbooks, but you should avoid using it in new ones.
References
— Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/index.html
440 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Guided Exercise
Outcomes
You should be able to include and import playbooks and tasks.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in the Interacting with Users and
Domains chapter. You must complete the exercises in this chapter before
starting this exercise.
1. Launch the Visual Studio Code editor, and then clone the projects repository to your
workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2. Review and fix the the contents of the three files in the tasks subdirectory. After making
the changes, commit and push the changes to the master branch.
2.1. Go to the tasks directory, located at the top-level. Select the environment.yml
file, this file contains a task for package installation. Change the file as follows:
DO417-RHAE2.8-en-1-20200106 441
Chapter 10 | Managing Large Projects
---
- name: IIS and .Net 4.5 are installed
win_feature:
name: "{{ iis_package_names }}"
include_management_tools: True
state: present
2.2. Click Save. Note the status icons in the lower left corner of the editor. There is now an
asterisk next to Master, indicating that changes have been made.
2.3. In the same subdirectory, select the firewall.yml file, which contains a task for
adding a new rule to the firewall. Change the content of the file as follows:
---
- name: Firewall rule is enabled
win_firewall_rule:
name: HTTP
localport: "{{ iis_site_port }}"
action: allow
direction: in
protocol: tcp
state: present
enabled: yes
2.4. In the same subdirectory, select the site.yml file. This file contains tasks for creating
the IIS site and directories, and to copy the index.html file into the proper directory.
Review the contents of the file:
---
- name: Logs directory is created
win_file:
path: C:\sites\logs
state: directory
442 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
application_pool: DefaultAppPool
physical_path: "{{ iis_site_path }}"
parameters: logfile.directory:C:\sites\logs
2.5. Change to the Source Control view, and then click + next to all the files that you have
modified to stage the changes.
2.6. Enter a commit message, and then press Ctrl+Enter to commit the changes.
2.7. The status icon in the lower left corner of the window indicates that there are changes
to push to the remote repository. Click Synchronize Changes to send your changes to
the remote repository, and to receive any new changes from the remote repository.
3. Review and fix the the content of the test.yml file in the plays subdirectory. After
making the changes, commit and push the changes to the master branch.
3.1. Go to the plays directory, located at the top-level. Select the test.yml file, which
contains a play that tests connections to a web service. Change the file as follows:
---
- name: Test web service
hosts: win1.example.com
gather_facts: false
tasks:
3.2. Click Save. Note the status icons in the lower left corner. There is an asterisk next to
Master to indicate that changes were made.
3.3. Switch to the Source Control view, and then click + for the test.yml file to stage
the changes.
3.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
3.5. The status icon in the lower left indicates that there is a change to the remote
repository. Click Synchronize Changes to send the change to the remote repository,
and to receive any new changes from the remote repository.
4. Review and fix the the content of the deploy.yml file in the top-level directory. After
making the changes, commit and push the changes to the master branch.
4.1. Navigate to the top-level directory. Select the deploy.yml file, which contains a
set of tasks that include and import tasks and plays from different files located in this
project directory. Change the file as follows:
---
- name: Configure web server
hosts: all
gather_facts: false
DO417-RHAE2.8-en-1-20200106 443
Chapter 10 | Managing Large Projects
tasks:
- name: Include the environment task file and set the variables
include_tasks: tasks/environment.yml
vars:
iis_package_names:
- Web-Server
- NET-Framework-Core
- Web-Asp-Net45
- name: Import the site task file and set the variables
import_tasks: tasks/site.yml
vars:
iis_site_path: C:\sites\projects
iis_site_name: "DO417-projects"
iis_site_port: 8080
- name: Import the firewall task file and set the variable
import_tasks: tasks/firewall.yml
vars:
iis_site_port: 8080
4.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master,
which indicates that changes have been made.
4.3. Change to the Source Control view, and then click + for the deploy.yml file to
stage the changes.
4.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
4.5. The status icon in the lower left corner indicates that there is a change to push to
the remote repository. Click Synchronize Changes to send the change to the remote
repository, and to receive any new changes from the remote repository.
5. In previous activities, you created IIS websites and HTTP firewall rules. Run the Run
projects project job remove-iis.yml playbook to remove the websites and firewall
rules.
5.2. From the list of templates, select the Run projects project template.
5.4. If cleared, select the PROMPT ON LAUNCH check box for the LIMIT option.
5.5. If selected, clear the PROMPT ON LAUNCH check box for the CREDENTIAL and
INVENTORY options.
444 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
5.8. Click SAVE to update the template, and then click LAUNCH to run the job.
5.11. Verify that the status of the job in the DETAILS pane displays Successful.
6. Run the Run projects project job to test your playbook with the import and include
tasks.
6.2. From the list of templates, select the Run projects project template.
6.4. Click SAVE to update the template, and then click LAUNCH to run the job.
6.7. Verify that the status of the job in the DETAILS pane displays Successful.
7. The last play executes a test using the managed host. If the job status is successful, then
the web page is accessible. Optionally, you can open Chrome from workstation and
access http://win1.example.com:8080. The new web page will be available.
DO417-RHAE2.8-en-1-20200106 445
Chapter 10 | Managing Large Projects
Creating Roles
Objectives
After completing this section, you should be able to create a role to allow code reuse by different
Ansible projects, and run it as part of a play in a playbook.
However, that play might be long and complex, with many included or imported files, and with
tasks and handlers to manage various situations. Copying all that code into another playbook
might not be trivial work.
Ansible roles make it easier to reuse Ansible code generically. You can package, in a standardized
directory structure, all the tasks, variables, files, templates, and other resources needed to
provision infrastructure or deploy applications. Copy that role from project to project by copying
the directory. Then, call that role from a play to execute it.
A well-written role allows you to pass variables to the role from the playbook that adjust its
behavior, setting all the site-specific hostnames, IP addresses, user names, secrets, and other
specific details. For example, a role to deploy a database server might support variables that
set the host name, database admin user and password, and other parameters that require
customization for your installation. The author of the role can also ensure that reasonable default
values are set for those variables if you choose not to set them in the play.
• You can write roles in a way that they define the essential elements of a system type: web server,
database server, Git repository, and more.
In addition to writing, using, reusing, and sharing your own roles, you can get numerous community
supported roles from the Ansible Galaxy website. Later in this chapter, you will learn more about
these roles.
446 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Each role has its own directory with a standardized directory structure. The top-level directory
defines the name of the role itself. Files are organized into subdirectories that are named
according to the purpose of each file in the role, such as tasks and handlers. The files and
templates subdirectories contain files referenced by tasks in other YAML files.
win_package.example
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
DO417-RHAE2.8-en-1-20200106 447
Chapter 10 | Managing Large Projects
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
Directory Function
defaults The main.yml file in this directory contains the default values of
role variables that can be overwritten when the role is used. These
variables have low precedence and are intended to be changed and
customized in plays.
files This directory contains static files that are referenced by role tasks.
handlers The main.yml file in this directory contains the handler definitions for
the role.
tasks The main.yml file in this directory contains task definitions for the
role.
templates This directory contains Jinja2 templates that are referenced by role
tasks.
tests This directory can contain an inventory and test.yml playbook that
can be used to test the role.
vars The main.yml file in this directory defines the variable values for the
role. Often these variables are used for internal purposes within the
role. These variables have high precedence, and are not intended to be
changed when used in a playbook.
Not every role will have all of these directories. If a subdirectory exists but is empty, it is ignored. If
a role does not use a feature, the subdirectory can be omitted altogether.
Typically, a README.md file in the root of the role directory provides a basic human-readable
description of the role, documentation, and examples of how to use it, and any non-Ansible
requirements that must be met.
448 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
For example, if you are converting a play into a role, copy all of the tasks from the play into the
tasks\main.yml file.
The following tasks\main.yml file makes sure the Web-Server feature is installed, that
the W3Svc service is running, and that the index.html file is templated into place using the
win_template module.
Because the win_template module is called by a task in a role, the index.j2 template is
retrieved from the templates subdirectory:
---
# tasks file for win_package.example role
The following displays the contents of the index.j2 template of the role, located in the
templates directory. It references Ansible facts and a system_owner variable.
Hello World!
Welcome to {{ ansible_facts['hostname'] }}.
The role defines a default value for the system_owner variable. Set this value in the defaults
\main.yml file in the directory structure for the role. The following defaults\main.yml file
sets the system_owner variable to user@host.example.com . This is the email address that is
written in the index.html file of managed hosts to which this role is applied.
---
system_owner: user@host.example.com
• Maintain each role in its own version control repository. Ansible works well with Git-based
repositories.
• Do not store in the role repository sensitive information, such as passwords or SSH keys.
Parameterize sensitive values as variables with default values that are not sensitive. Playbooks
DO417-RHAE2.8-en-1-20200106 449
Chapter 10 | Managing Large Projects
that use the role are responsible for defining sensitive variables through Ansible Vault variable
files, Ansible Tower surveys, the "prompt on launch" feature when started with an Ansible Tower
job template, or other appropriate means.
• Create and maintain README.md and meta\main.yml files to document what your role is for,
who wrote it, and how to use it.
• Keep your role focused on a specific purpose or function. Instead of making one role do many
things, write more than one role.
• Reuse and refactor roles often. Resist creating new roles for edge configurations. If an existing
role accomplishes a majority of the required configuration, refactor the existing role to integrate
the new configuration scenario. Use integration and regression testing techniques to ensure that
the role provides the required new functionality, and also does not cause problems for existing
playbooks.
Default variables allow setting default values for variables that can be used in a play to configure
the role or customize its behavior. To define these variables, create a defaults\main.yml file
with key: value pairs in the role directory hierarchy. Default variables have the lowest precedence
of any variables available. They can be easily overridden by any other variable, including inventory
variables. These variables provide the person writing a play that uses the role with a way to
customize or control exactly how that role will function. They also provide information to the role
that it needs to configure or deploy something properly.
Important
Roles should not have site-specific data in them. They should never contain any
secrets, like passwords or private keys.
Secrets should be provided to the role through other means. This is one reason you
might want to set role variables when calling a role. Role variables set in the play
could provide the secret, or point to an Ansible Vault-encrypted file containing the
secret.
450 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
---
- name: use win_package.example role in play
hosts: winhost1
roles:
- win_package.example
When the playbook runs, you can identify the tasks resulting from a role by the role name
preceding the task name.
For example, the output of the play above might look like this:
The value of any variable defined in the defaults directory for a role will be overwritten if that same
variable is defined:
The following example demonstrates using the win_package.example role with a different
value for the system_owner role variable. The value specified, someone@host.example.com,
replaces the variable reference when the role is applied to a managed host.
DO417-RHAE2.8-en-1-20200106 451
Chapter 10 | Managing Large Projects
---
- name: use win_package.example role in play with a variable setting
hosts: winhost1
vars:
system_owner: someone@host.example.com
roles:
- win_package.example
When defined in this way, the value of system_owner declared in vars overrides the value
of the variable of the same name defined in the defaults directory. However, the value of
system_owner does not override any declaration in the vars directory.
The following example shows how to use the win_package.example role with a different value
for the system_owner role variable. The value specified, someone@host.example.com,
replaces the variable reference even though it is defined in the vars or defaults directory for
the role.
---
- name: use windows role in playbook
hosts: winhost1
roles:
- win_package.example
system_owner: someone@host.example.com
Important
Variable precedence can be confusing when working with role variables in a play.
• Almost any other variable will override default variables for a role, including
inventory variables, play vars, inline role parameters, and more.
• Fewer variables can override role variables defined in a the vars directory. Facts,
variables loaded with include_vars, registered variables, and role parameters
are some variables that can take precedence. Inventory variables and play vars
cannot. This is important because it helps keep your play from accidentally
changing the internal functioning of the role.
• However, variables declared inline as role parameters, like the last of the
preceding examples, have very high precedence. They can override role variables
defined in the vars directory. If a role parameter has the same name as a variable
set in vars for a play, in vars for a role, or in an inventory or playbook variable,
the role parameter overrides the other variables.
---
- hosts: remote.example.com
roles:
- role1
- role2
452 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
The following example sets values for two role variables of role2, var1, and var2. Any
defaults and vars variables are overridden when role2 is used.
---
- hosts: remote.example.com
roles:
- role1
- role: role2
vars:
var1: val1
var2: val2
---
- hosts: remote.example.com
roles:
- role1
- { role: role2, vars: { var1: val1, var2: val2 } }
There are situations where this can be harder to read, even though it is more compact.
Important
Role variables set inline (role parameters), as in the preceding examples, have very
high precedence. They override most other variables.
Be very careful not to reuse the names of any role variables that you set inline
anywhere else in your play, since the values of the role variables override inventory
variables and any play vars.
But, when a role is added to a play using the roles directive, the tasks from that role are added to
the beginning of the tasks list. If a second role is included in a play, the tasks list is added after the
tasks list from the first role. The order of the tasks and roles directives do not matter. However,
for clarity it helps if you put the roles section first in the play.
---
- hosts: remote.example.com
roles:
- role: role1
- role: role2
tasks:
- task1
Role handlers are added to plays in the same manner that role tasks are added to plays. Each play
defines a handlers list. Role handlers are added to the handlers list first, followed by any handlers
defined in the handlers section of the play.
DO417-RHAE2.8-en-1-20200106 453
Chapter 10 | Managing Large Projects
In certain scenarios, it may be necessary to execute some play tasks before the roles. To support
such scenarios, plays can be configured with a pre_tasks section. Any task listed in this section
executes before any roles are executed. If any of these tasks notify a handler, then those handler
tasks execute before the roles or normal tasks.
Plays also support a post_tasks keyword. These tasks execute after the normal tasks in the play,
and any handlers they notify run.
The following play demonstrates pre_tasks, roles, tasks, post_tasks and handlers. In a
production scenario, it is unusual for a play to contain all of these sections. Although most tasks in
this example are unnamed to save space, omitting task names is not recommended when working
outside of this test environment.
In the above example, a debug task executes in each section to notify the my handler handler.
The my handler task is executed three times:
• After all role tasks and tasks from the tasks section execute.
The following playbook demonstrates how a role can be included using a task with the
include_role module.
454 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Note
The include_role module was added in Ansible 2.3, and the import_role
module in Ansible 2.4.
References
Ansible User Guide — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/index.html
DO417-RHAE2.8-en-1-20200106 455
Chapter 10 | Managing Large Projects
Guided Exercise
Creating Roles
In this exercise, you will create an Ansible role, add it to a playbook, and run the playbook to
test the new role.
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
All Chapter 8, Interacting with Users and Domains guided exercises must be completed prior
to starting this exercise, due to changes in inventory and authentication.
1. Open the Visual Studio Code editor and clone the projects repository to your
workstation.
1.1. From workstation, double-click the desktop icon to open the Visual Studio Code
editor. Alternatively, click Search Windows, search for code, and then open Visual
Studio Code.
1.4. When a prompt to open the project displays in the lower right corner of the editor, click
Open.
2. Open the roles-example.yml playbook file and review its contents. The playbook
declares a few variables to insert strings into a template and a Boolean debug_tools:
True declaration. The tasks ensure that the IIS web server is started, and then deploy static
files and a Jinja2 template. The debug_tools variable is used as a condition for installing
the HTTP Tracing IIS feature.
456 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
3. Move all but the first and last tasks in the roles-example.yml file to the roles\web
\tasks\main.yml web role playbook file.
3.1. In the roles-example.yml file, select the four tasks starting with the task named
IIS Web Server started.
3.2. Select Edit → Cut or press Ctrl+X to paste the text into the empty roles\web
\tasks\main.yml playbook.
3.3. Navigate to Edit → Paste or press Ctrl+V to paste the text into the empty roles
\web\tasks\main.yml playbook.
3.4. Select all of the text and press Shift+Tab twice to remove the task indentation.
3.5. Because roles follow a predetermined directory structure, Ansible finds templates
and files in their respective directories. Remove the templates/ and files/
subdirectories from the win_template and win_copy src parameters.
---
- name: IIS Web Server started
win_feature:
name: Web-Server
state: present
4.1. Remove the deployed_by: Ansible line from the roles-example.yml playbook.
DO417-RHAE2.8-en-1-20200106 457
Chapter 10 | Managing Large Projects
---
deployed_by: Ansible
5.1. Remove the site_title: Default Site and site_subtitle: Example Web
Site lines from the roles-example.yml playbook.
---
site_title: Default Site
site_subtitle: Welcome!
debug_tools: False
6. Click the templates\index.html.j2 file in the PROJECTS pane, and then drag it into
the roles\web\templates directory.
7. Click the files\info.html file in the PROJECTS pane, and then drag it into the roles
\web\files directory.
---
- name: Deploy website
hosts: all
vars:
debug_tools: True
pre_tasks:
- debug:
msg: Installing with debug tools enabled.
when: debug_tools
roles:
- role: web
site_title: Example Web Site
post_tasks:
- name: Custom page is added
win_copy:
content: "Hello!"
dest: C:\Inetpub\wwwroot\example.html
458 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Move the debug message task to a pre_task, so that it will run before the role tasks.
Add a list of roles with a single item role: web invoking the web role.
Override the default site_title to insert a custom heading on the web site.
Move the final Custom page is added task to a post_task that Ansible invokes
after the role tasks have completed.
9. Commit the changes to your local Git repository, and then push them to the remote
repository.
9.1. Navigate to the Source Control pane, and then stage the changes.
9.2. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
9.3. Locate the status icons in the lower left corner of the editor, and notice that there is a
change to be pushed to the remote Git repository. Click the Synchronize Changes to
push your changes.
10. From workstation, access your Red Hat Ansible Tower instance available at http://
tower.example.com. Connect as the student user with the RedHat123@! password.
11. Run your playbook using the Run projects project job template.
11.3. Click the magnifying glass icon in the INVENTORY input field. Click Dynamic
inventory, and then click SELECT.
11.4. Click the magnifying glass icon in the CREDENTIAL input field. Click AD
Administrator, and then click SELECT.
11.7. Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 459
Chapter 10 | Managing Large Projects
11.9. After all tasks have completed, verify that the status in the DETAILS pane displays
Successful.
12. In Chrome, open a new tab and navigate to http://win1.example.com/. Click the "info
page" link to verify the deployment of the static info.html.
460 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
14. Run the cleanup-roles.yml playbook from the Run projects project job template
to clean up your work.
14.5. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is
selected.
14.7. Click SAVE to update the template, and then click LAUNCH to run the job.
DO417-RHAE2.8-en-1-20200106 461
Chapter 10 | Managing Large Projects
Objectives
After completing this section, you should be able to select and retrieve roles from Ansible Galaxy
or other sources, such as a Git repository, and use them in playbooks.
462 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Many of the roles on Ansible Galaxy are designed for other operating systems or network devices.
Use the Search tab to find Microsoft Windows-compatible roles. For example, searching for the
keyword or tag "windows" returns a large number of results.
Results are presented in descending order, based on the Best Match score, which is a computed
score derived from role quality, role popularity, and searches criteria.
Note
Consult the Content Scoring [https://galaxy.ansible.com/docs/contributing/
content_scoring.html] section of the Ansible Galaxy documentation for more
information on how Ansible Galaxy scores roles.
Figure 10.7 demonstrates how to use the search feature to browse roles. The Filters menu allows
you to perform searches by keywords, author IDs, platform, and tags. Possible platform values
include Windows for Microsoft Windows, among others.
Tags are arbitrary, single-word strings set by the role author that describe and categorize the role.
Users can use tags to find relevant roles. Possible tag values include system, development, web,
monitoring, and others. A role can have up to 20 tags in Ansible Galaxy.
Ansible Galaxy reports the number of times each role has been downloaded from Ansible Galaxy.
Ansible Galaxy also reports the number of watchers, forks, and stars for each GitHub repository
that stores a role. Use this information to determine how active development is for a particular
role, and how popular that role is in the community.
Figure 10.8 demonstrates a role page, which contains information such as tags, the Ansible version
the role requires, or the production readiness of the role.
DO417-RHAE2.8-en-1-20200106 463
Chapter 10 | Managing Large Projects
Important
In the Ansible Galaxy search interface, keyword searches match words or phrases in
the README file, content name, or content description. Tag searches, by contrast,
specifically match tag values set for the role by the author.
Use the name keyword to override the local name of the role. Use the version keyword to specify
the version of the role. You can use the version keyword with any value that corresponds to a
branch, tag, or commit hash in the software repository for the role. The src attribute specifies the
source of the role, for example, the arillso.chocolatey role from Ansible Galaxy.
- src: arillso.chocolatey
name: test.chocolatey
version: 1.3.2
Important
Specify the version of the role in your requirements.yml file, especially for
playbooks in production. If you do not specify a version, then the most recent
version of the role is used. If the upstream author makes changes to the role that
are incompatible with your playbook, then it may cause automation failure or other
problems.
464 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Specify roles that are not in Ansible Galaxy in your roles/requirements.yml file, and
Ansible Tower can automatically retrieve them. You can host your proprietary or internal roles
in a private Git repository, or on a web server. The following example shows how to configure a
requirements file using a variety of remote sources.
# 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 and a specific commit hash
- src: https://gitlab.com/guardianproject-ops/ansible-nginx-acme.git
scm: git
version: 56e00a54
name: nginx-acme
# from any Git-based repository, using SSH and a specific Git branch
- src: git@gitlab.com:guardianproject-ops/ansible-nginx-acme.git
scm: git
version: master
name: nginx-acme-ssh
The src keyword specifies the Ansible Galaxy role name. If the role is not hosted on Ansible
Galaxy, the src keyword indicates the URL for the role.
If the role is hosted in a source control repository, the scm attribute is required. Ansible Tower is
capable of downloading and installing roles from either Git-based or mercurial-based software
repositories. A Git-based repository requires an scm value of git, whereas a role hosted on a
mercurial repository requires a value of hg. If the role is hosted on Ansible Galaxy or as a tar
archive on a web server, then the scm keyword is omitted.
References
Galaxy Documentation — Ansible Documentation
https://galaxy.ansible.com/docs/
DO417-RHAE2.8-en-1-20200106 465
Chapter 10 | Managing Large Projects
Guided Exercise
Outcomes
You should be able to use Ansible Tower to download a role from Ansible Galaxy and use it in
your environment.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in Chapter 8, Interacting with Users and
Domains. You must complete the exercises for that chapter before attempting
the following activity.
1. Launch the Visual Studio Code editor, and then clone the projects repository to your
workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2. Review and fix the content of the requirements.yml file in the roles subdirectory. After
making the changes, commit and push the changes to the master branch.
2.1. Go to the roles directory, located at the top-level. Select the _requirements.yml
file, and then press F2 to rename the file to requirements.yml. The underscore
prevented Ansible from attempting to parse the incomplete file when syncing the
project.
466 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
2.2. Open the requirements.yml file. This file contains everything needed for Ansible
Tower to download the proper role. Change the file as follows:
- src: https://github.com/arillso/ansible.chocolatey.git
version: 1.3.2
name: ansible-chocolatey-role
2.3. Click Save. Note the status icons in the lower left corner. The asterisk on Master
indicates that changes were made.
3. Review and fix the the content of the install_chocolatey.yml file in the top-level
directory. After making the changes, commit and push the changes to the master branch.
3.1. Navigate to the top-level directory. Select the install_chocolatey.yml file; this
playbook uses the role from the requirements.yml file to install Chocolatey with
custom options. You can find this particular role at https://galaxy.ansible.com/
arillso/chocolatey . Change the file as follows:
---
- name: Installing chocolatey using a role
hosts: all
tasks:
- name: Install chocolatey
vars:
chocolatey_config:
- commandExecutionTimeoutSeconds: 2300
chocolatey_feature:
- virusCheck: true
- usePackageRepositoryOptimizations: true
import_role:
name: ansible-chocolatey-role
Important
Usually, a role has a lot of variables that are set to some default values. Use the
Galaxy interface to access the README.md file, which describes the usage of the
role, including the variables that customize the behavior of the role.
3.3. Change to the Source Control view, and then click + to stage the changes.
3.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
3.5. The status icon in the lower left indicates that there is a change to push to the remote
repository. Click Synchronize Changes to send the change to the remote repository,
and to receive any new changes from the remote repository.
4. Start an update of the projects repository project to synchronize the changes that
you made, and to automatically download the role defined in the requirements.yml file
from Ansible Galaxy.
DO417-RHAE2.8-en-1-20200106 467
Chapter 10 | Managing Large Projects
4.2. In the list of projects, click the synchronize changes icon for the projects
repository project to start the synchronization process.
4.3. Click the status icon and observe the automatic SCM update of the projects
repository project.
Note
Notice the fetch galaxy roles from requirements.yml task. This task
is automatically triggered at the end of the project synchronization when Ansible
Tower finds the roles/requirements.yml file.
5. Run the Run projects project job to test your playbook and the new role.
5.2. From the list of templates, select the Run projects project template.
Note
To select a project for editing, click its name.
5.4. If cleared, select the PROMPT ON LAUNCH check box for the LIMIT option.
5.5. If selected, clear the PROMPT ON LAUNCH check box of the CREDENTIAL and
INVENTORY options.
5.11. Verify that the status of the job in the DETAILS pane displays Successful.
Installation of Chocolatey with custom options, using a role from Ansible Galaxy, is
complete.
6. Add a role stored in your local git repository to the requirements.yml file.
6.1. Edit the content of the requirements.yml file in the roles subdirectory. After
making the changes, commit and push the changes to the master branch.
6.2. Go to the roles directory, located at the top-level. Select the requirements.yml
file, which contains everything needed for Ansible Tower to download the proper
role. Add a role to the file; the role was downloaded from Ansible Galaxy and
stored in your local git repository. You can find this particular role at https://
468 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
...output omitted...
- name: Ansible 7-zip Galaxy role
src: https://gitlab.example.com/student/ansible-7zip.git
scm: git
name: ansible-7zip
6.3. Click Save. Note the status icons in the lower left corner. There is an asterisk for
Master that indicates changes were made.
6.4. Change to the Source Control view, and then click + for requirements.yml to
stage the changes.
6.5. Enter a commit message, and then press Ctrl+Enter to commit the changes.
6.6. The status icon in the lower left indicates that there are changes to push to the remote
repository. Click Synchronize Changes to send your changes to the remote repository,
and retreive any new changes from the remote repository.
7.1. Navigate to the top-level directory. Select the install_7zip.yml file; this playbook
uses the role from the requirements.yml file to install 7zip. It displays as follows:
---
- name: Installing 7zip using a local role
hosts: all
tasks:
- name: Install 7zip
import_role:
name: ansible-7zip
8. Start an update of the projects repository project to synchronize the changes that
you made, and to automatically download the role defined in the requirements.yml file
from Ansible Galaxy.
8.2. In the list of projects, click the synchronize changes icon for the projects
repository project to start the synchronization process.
8.3. Click the status icon and observe the automatic SCM update of the project projects
repository.
Note
Notice the fetch galaxy roles from requirements.yml task. This task
is automatically triggered at the end of the project synchronization, when Ansible
Tower finds the roles/requirements.yml file.
9. The 7zip role that you synchronized uses the deprecated win_msi module, and an earlier
version of 7zip. In the following steps, you modify the role to replace the deprecated
module, and changethe version of 7zip to a later one.
DO417-RHAE2.8-en-1-20200106 469
Chapter 10 | Managing Large Projects
9.1. Launch the Visual Studio Code editor and clone the ansible-7zip repository to your
workstation instance.
9.2. Click Search Windows, search for code, and then open Visual Studio Code.
9.4. Review and fix the content of the main.yml file in the tasks directory. After making
the changes, commit and push the changes to the master branch.
9.5. Go to the tasks directory. Select the main.yml file; this file contains a set of tasks
required to download and install 7zip. Change all occurrences of win_msi module to
win_package module. Change the 7zip version from 1604 to 1900 . The main.yml
file with all the changes displays as follows:
---
# tasks file for 7zip
- name: create directory on localhost
file:
path: /tmp/ansible
state: directory
delegate_to: localhost
470 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
path: 'C:\ansible\7z1900-x64.msi'
state: absent
when: sevenzip_uninstall
9.6. Click Save. Note the status icons in the lower left. There is an asterisk next to Master,
indicating that changes were made.
9.7. Switch to the Source Control view, and then click + for the main.yml file to stage
the changes.
9.8. Enter a commit message, and then press Ctrl+Enter to commit the changes.
9.9. The status icons in the lower left indicates that there is a change to push to the remote
repository. Click Synchronize Changes to send the change to the remote repository,
and to receive any new changes from the remote repository.
10. Because you changed the role, Ansible Tower must download the correct version
of the role from the repository. The following steps demonstrate ho to change the
requirements.yml file, so that Ansible Tower uses the correct version of the role.
10.1. The commit number is now the role version number. To find out the proper commit
number in Visual Studio Code editor, click master on the status bar.
10.2.In the newly opened window take note of the number next to master. This is the
number of the last commit with your change. For example, the number might be
b967f3e4.
10.3.Change the working directory in Visual Studio Code. Click File, click Open Folder, and
select the projects directory.
10.4.Edit the content of the requirements.yml file in the roles subdirectory. After
making the changes, commit and push the changes to the master branch.
10.5.Go to the roles directory, located at the top-level. Select the requirements.yml
file. Add the commit version number as a parameter for the role version. Modify the file
as follows:
...output omitted...
- name: Ansible 7-zip Galaxy role
src: https://gitlab.example.com/student/ansible-7zip.git
scm: git
version: b967f3e4 <--INSERT THE COMMIT VERSION NUMBER HERE
name: ansible-7zip
DO417-RHAE2.8-en-1-20200106 471
Chapter 10 | Managing Large Projects
10.6.Click Save. Note the status icons in the lower left corner. There is an asterisk next to
Master, which indicates that changes were made.
10.7. Change to the Source Control view, and then click + next to requirements.yml to
stage the changes.
10.8.Enter a commit message, and then press Ctrl+Enter to commit the changes.
10.9.The status icon at the lower left corner indicates that there are changes to push to the
remote repository. Click Synchronize Changes to send your changes to the remote
repository, and to receive any new changes from the remote repository.
11. Start an update of the projects repository project, to synchronize the changes that
you made, and to automatically download the role defined in the requirements.yml file
from Ansible Galaxy.
11.2. In the list of projects, click the synchronize changes icon for the projects
repository project to start the synchronization process.
11.3. Click the status icon and observe the automatic SCM update of the projects
repository project.
Note
Notice the fetch galaxy roles from requirements.yml task. This task
is automatically triggered at the end of the project synchronization, when Ansible
Tower finds the roles/requirements.yml file.
12. Run the Run projects project job to test your updated role.
12.2. From the list of templates, select the Run projects project template.
Note
To select a project for editing, click its name.
12.4. If cleared, select the PROMPT ON LAUNCH check box for the LIMIT option.
12.5. If selected, clear the PROMPT ON LAUNCH check box of the CREDENTIAL and
INVENTORY options.
472 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
12.11. Verify that the status of the job in the DETAILS pane displays Successful.
13. You modified a role, and used that role to install 7zip on one of the managed hosts.
Click the Log Out icon to log out of Ansible Tower
DO417-RHAE2.8-en-1-20200106 473
Chapter 10 | Managing Large Projects
Objectives
After completing this section, you should be able to configure and run PowerShell Desired State
Configuration (DSC) resources from your Ansible Playbook to automate tasks.
Microsoft fosters a community effort to build and maintain DSC resources for many technologies.
These resources are published each month to the PowerShell Gallery as the DSC Resource Kit,
and are available from the GitHub site: https://github.com/PowerShell/DscResources.
The win_dsc Ansible module was introduced in Ansible 2.4, and allows Ansible to use existing
DSC resources for Windows hosts. The minimum requirement to run this module on hosts is
Powershell v5.0 or later.
DSC resources support code reuse, similar to Ansible roles, but provide a larger library of existing,
community-supported automation code than using only Ansible modules.
In many cases, you might have a choice between an Ansible module or a DSC resource to
automate a particular task. The following lists discuss some criteria that you might use when
deciding which approach to use:
• The host does not support PowerShell v5.0, or you cannot easily upgrade it.
• The Ansible module you are using has a feature that the DSC resource does not.
• The Ansible module checks for idempotency are better suited for your needs than the limited
DSC check mode support.
• The Ansible module in question supports diff mode, and DSC resources do not.
• There are bugs in a DSC resource, but the Ansible module works.
474 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
• You are familiar with the DSC resource, and more comfortable with how it functions.
• You want to use DSC resources and Ansible modules in the same automation runs, or in cross-
platform automation operations.
• The Ansible module does not support a feature present in a DSC resource.
• There are bugs in an existing Ansible module but the DSC resource works.
• Archive
• File
• Group
• Package
• WindowsFeature
You can find the list of all the DSC Resources at https://docs.microsoft.com/en-us/powershell/
scripting/dsc/resources/resources?view=powershell-6#built-in-resources.
Microsoft, and the community through the DSC Resource Kit, provide many additional custom
DSC resources, including:
• Domain Controller
• Failover Cluster
• DNS
In the first example, this excerpt from the tasks section of a play uses Ansible modules to install
Internet Information Services (IIS), and create a web page:
DO417-RHAE2.8-en-1-20200106 475
Chapter 10 | Managing Large Projects
Use the win_dsc module to accomplish the same tasks using DSC resources:
In the preceding code, Ansible installs the xWebAdministration DSC Resource Module using
the win_psmodule module. With the right DSC Resources now present, windowsfeature
resource is invoked to install the Web-Server feature. xWebsite resource is invoked in the last
task to create the IIS Website, and to add an HTTP binding to IIS Web Server.
476 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
The parameter PsDscRunAsCredential, can be set for every DSC resource, forcing the DSC
engine to run under a different account. PsDscRunAsCredential has a type of PSCredential
that you configure with the username and password suffix.
Using the Registry resource type as an example, the following example demonstrates defining a
task to access the HKEY_CURRENT_USER hive of the Ansible user:
References
Ansible Documentation — Desired State Configuration
https://docs.ansible.com/ansible/latest/user_guide/windows_dsc.html
DO417-RHAE2.8-en-1-20200106 477
Chapter 10 | Managing Large Projects
Guided Exercise
Outcomes
You should be able to use the win_dsc module to create files and directories.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in Chapter 8, Interacting with Users and
Domains. You must complete the exercises for that chapter before attempting
the following activity.
1. Launch the Visual Studio Code editor and then clone the projects repository to your
workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2. Review and fix the the content of the dsc_usage.yml file. After making the changes,
commit and push the changes to the master branch.
2.1. Select the dsc_usage.yml file; this file contains tasks for creating a directory,
creating a file, and extracting a zip archive. Change the file as follows:
478 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
...output omitted...
- name: Create a new directory
win_dsc:
resource_name: File
DestinationPath: C:\DO417\dsc-usage-example
Ensure: Present
Type: Directory
2.2. Click Save. Note the status icons in the lower left. There is an asterisk next to Master
indicating that changes were made.
2.3. Change to the Source Control view, and then click + for the modified file to stage the
changes.
2.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
2.5. The status icon in the lower left corner indicates that there are changes to push to the
remote repository. Click Synchronize Changes to send your changes to the remote
repository, and to receive any new changes from the remote repository.
3. Run the Run projects project job to test your playbook with the win_dsc modules.
3.2. From the list of templates, select the Run projects project template.
Note
To select a project for editing, and then click its name.
DO417-RHAE2.8-en-1-20200106 479
Chapter 10 | Managing Large Projects
3.4. If cleared, select the PROMPT ON LAUNCH check box for the LIMIT option.
3.5. If selected, clear the PROMPT ON LAUNCH check box for the CREDENTIAL and
INVENTORY options.
3.11. Verify that the status of the job in the DETAILS pane displays Successful.
5. Log in to win1.example.com host as the devops user with the RedHat123@! password.
Verify that you have a C:\DO417\dsc-usage-example directory with a new-file.txt
file in it, and an extracted-zip subdirectory containing the unzipped Example-of-a-
extracted-file.txt file.
480 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Lab
Outcomes
You should be able to:
• Create a playbook that uses the role to create new directories and install a Windows
feature.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
All Chapter 8, Interacting with Users and Domains guided exercises must be completed prior
to starting this exercise, due to changes in inventory and authentication.
1. Edit the projects-review.yml playbook in the projects repository, and make the
changes indicated. Commit and push your changes to the Git repository. Comments in the
playbook indicate the changes to make.
• Use DSC to create the proper directory structure, and to unzip the provided archive.
• Update the first task with the correct Ansible module, and the module options needed to
create the defined directory.
• Update the third task with the correct Ansible module, and the module options to install
the telnet-client Windows Feature.
2. Convert the projects-review.yml playbook that you modified to a role named
projects-review. The necessary directories and files inside the roles\projects-
review role directory are already populated. Copy and paste the code from the original
playbook into the proper main.yml files in the new role structure. When you copy the code
to the proper locations, make sure the indentation is correct.
Comments in each of the main.yml files help you identify which part of the original
playbook should be pasted into which directory or file in the new role structure.
DO417-RHAE2.8-en-1-20200106 481
Chapter 10 | Managing Large Projects
• Put all the other variables from the playbook in the roles\projects-review\vars
\main.yml file.
• Copy the do417-example.zip file from the projects\files directory to the roles
\projects-review\files directory.
3. Create a new projects_review_role.yml playbook that uses your new role to create the
directory structure and installs the Windows feature. Override the default variable of this role
by pointing it to the C:\DO417\projects-review-role\ directory.
Commit the changes to your local Git repository, and then push them to the remote
repository.
4. Start an update of the projects repository project to synchronize your
changes. Update the Run projects project job template to use your new
projects-review role. Update the template to instruct Ansible Tower to use the
projects_review_role.yml playbook to prompt you for the host to target, and to set
the proper credentials and inventory to use.
Launch a job using the template, and when prompted use win2.example.com as the target
host, AD Administrator as the credentials, and Dynamic inventory as the inventory.
5. You modified a playbook and converted it to a role. You used that role to install a Windows
feature, and to create directories and files on one of the managed hosts. If necessary, you
can log in to win2.example.com to verify that the new C:\DO417\projects-review-
role\ directory has been created, along with all the subdirectories and files defined in the
role. Use the EXAMPLE\Administrator username and AD Administrator password to
access win2.example.com.
6. Click Log Out to exit the Ansible Tower web interface.
482 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Solution
Outcomes
You should be able to:
• Create a playbook that uses the role to create new directories and install a Windows
feature.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
All Chapter 8, Interacting with Users and Domains guided exercises must be completed prior
to starting this exercise, due to changes in inventory and authentication.
1. Edit the projects-review.yml playbook in the projects repository, and make the
changes indicated. Commit and push your changes to the Git repository. Comments in the
playbook indicate the changes to make.
• Use DSC to create the proper directory structure, and to unzip the provided archive.
• Update the first task with the correct Ansible module, and the module options needed to
create the defined directory.
• Update the third task with the correct Ansible module, and the module options to install
the telnet-client Windows Feature.
1.1. Launch the Visual Studio Code editor. Navigate to File → Open Folder, and then
select the c:\Users\student\Documents\projects folder to open the c:\Users
\student\Documents\projects directory.
• Use DSC to create the proper directory structure, and to unzip the provided archive.
DO417-RHAE2.8-en-1-20200106 483
Chapter 10 | Managing Large Projects
• Update the first task with the correct Ansible module, and the module options to
create the defined directory.
• Update the third task with the correct Ansible module and the module options to
install the telnet-client Windows Feature.
---
- name: Configure a host using DSC
hosts: all
vars:
directory_location: C:\DO417\projects-review\
file_name: "{{ directory_location }}new-file.txt"
windows_resource: WindowsFeature
feature_name: telnet-client
zip_file_location: files/do417-example.zip
zip_remote_location: "{{ directory_location }}do417-example.zip"
zip_extracted_location: "{{ directory_location }}extracted-zip"
tasks:
484 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
resource_name: Archive
Destination: "{{ zip_extracted_location }}"
Path: "{{ zip_remote_location }}"
Ensure: Present
1.3. Save your changes. Note the status icons in the lower left corner. The asterisk next to
Master indicates that there are new changes
1.4. Switch to the Source Control view, and then click + for the projects-review.yml
playbook to stage the changes.
1.5. Enter a commit message and then press Ctrl+Enter to commit the changes.
1.6. The status icon in the lower left corner indicates that there are changes to push to the
remote repository. Click Synchronize Changes to send your changes to the remote
repository, and to receive any new changes from the remote repository.
• Put all the other variables from the playbook in the roles\projects-review\vars
\main.yml file.
• Copy the do417-example.zip file from the projects\files directory to the roles
\projects-review\files directory.
2.3. Select Edit → Copy or press Ctrl+C to cut the tasks from the file.
2.4. Navigate to Edit → Paste or press Ctrl+V to paste the text into the empty roles
\projects-review\tasks\main.yml playbook.
2.5. Select all of the text and press Shift+Tab twice to remove the task indentation.
DO417-RHAE2.8-en-1-20200106 485
Chapter 10 | Managing Large Projects
---
- name: Create a new directory
win_dsc:
resource_name: File
DestinationPath: "{{ directory_location }}"
Ensure: Present
Type: Directory
2.8. Copy all the variables, except the directory_location: variable, from the
projects-review.yml playbook to the roles\projects-review\vars
\main.yml file.
---
file_name: "{{ directory_location }}new-file.txt"
windows_resource: WindowsFeature
feature_name: telnet-client
zip_file_location: files/do417-example.zip
zip_remote_location: "{{ directory_location }}do417-example.zip"
zip_extracted_location: "{{ directory_location }}extracted-zip"
486 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
---
directory_location: C:\DO417\projects-review\
2.14. Commit the changes to your local Git repository, and then push them to the remote
repository.
2.15. Navigate to the Source Control pane, and then stage the changes.
2.16. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
2.17. Locate the status icons in the lower left corner, and notice that they indicate a change to
push to the remote Git repository. Click the Synchronize Changes to push your changes.
3. Create a new projects_review_role.yml playbook that uses your new role to create the
directory structure and installs the Windows feature. Override the default variable of this role
by pointing it to the C:\DO417\projects-review-role\ directory.
Commit the changes to your local Git repository, and then push them to the remote
repository.
3.1. Create the projects\projects_review_role.yml file and use the new role as
follows:
---
- name: Configure a host using a role
hosts: all
roles:
- role: projects-review
directory_location: C:\DO417\projects-review-role\
3.2. Commit the changes to your local Git repository, and then push them to the remote
repository.
Navigate to the Source Control pane, and then stage the changes.
3.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
3.4. Locate the status icons in the lower left corner and notice that they indicate a change to
push to the remote Git repository. Click the Synchronize Changes to push your changes.
DO417-RHAE2.8-en-1-20200106 487
Chapter 10 | Managing Large Projects
4.1. Double-click the Ansible Tower desktop icon to access Ansible Tower.
Log in using admin as the user name and RedHat123@! as the password.
4.3. In the list of projects, click the synchronization icon for the projects repository
project to start the synchronization process.
4.4. Click the status icon and observe the automatic SCM update of the project projects
repository.
4.6. Click the Run projects project job template to edit it.
4.7. Click the magnifying glass icon in the INVENTORY field. Click Dynamic inventory,
and then click SELECT.
4.8. Click the magnifying glass icon in the CREDENTIAL field. Click the AD
Administrator button, and then click SELECT.
4.9. Select the PROMPT ON LAUNCH check box for the LIMIT option.
4.11. Click SAVE to update the template, and then click LAUNCH to run the job.
4.12. Type win2.example.com in the LIMIT field. Click NEXT, and then click LAUNCH.
4.13. After all tasks have completed, verify that the status in the DETAILS pane displays
Successful.
5. You modified a playbook and converted it to a role. You used that role to install a Windows
feature, and to create directories and files on one of the managed hosts. If necessary, you
can log in to win2.example.com to verify that the new C:\DO417\projects-review-
role\ directory has been created, along with all the subdirectories and files defined in the
role. Use the EXAMPLE\Administrator username and AD Administrator password to
access win2.example.com.
6. Click Log Out to exit the Ansible Tower web interface.
488 DO417-RHAE2.8-en-1-20200106
Chapter 10 | Managing Large Projects
Summary
In this chapter, you learned:
• You can import playbooks into higher level playbooks to manage large projects with many plays
in a modular way.
• You can dynamically include or statically import tasks into plays in a playbook.
• Ansible roles make it easier for you to share and reuse Ansible code.
• Ansible Galaxy is a public library of Ansible content written and maintained by a variety of
Ansible administrators and users.
• You can use PowerShell DSC resources as tasks in your Ansible plays to run tasks, using existing
automation in the PowerShell Gallery maintained by Microsoft and the community.
DO417-RHAE2.8-en-1-20200106 489
490 DO417-RHAE2.8-en-1-20200106
Chapter 11
DO417-RHAE2.8-en-1-20200106 491
Chapter 11 | Constructing Ansible Tower Workflows
Objectives
After completing this section, you should be able to describe users and teams in Red Hat Ansible
Tower, the roles to which they can be assigned, and how to create and manage them.
Different people using an Ansible Tower installation require different levels of access. Some users
must have access to run existing job templates against a preconfigured inventory of machines.
Others must modify particular inventories, job templates, and playbooks. Still, others must have
access to change anything in the Ansible Tower installation.
Setting up user accounts for each person makes it easier to manage individual access to
inventories, credentials, projects, and job templates.
Users are assigned roles that control permissions, defining who can view, change, or delete an
object in Ansible Tower. Roles are managed with Role-Based Access Controls (RBAC). You can
manage roles collectively by granting them to a team, which is a collection of users. All users in
a team inherit the team's roles. Roles can also be granted to an organization, which is a logical
grouping of teams and resources. Each user must be assigned to an organization, and users inherit
roles from the organization, based on their user type.
Note
Roles determine whether users and teams can see, use, change, or delete objects
such as inventories and projects.
System Administrator
The System Administrator user type (also known as Superuser) provides unrestricted
access to perform any action within the entire Ansible Tower environment. System
Administrator is a special singleton role, which has read-write permission on all objects in
all organizations on the Ansible Tower.
The admin user created by the installer has the system administrator singleton role. therefore,
an Ansible Tower administrator should connect to Ansible Tower as this admin user.
492 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
System Auditor
The System Auditor user type also has a special singleton role, which has read-only access
to the entire Ansible Tower environment.
Normal User
Normal User is the standard user type. Initially, this user type has no special roles assigned
and starts with minimal access. A Normal User has no singleton roles, and is only assigned
roles associated with the organization of which the user is a member.
Creating Users
The following steps demonstrates how a user, that is logged in to Ansible Tower as the admin user,
can create additional user accounts.
• Enter the first name, last name, and email address for the new user into the FIRST NAME,
LAST NAME, and EMAIL fields, respectively.
• In the USERNAME field, specify a unique username for the new user.
• Click the magnifying glass icon for the ORGANIZATION field to display a list of organizations
within Ansible Tower. Select an organization from the list, and then click SAVE.
• Enter the desired password for the new user in the PASSWORD and CONFIRM PASSWORD
fields.
DO417-RHAE2.8-en-1-20200106 493
Chapter 11 | Constructing Ansible Tower Workflows
Editing Users
Use the Edit User window to edit the properties of the newly created user, as described in the
following steps:
One benefit of using Ansible Tower is the ability to share Ansible roles and playbooks across
departmental or functional boundaries within an enterprise. For example, the operations group in
an organization might already have Ansible roles for provisioning production, web, database, and
application servers. Developers can use these same roles to provision servers when preparing their
development environment. Ansible Tower makes it easier for different users and groups to use
existing roles and playbooks.
For very large deployments, it can be useful to categorize large numbers of users, teams, projects,
and inventories under one umbrella organization. Certain departments may not deploy to
certain inventories of hosts, or run certain playbooks. By using organizations, you can configure a
collection of users and teams to work with only those Ansible Tower resources that they expect to
use.
• In the fields, enter a name for the new organization, and an optional description if desired.
494 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Organization Roles
Newly created users inherit specific roles from the organization, based on the user type. You can
assign additional roles to a user after creation to grant permissions to view, use, or change other
Ansible Tower objects. An organization is itself one of these objects. There are four roles that users
can be assigned to in an organization:
Organizational Admin
A user with the organizational Admin role can manage all aspects of that organization,
including reading and changing the organization, and adding or removing users and teams.
DO417-RHAE2.8-en-1-20200106 495
Chapter 11 | Constructing Ansible Tower Workflows
Note
A number of related administrative roles grant more limited access than Admin:
Project Admin
A user with this role can create, read, update, and delete any project in the
organization. In conjunction with the Inventory Admin role, this allows users
to create job templates.
Inventory Admin
A user with this role can create, read, update, and delete any inventory in the
organization. In conjunction with the Job Template Admin and Project
Admin roles, this allows the user full control over job templates within the
organization.
Credential Admin
A user with this role can create, read, update, and delete shared credentials.
Notification Admin
A user with this role can be assigned notifications.
Workflow Admin
A user with this role can create workflows within the organization.
Auditor
A user with this role has read-only access to the organization.
Member
A user with this role has read-only access to the organization. The organization Member role
only provides a user the ability to view the list of users who are members of the organization,
and their assigned organization roles.
Unlike the organization Admin and Auditor roles, the Member role does not give users
permissions to any of the resources in the organization, such as teams, credentials, projects,
inventories, job templates, work templates, or notifications.
Read
A user with this role has read-only access to the organization object only. The Read role
allows a user to view the list of users who are members of the organization, and their assigned
organization roles.
However, unlike the organization Admin and Auditor roles, the Read role does not inherit
roles on any of the resources the organization contains, such as teams, credentials, projects,
inventories, job templates, work templates, and notifications.
You cannot assign roles to the organization object on Ansible Tower resources. Therefore,
a user that has the Member role or Read role on an organization only has access to the
organization object, and inherits no other permissions as a result of these roles.
Execute
A user with this role can execute job templates and workflow job templates in the organization.
496 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Important
Users with the System Administrator singleton role inherit the Admin role on
every organization within Ansible Tower.
Users with the System Auditor singleton role inherit the Auditor role on every
organization within Ansible Tower.
A user created with the Normal User user type is assigned a Member role on
the organization to which they were assigned at the time of the user's creation in
Ansible Tower. You can add other roles later, including additional Member roles on
other organizations.
Full administration of a user's role in an organization requires admin access. The following steps
provide an overview of administering user roles in Ansible Tower.
• Log in to the Ansible Tower web interface as admin, or any user with the Admin role on the
organization being modified.
• Click Permissions for the organization being managed. A list of users who have been granted
roles to the organization displays.
• In the ADD USERS/TEAMS pane, select the check box for the desired user.
• Click SELECT ROLES, and then select the desired organization role for the user. This step can
be repeated multiple times to add multiple roles for a user.
Note
For a list of role definitions, click the KEY button.
DO417-RHAE2.8-en-1-20200106 497
Chapter 11 | Constructing Ansible Tower Workflows
• Click the X symbol preceding to the role to remove existing roles from a user.
In Ansible Tower, users exist as objects at a Tower-wide level. A user can have roles in multiple
organizations. A team belongs to only one organization, but an Ansible Tower System
Administrator can assign the team roles on resources that belong to other organizations.
Important
Although a team belongs to a particular organization, you cannot assign
organizational roles to a team, as you can individual users. To manage the
organization object, you must directly assign roles to specific users.
However, you can assign roles to teams that give access to resources that belong to
a particular organization, such as projects, inventories, or job templates.
Creating Teams
The following steps describe how to create teams in an organization.
• Log in to the Ansible Tower web interface as the admin user, or as a user assigned the admin
role for the organization to which the new team will belong.
• Click +.
• in the New Team pane, enter a name for the new team in the NAME field.
498 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
• To complete the ORGANIZATION field, click the magnifying glass icon to get a list. In the
SELECT ORGANIZATION pane, select the organization to which the team belongs.
• Log in to the Ansible Tower web interface as the admin user, or a user assigned the admin role
for the organization to which the team belongs.
• In the Teams pane, click the name of the team to which to add the user.
• Click +.
• In the ADD USERS pane, select one or more users to add to the team. Then, click SAVE to add
the selected users to the team.
The following steps describe how to integrate Ansible Tower with Active Directory:
• In Active Directory, create a user with read permissions to the entire LDAP structure.
• Log in to the Ansible Tower web interface as the admin user, or as a user assigned the admin
role.
DO417-RHAE2.8-en-1-20200106 499
Chapter 11 | Constructing Ansible Tower Workflows
• Click LDAP.
• In the LDAP SERVER URI field, enter the LDAP server address to which Ansible Tower will
connect. For example, ldap://demo.example.com:389.
• In the LDAP BIND DN field, enter the Bind DN for the user that you
want Ansible Tower to use to connect to the LDAP server. For example,
CN=demo_user,CN=Users,DC=example,DC=com.
• In the LDAP BIND PASSWORD field, enter the binding user's password.
• From the LDAP GROUP TYPE list, choose the ActiveDirectoryGroupType type.
• In the LDAP USER SEARCH field, enter the pattern for the LDAP user search query. For
Active Directory, use the sAMAccountName=%(user)s) template. For example:
[
"CN=Users,DC=example,DC=com",
"SCOPE_SUBTREE",
"(sAMAccountName=%(user)s)"
]
• In the LDAP GROUP SEARCH field, enter the pattern for the LDAP search query to find
groups. For example:
[
"dc=example,dc=com",
"SCOPE_SUBTREE",
"(objectClass=group)"
]
• In the LDAP USER ATTRIBUTE MAP field, enter the pattern for mapping the LDAP users to
Ansible Tower API user attributes. For example:
{
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
• This step is optional, but depending on your environment configuration, you might find it useful.
With this setting, you can map users to Ansible Tower organizations, relative to their LDAP group
membership. In the LDAP ORGANIZATION MAP field, enter the pattern for mapping the
LDAP groups to Ansible Tower organizations. In the below example members of the Domain
Admins group map to the Demo Organization with the admin role, whereas members of the
Users group map to the organization with the Member role:
500 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
{
"Demo Organization": {
"admins": "CN=Domain Admins,CN=Users,DC=example,DC=com",
"users": [
"CN=Users,DC=example,DC=com"
],
"remove_users": true,
"remove_admins": true
}
}
• This step is optional, but depending on your environment configuration, you might find it useful.
With this setting, you can map all Active Directory users as members of a particular team. In the
LDAP TEAM MAP field, enter the pattern for mapping the LDAP users to Ansible Tower teams.
In the below example, all members of the Active Directory that successfully log into Ansible
Ansible Tower are automatically added to the My Demo Team team with a Member role:
{
"My Demo Team": {
"organization": "Demo Organization",
"users": true
}
}
You should now be able to log in to Ansible Tower using a user and password stored in
Active Directory.
References
Ansible Tower User Guide
https://docs.ansible.com/ansible-tower/latest/html/userguide
DO417-RHAE2.8-en-1-20200106 501
Chapter 11 | Constructing Ansible Tower Workflows
Guided Exercise
Outcomes
You should be able to create user accounts and teams, and describe the access provided by
different account types.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in Chapter 8: Interacting with Users and
Domains; you must complete those exercises before starting this exercise.
1. Access Ansible Tower by double-clicking the Ansible Tower shortcut on your desktop, or
by navigating to https://tower.example.com. Log in using the admin account and
RedHat123@! as the password.
2. Modify the Run tower project job template to run a new job that uses the domain-
users.yml playbook. The playbook populates Active Directory with additional user
accounts. You will use some of these accounts to create users in Ansible Tower.
2.2. From the list of templates, select the Run tower project template.
2.4. Select the PROMPT ON LAUNCH check box for the LIMIT option.
2.5. Select the PROMPT ON LAUNCH check box for the INVENTORY option.
2.6. Select the PROMPT ON LAUNCH check box for the CREDENTIAL option.
2.8. From the RUN TOWER PROJECT window, select Dynamic Inventory, and then
click NEXT.
502 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
2.10. In the LIMIT field, type in the windc.example.com hostname. Click NEXT, and then
click LAUNCH.
2.12. Verify that the status of the job in the DETAILS pane displays Successful.
Field Value
ORGANIZATION Default
EMAIL sam@example.com
USERNAME sam
PASSWORD RedHat123@!
4.3. Click Log Out in the upper right corner to log out, and then log back in as the user sam
and RedHat123@! as the password.
4.4. In the navigation pane, you can see that the user's access is limited because some
options are unavailable.
4.5. Click Users in the navigation pane to manage user permission. The user sam should
not be able to create new users.
4.6. Click the Log Out icon in the upper right corner to log out.
DO417-RHAE2.8-en-1-20200106 503
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
ORGANIZATION Default
EMAIL sylvia@example.com
USERNAME sylvia
PASSWORD RedHat123@!
6.2. As you can see, sylvia has the role of a System Auditor.
6.3. Log out, and then log back in as the user sylvia and RedHat123@! as the password.
6.4. Because sylvia is a system auditor, she has access to all the elements in the Ansible
Tower interface.
6.5. Click Users in the navigation pane to manage users. The user sylvia should not be
able to add new users.
6.6. Click the Log Out icon to log out of the Ansible Tower web interface.
7.1. Log in to the Ansible Tower web interface as the admin user with RedHat123@! as the
password.
Field Value
ORGANIZATION Default
504 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
EMAIL simon@example.com
USERNAME simon
PASSWORD RedHat123@!
8.1. Click PERMISSIONS to see the user’s permissions. This time, the permissions
frame explicitly reads "SYSTEM ADMINISTRATORS HAVE ACCESS TO ALL
PERMISSIONS".
8.2. Log out, and then log back in as simon with RedHat123@! as the password.
8.3. You can see, the user has access to all the elements in the navigation pane.
8.4. Click Users in the navigation pane to manage users. As you can see, simon has the
rights to create new users.
8.5. Click the Log Out icon to log out of the Ansible Tower web interface.
9. In the following steps, you integrate Ansible Tower with Active Directory.
Important
In your classroom environment, some of the options are already pre-populated.
Normally, all the fields are empty and you will have to populate them with the proper
settings according to your environment configuration.
Log in to the Ansible Tower web interface as the admin user or as a user assigned the
admin role.
9.6. In the LDAP BIND PASSWORD field, enter the binding user's password of
RedHat123@!.
9.7. From the LDAP GROUP TYPE list, select the ActiveDirectoryGroupType type.
9.8. In the LDAP USER SEARCH field, enter the pattern for the LDAP user search query.
DO417-RHAE2.8-en-1-20200106 505
Chapter 11 | Constructing Ansible Tower Workflows
[
"CN=Users,DC=example,DC=com",
"SCOPE_SUBTREE",
"(sAMAccountName=%(user)s)"
]
9.9. In the LDAP GROUP SEARCH field, enter the pattern for the LDAP search query to
find groups.
[
"CN=Builtin,dc=example,dc=com",
"SCOPE_SUBTREE",
"(objectClass=group)"
]
9.10.In the LDAP USER ATTRIBUTE MAP field, enter the pattern for mapping the LDAP
users to Ansible Tower API user attributes.
{
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
9.11. Clear the LDAP GROUP TYPE PARAMETERS field, so that it contains only {}.
{}
9.12. In the LDAP ORGANIZATION MAP field, enter the pattern for mapping the LDAP
groups to Ansible Tower organizations.
{
"Default": {
"admins": "CN=Administrators,CN=Builtin,DC=example,DC=com",
"users": false,
"remove_admins": true
}
}
9.13. In the LDAP TEAM MAP field, enter the pattern for mapping the LDAP users to
Ansible Tower teams.
{
"Developers": {
"organization": "Default",
"users": true
}
}
506 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
You can now log in to Ansible Tower using a user and password stored in
Active Directory.
9.15. Click the Log Out icon to log out of the Ansible Tower web interface.
10. Log in to Ansible Tower as the Active Directory user robert and RedHat123@! as the
password. With the LDAP integration that you have configured, Ansible Tower automatically
assigns this user the admin role, based on his Active Directory group membership.
10.1. Log in to the Ansible Tower web interface as the robert user and RedHat123@! as
the password.
You can see, the user has access to all the elements in the navigation pane.
10.2.Click the user robert to access the account details for this user.
Notice that Ansible automatically creates the user when first logged in, based on the
Active Directory integration and the proper LDAP group membership mapping.
Notice that the user has the admin role for the Default organization, becuase
this user is member of the Administrators group in Active Directory. When the
user robert logged in for the first time, Ansible Tower created a new team called
Developers. This user was added to the team and assigned the role of Member. The
team creation and user assignment are based on the user's membership in the Domain
Users Active Directory group, whose members are mapped automatically as members
of the Developers team.
10.4.Click Users in the navigation pane to manage users. As you can see, robert has the
rights to create new users.
DO417-RHAE2.8-en-1-20200106 507
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
NAME Devops
ORGANIZATION Default
13. Log in to Ansible Tower as the Active Directory user david and RedHat123@! as the
password. Ansible Tower automatically assigns this user the normal user role, based on
his Active Directory group membership.
13.1. Log in to the Ansible Tower web interface as the david user with RedHat123@! as the
password.
As you can see, this user has limited access to Ansible Tower elements in the navigation
pane.
13.4. Click Users in the navigation pane to manage users. The user david should not be
able to create new users.
14. Click the Log Out icon in the top right corner to log out.
508 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Objectives
After completing this section, you should be able to create a survey to make it simple for users to
launch jobs with Red Hat Ansible Tower.
Managing Variables
Writing playbooks that you can reuse in different situations, or for different systems, is
recommended. These systems might require slightly different behaviors, configurations, or work
in different environments. One easy way to deal with this variation is to use variables that you can
override when you run your plays.
You can set values for variables in several ways in Ansible, and you can override values if they are
properly set up. For example, a role provides a default value for a variable that can be overridden
by values set for that variable in an inventory or by a playbook. In general, it is best to set a value
for a variable in exactly one place to avoid issues with variable precedence.
In Ansible Tower, job templates can set extra variables and prompt users for a value when
launching a Job Template, or they may be set automatically by rerunning a job that was launched
with extra variables. Ansible Tower does not support playbooks with vars_prompt questions; the
closest replacement is surveys, which are discussed further in this section.
Important
Ansible Tower does not support playbooks that use vars_prompt to interactively
set variables.
• Set extra variables by entering them in YAML or JSON format in the EXTRA VARIABLES field
of the Job Template.
• Select the PROMPT ON LAUNCH option on the EXTRA VARIABLES field; Ansible Tower
prompts users to interactively modify the list of extra variables to use before running a job.
The following example demonstrates setting extra variables in the job template:
DO417-RHAE2.8-en-1-20200106 509
Chapter 11 | Constructing Ansible Tower Workflows
If you select the PROMPT ON LAUNCH option on the EXTRA VARIABLES field, then a window
displays to edit the variables when you launch a job from a job template.
510 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
If you relaunch the resulting job, the job reuses the same extra variables. You cannot modify the
extra variables of a job when it is rerun. To modify the extra variables, launch the job from the
original job templates and use different values for the variables.
Prompting for user input offers several advantages over other ways to set extra variables. No
detailed knowledge about how extra variables work, or the names of the extra variables that
playbooks use, is necessary. The user might not even know that extra variables are used in the job
template.
Because prompts can contain arbitrary text, they can be phrased in user-friendly language that is
easily understood, even if users lack detailed knowledge about Ansible.
Important
Surveys set extra variables. The values set for variables using a survey override the
values set on variables of the same name in any other way. This includes the EXTRA
VARIABLES field and PROMPT ON LAUNCH option set on the job template.
User-friendly Questions
Surveys can prompt users for input using customized questions. This allows for more user-
friendly prompts for user input of extra variable values than the PROMPT ON LAUNCH
method.
Answer Type
Aside from offering a user-friendly prompt, surveys can also define rules for, and perform
validation of, user inputs. User responses to survey questions can be limited to one of the
following seven answer types:
Type Description
Multiple Choice (single select) A list of options from which users can only
choose one option as a response.
Multiple Choice (multiple select) A list of options from which users can
choose one or more options as a response.
DO417-RHAE2.8-en-1-20200106 511
Chapter 11 | Constructing Ansible Tower Workflows
Answer Length
You can also define rules for the size of user responses to survey questions. For the following
answer types, a survey can define the minimum and maximum allowable character length for
user responses: Text, Textarea, Password, Integer, and Float.
Default Answer
You can provide a default answer for a question. The question can also be marked as
REQUIRED, which indicates that the users must provide an answer to the question.
Creating a Survey
You cannot add a survey when creating a job template. Add a survey to a job template after
creating the job template.
2. In the ANSWER VARIABLE NAME field, enter the name of the extra variable to
which the user's response is assigned.
3. From the ANSWER TYPE list, select the desired answer type for the user's response.
4. If using a multiple choice answer type, then define the list by entering one list item per
line in the MULTIPLE CHOICE OPTIONS field.
5. If using any answer type other than multiple choice, optionally specify the minimum
and maximum character length for the user's response in the MINIMUM LENGTH
and MAXIMUM LENGTH fields, respectively.
6. If desired, optionally define a default value for the extra variable being surveyed in the
DEFAULT ANSWER field. Ansible Tower uses this value if the user does not provide a
response.
8. Click +ADD to add the question to the Survey. A preview of the new question appears
in the PREVIEW panel.
5. Repeat the preceding steps to add additional questions to the survey. After you have added
all if your questions, scroll to the top of the window. A switch in the upper-left, next to
SURVEY, determines whether the survey is enabled or disabled. By default, surveys are
enabled upon creation, so the switch is in the ON position. To disable the survey, toggle the
switch to the OFF position.
512 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
After adding a survey to a job template, users are prompted for answers to the survey questions
when they launch jobs with that job template. If the job template has extra variables, or is
configured to prompt the user to set extra variables, then these values are set before the survey
is displayed to the user. Answers to the survey questions override any extra variables that were
already set.
References
Ansible Tower User Guide
https://docs.ansible.com/ansible-tower/latest/html/userguide
DO417-RHAE2.8-en-1-20200106 513
Chapter 11 | Constructing Ansible Tower Workflows
Guided Exercise
Outcomes
You will be able to add a survey to an existing job template and launch a job using a survey
from the Ansible Tower web UI.
Important
This exercise uses resources created in Chapter 8: Interacting with Users and
Domains; you must complete those exercises before starting this exercise.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Launch the Visual Studio Code editor, and then clone the tower repository to your
workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2. Edit the index.html.j2 file in the templates folder; modify this file so that it uses
variables to generate the index.html file. After making the changes, commit and push
the changes to the master branch.
2.1. Go to the templates directory, located at the top-level. Select the index.html.j2
file, then change the file as follows:
514 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
...output omitted...
<h2 style="color: #2e6c80;">This page has been provisioned by {{ student_name }}
using Ansible on the {{ ansible_facts['hostname'] }} host>/h2>
<h2 style="color: #2e6c80;">This page version is {{ version }}>/h2>
2.2. Click Save. Note the status icons in the lower left corner. There is an asterisk next to
Master that indicates that changes have been made.
2.3. Change to the Source Control view, and then click + for index.html.j2 to stage
the changes.
2.4. Enter a commit message, and then press Ctrl+Enter to commit the changes.
2.5. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to
push your local changes to the remote repository, and retrieve any new changes from
the repository.
3. Add a survey to the Run tower project job template. This survey will collect values for
the variables needed to generate the index.html file.
3.2. In the list of available templates, click Run tower project to edit the job template.
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Checked
3.5. Click +ADD to add this prompt to the survey, and then display a preview of the survey.
3.6. Add another question to the survey, filling in the details as follows:
Field Value
DO417-RHAE2.8-en-1-20200106 515
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Checked
3.7. Click +ADD to add this prompt to the survey, and then display a preview of the survey.
Important
Before saving, make sure that the Survey toggle switch is set to ON at the top of the
Survey editor window.
4. Run the Run tower project job to test your Jinja template and the survey.
4.2. From the list of templates, select the Run tower project template.
Note
To select a project for editing, click its name.
4.4. Select the PROMPT ON LAUNCH check box for the LIMIT option if not already
selected.
4.5. If selected, clear the PROMPT ON LAUNCH check box for both the CREDENTIAL
and the INVENTORY options.
4.9. In the RUN TOWER PROJECT window, type in the win2.example.com hostname.
Click NEXT.
4.10.In the WHAT VERSION ARE YOU DEPLOYING? field, type 1.0 as the value. In the
WHAT IS YOUR NAME? field, type in your name. Click NEXT, followed by LAUNCH.
4.11. Observe the live output of the running job. The status of the job changes after the
server successfully restarts.
516 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
4.12. Verify that the job status in the DETAILS pane displays Successful.
Notice the page version number and your name as the page creator.
6. Rerun the Run tower project job, this time with different version number value.
6.2. From the list of templates, select the rocket icon of the Run tower project
template.
6.3. In the RUN TOWER PROJECT window, type in the win2.example.com hostname.
Click NEXT.
6.4. In the WHAT VERSION ARE YOU DEPLOYING? field, type 1.5 as the value. In the
WHAT IS YOUR NAME? field, type in your name. Click NEXT followed by LAUNCH.
6.5. Observe the live output of the running job. The status of the job changes after the
server successfully restarts.
6.6. Verify that the job status in the DETAILS pane displays Successful.
DO417-RHAE2.8-en-1-20200106 517
Chapter 11 | Constructing Ansible Tower Workflows
8. Edit the Run tower project job template to turn off the survey.
8.1. In Ansible Tower, access the job templates from the navigation pane.
8.4. At the top of the survey editor window, toggle the Survey switch and set it to the OFF
position.
518 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Objectives
After completing this section, you should be able to schedule automatic execution of a job
template in Red Hat Ansible Tower.
If you have the Execute role on a job template, then you can launch jobs from that template using
a schedule. To configure scheduled jobs, first select Templates from the navigation pane. Click
the job template that you want to schedule, and then click SCHEDULES. Click + to create a new
schedule for that job template.
• LOCAL TIME ZONE: Run the Get-TimeZone PowerShell command to determine your local
time zone.
• REPEAT FREQUENCY: How often to repeat the job that the schedule manages. You can
choose None (run once), Minute, Hour, Day, Week, Month, or Year.
DO417-RHAE2.8-en-1-20200106 519
Chapter 11 | Constructing Ansible Tower Workflows
Depending on the chosen frequency, you might need to provide additional information, such as
launching a job every two days, or on the first Sunday of every month.
When finished, click SAVE to save the schedule. You can deactivate or activate a schedule using
the Survey ON/OFF toggle switch next to the schedule name.
You can also edit or delete any schedule from this pane, assuming you have sufficient privileges to
do so..
Cleanup Job Schedule deletes the details of historic jobs to save space. This job runs once
a week on Sundays to remove information about jobs more than 120 days old by default. You
can change edit the schedule to adjust the day or frequency of the job, and the data it keeps or
removes.
Cleanup Activity Schedule runs once a week on Tuesdays to remove information from the
activity stream that is more than 355 days old. Again, you can edit the schedule to change when
the job runs, and how much data it keeps.
References
Ansible Tower User Guide
https://docs.ansible.com/ansible-tower/latest/html/userguide
520 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Guided Exercise
Outcomes
You should be able to schedule a job template to launch automatically.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in Chapter 8: Interacting with Users and
Domains; you must complete those exercises before starting this exercise.
1. Add a schedule to the Run tower project job template that configures it to run at three
minutes from the current time. Use the win1.example.com host.
Access Ansible Tower using the Ansible Tower shortcut on your desktop, or navigate to
https://tower.example.com. Log in using the admin account and RedHat123@! as
the password.
5. Ensure that the PROMPT ON LAUNCH option is cleared for the LIMIT, INVENTORY,
and CREDENTIAL fields.
Select the Default inventory from the INVENTORY field. In the LIMIT field, enter
the win1.example.com as the host name. Ensure that the DevOps credential is set in the
CREDENTIAL field.
7. Click SCHEDULES to manage automatic execution of a job based on this job template.
DO417-RHAE2.8-en-1-20200106 521
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
START DATE Look at the current date on workstation, and set the
execution of the job to today's date.
START TIME Look at the current time on workstation, and set the
execution of the job to +3 minutes from the current time.
Note
The start time uses a 24-hour clock notation, for example, enter 18:00 to indicate 6
p.m.
Note
To save the schedule, you must turn off the survey. If you did not disable the survey
in the preceding exercise, go back and follow the steps to turn the survey off.
522 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
11. Click Jobs in the navigation bar and wait for the scheduled jobs to run.
DO417-RHAE2.8-en-1-20200106 523
Chapter 11 | Constructing Ansible Tower Workflows
Objectives
After completing this section, you will be able to create a sequence of job templates to execute
using workflows and workflow job templates in Red Hat Ansible Tower.
Instead of writing one large playbook to automate a complex operation, consider running several
playbooks in sequence. For example, to provision a server you might want to use a playbook from
the Networking team to allocate an IP address to the server and set up a DNS record, and then
use a separate playbook from the Operations team to install and configure the server operating
system. Finally, you could use a playbook from the Development team to deploy an application. In
other words, there is a particular workflow that you must follow for the process to succeed.
To manage this workflow in Ansible Tower, users can manually launch multiple jobs in sequence.
However, the jobs must execute in the correct order for everything to work correctly, as defined by
your workflow:
2. Operations jobs follow, but only if the networking jobs successfully complete.
3. Likewise, application development jobs follow operations jobs only if the networking and
operations jobs successfully complete.
Finally, if one of these playbooks fails, users might need to run other playbooks to recover.
To make this workflow easier to manage, Red Hat Ansible Tower supports Workflow Job Templates.
A workflow job template connects multiple job templates in a workflow. When launched, the
workflow job template starts a job using the first job template; whether the job succeeds or fails
determines which job template to launch next. This allows a sequence of jobs to run, and for
recovery steps to automatically run if a job fails.
You can start workflow job templates in several ways: manually, from the Ansible Tower web UI; as a
scheduled job; or using the Ansible Tower API with an external program.
Workflow job templates do not just serially run job templates. Using the graphical workflow editor,
workflow job templates chain together multiple job templates and run different job templates
depending on whether the preceding job succeeds or fails.
524 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Creating a workflow job template within the context of an organization requires the admin role for
the organization. Creating a workflow job template that is not part of an organization requires a
user with the singleton System Administrator user type.
1. Click Templates in the navigation pane to access the template management interface.
3. Enter a unique name for the workflow job template in the NAME field. Optionally, enter any
desired key-value pairs in the EXTRA VARIABLES field.
4. Click SAVE to create the workflow job template. After the workflow job template is created,
use the workflow visualizer to define and associate a workflow.
DO417-RHAE2.8-en-1-20200106 525
Chapter 11 | Constructing Ansible Tower Workflows
When you launch the workflow visualizer, it contains a single START node representing the starting
point for the execution of the workflow. Click START to initiate the workflow editing process; the
workflow visualizer displays a list of Ansible Tower resources that you can add as the first step of
the workflow. Select the desired resource type, the specific resource, and then click SELECT to
add the selected Ansible Tower resource as the first node.
In addition to job templates, you can also incorporate jobs that synchronize projects or inventories
into your workflow. This is useful to ensure that Ansible Tower updates projects and inventory
resources before starting the job templates that depend on them . To make these jobs easier to
identify in the workflow, project synchronization and inventory synchronization nodes are indicated
by a P or an I symbol respectively, which is displayed in the lower left corner of the node. This
notation is explained by the key at the top of the workflow editor screen. Job template nodes are
not marked with any special notation because they are the main node type in a workflow.
After adding a resource as the first workflow node, hovering over it causes two buttons to appear.
The red - button deletes the node, and the green + button adds a subsequent node. When adding
subsequent nodes, the RUN prompt appears in the resource selection panel, prompting for
additional input when you select a resource. The following three choices are offered by this prompt
to designate the relationship between the new node and the preceding node.
On Success Ansible Tower executes this node resource upon successful completion
of the actions associated with the previous node.
On Failure Ansible Tower executes this node resource upon failure of the actions
associated with the previous node.
Always Ansible Tower executes this node resource regardless of the outcome
of the actions associated with the previous node.
A node can have more than one child node. You can add a child node with a parent node
association type of On Success, and then add another child node with an association type of On
Failure. This creates a branch in the workflow structure, such that one course of action is taken
upon the success of an action, and a different course is taken upon failure.
526 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
As you add nodes to a workflow, differently colored lines connecting the nodes in the Workflow
Editor indicate the relationships between parent and child nodes. A green line indicates an On
Success type relationship between a parent and child node, and a red line indicates an On Failure
type relationship. A blue line indicates an Always type relationship.
After creating the entire decision tree structure of the workflow in the Workflow Editor, click SAVE
to save the workflow.
Surveys
Workflow job templates have access to many of the features that were discussed in previous
chapters for job templates. Like job templates, you can add surveys to workflow job templates to
allow users to interactively set extra variables.
DO417-RHAE2.8-en-1-20200106 527
Chapter 11 | Constructing Ansible Tower Workflows
Note
When a survey is added to a workflow job template, every job executed by the
workflow can access the resulting extra variables.
Launching a workflow job template is similar to launching a job template, as illustrated in the
following:
1. Click Templates in the navigation pane to access the template management interface.
2. Click the rocket icon for the workflow job template to launch the job.
As each step is completed, its node is outlined in either green or red, indicating the success or
failure of the actions associated with that step in the workflow. Progressions from one step to
another are represented by colored lines that indicate the decision responsible for the progression.
Green indicates an On Success progression, and red indicates an On Failure progression. Blue
indicates an Always progression.
Details of the workflow job run can be displayed either during or after execution. Click the
DETAILS link for each node in the workflow diagram, to display details about a currently running
job or a completed job. Click this link to display the results and standard output for the job run.
528 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
References
Ansible Tower User Guide
https://docs.ansible.com/ansible-tower/latest/html/userguide/
DO417-RHAE2.8-en-1-20200106 529
Chapter 11 | Constructing Ansible Tower Workflows
Guided Exercise
Outcomes
You should be able to create a workflow job template and launch a workflow from the Ansible
Tower web UI.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Important
This exercise uses resources created in Chapter 8: Interacting with Users and
Domains; you must complete those exercises before starting this exercise.
1. Access Ansible Tower using the Ansible Tower shortcut on your desktop, or navigate to
https://tower.example.com. Log in using the admin account and RedHat123@! as
the password.
2. Run the prepare.yml playbook from the Run tower project job template.
2.2. Click the Run tower project job template to open it.
2.4. Make sure that the PROMPT ON LAUNCH check box for the LIMIT option is cleared
and the text field is blank.
2.5. Make sure that the PROMPT ON LAUNCH check box for the CREDENTIAL option is
cleared. From the list of available credentials choose AD Administrator .
2.6. Make sure that the PROMPT ON LAUNCH check box of the INVENTORY option is
cleared. From the list of available inventories, choose Dynamic Inventory.
2.7. Click SAVE to update the template, and then click LAUNCH to run the job.
530 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
3. Modify the existing Run tower project job template. Limit the job template to only
run on win2.example.com, using the AD Administrator credentials, the Dynamic
inventory, and the manage.yml playbook.
Field Value
ORGANIZATION Default
5. Configure the workflow of the Deploy the web page workflow job template.
5.2. Click START to add the first action. This displays a list of available actions in the ADD
A NODE panel.
5.4. Select tower repository and click SELECT. This links the START node with a blue
line (always perform) to the node project node, tower repository, in the Workflow
Visualizer window.
5.5. Move your mouse over the new node and click + to add an action following the project
synchronization of the tower repository. This displays a list of available actions in
the ADD A NODE panel.
5.7. Select broken repository, and then click SELECT. This links the node for the
tower repository project to a new node for the broken repository project
synchronization in the Workflow Visualizer window. The green link indicates that the
progression only takes place upon success of the preceding node.
DO417-RHAE2.8-en-1-20200106 531
Chapter 11 | Constructing Ansible Tower Workflows
5.8. Move your mouse over the new node and click + to add an action after the project
synchronization of broken repository. This displays a list of actions to be
performed.
5.9. Click JOBS if not already there, and then select the Run tower project job
template.
5.10. Select On Success from the RUN list, and then click SELECT. This links the node
for the broken repository project to a new node for the Run tower project
job template in the workflow visualizer window. The green link indicates that the
progression only takes place upon success of the preceding node.
5.11. Move your mouse over the broken repository node and click + to add an action
after the project synchronization of broken repository. This displays a list of
actions to be performed. This time, you will add a node to execute if the broken
repository project synchronization node fails.
5.12. Click JOBS if not already there, and then select the Clean win2 job template.
5.13. Select On Failure from the RUN list, and then click SELECT. This links the node for
the broken repository project to a new node for the Clean win2 job template in
the workflow visualizer window. The red link indicates that the progression only takes
place upon failure of the preceding node.
6. Launch a job using the Deploy the web page workflow job template.
6.2. Click the rocket icon for the Deploy the web page workflow job template, to launch
the workflow. This redirects you to a detailed status page for the running workflow.
6.3. Observe the running jobs in the workflow. Click DETAILS for each running job to see
more detailed output.
6.4. Notice that the broken repository node is marked red, and the Clean win2 node
runs. The red border around the broken repository node indicates that the job
associated with that node failed; based on the workflow logic the Clean win2 node
executes and successfully finishes.
6.5. Verify that the status of the workflow in the DETAILS pane displays Successful.
7. Fix the issue in the broken repository project, and then execute the workflow again.
Observe how the workflow logic executes a different selection of nodes based on the
successful execution of each node in the workflow.
7.3. In the SCM URL field, enter the url for synchronizing the repository, https://
gitlab.example.com/student/windows.git.
532 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
8. Workflows can use surveys to assign values to existing variables. Add a survey to the
Deploy the web page workflow.
8.1. Add a survey to the Deploy the web pag workflow. This survey will collect values
for the variables needed to generate the index.html file.
8.3. In the list of available templates, click Deploy the web page to edit the workflow
template.
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Selected
8.6. Click +ADD to add this survey prompt to the survey. This displays a preview of the
survey.
8.7. Add another question to the survey, completing the details as follows:
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Selected
8.8. Click +ADD to add this prompt to the Survey. This displays a preview of the Survey.
Important
Before saving, make sure that the ON/OFF toggle switch is set to ON.
DO417-RHAE2.8-en-1-20200106 533
Chapter 11 | Constructing Ansible Tower Workflows
9. Launch the modified workflow with the survey, and verify the successful execution of each
of the nodes. Click Templates in the navigation pane.
9.1. Click the rocket icon for the Deploy the web page workflow template to launch the
workflow.
9.2. A DEPLOY THE WEB PAGE window displays. In the WHAT VERSION ARE YOU
DEPLOYING? field, type 3.0. In the WHAT IS YOUR NAME? field, type in your
name. Click NEXT, and then click LAUNCH.
9.3. Observe the running jobs of the workflow. Click DETAILS for each running job to see a
more detailed output. All the workflow nodes should complete their jobs successfully.
9.4. Verify that the workflow status displayed in the DETAILS pane is Successful.
10. Open Chrome, and then access http://win2.example.com:8080 . The new webpage
is deployed using your workflow, including all the data provided by the survey.
11. Click the Log Out icon to log out of Ansible Tower
534 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Lab
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Add two users as Normal Users to the Default organization with the following information:
User 1 User 2
DO417-RHAE2.8-en-1-20200106 535
Chapter 11 | Constructing Ansible Tower Workflows
4. Copy the existing Run tower project job template and name it TEST webservers
setup.
Use the following details to modify the new job template:
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT win2.example.com
5. Copy the existing Run tower project job template and give it the name PROD
webservers setup.
Use the following details to modify the copied job template:
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT windc.example.com
6. Create a new From Test to Prod workflow job template using the following details:
Field Value
ORGANIZATION Default
7. Configure the From Test to Prod workflow job template so that it contains the following
steps:
• Upon success of the previous step, launch the TEST webservers setup job template.
• Upon success of the previous step, launch the PROD webservers setup job template.
536 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
8. Add a Survey containing the following information to the From Test to Prod workflow job
template. Make sure this is a required survey.
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
9. Launch a workflow using the From Test to Prod workflow job template. When prompted
by the survey, enter v1.3 for the page version and your name.
10. Verify that the web servers have been updated: win2.example.com,
windc.example.com. Open Chrome and access http://win2.example.com:8080 and
http://windc.example.com:8080 .
DO417-RHAE2.8-en-1-20200106 537
Chapter 11 | Constructing Ansible Tower Workflows
Solution
Outcomes
You should be able to:
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
1. Add two users as Normal Users to the Default organization with the following information:
User 1 User 2
1.1. Log in to the Ansible Tower web interface as the admin user with RedHat123@! as the
password.
538 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
ORGANIZATION Default
EMAIL adam@example.com
USERNAME adam
PASSWORD RedHat123@!
1.6. Scroll down the next pane, and then click + to add another user.
Field Value
ORGANIZATION Default
EMAIL ophelia@example.com
USERNAME ophelia
PASSWORD RedHat123@!
DO417-RHAE2.8-en-1-20200106 539
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
NAME Operations
ORGANIZATION Default
3.1. In the Operations team editor window, click USERS to manage team users.
3.6. In the next window, verify that adam and ophelia have the Member role in the
Operations team.
4. Copy the existing Run tower project job template and name it TEST webservers
setup.
Use the following details to modify the new job template:
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT win2.example.com
4.2. Click the copy icon for the Run tower project job template.
4.4. Use the following details to modify the new job template:
Field Value
540 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT win2.example.com
5. Copy the existing Run tower project job template and give it the name PROD
webservers setup.
Use the following details to modify the copied job template:
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT windc.example.com
5.2. Click the copy icon for the Run tower project job template.
Field Value
CREDENTIAL AD Administrator
PLAYBOOK manage.yml
LIMIT windc.example.com
DO417-RHAE2.8-en-1-20200106 541
Chapter 11 | Constructing Ansible Tower Workflows
6. Create a new From Test to Prod workflow job template using the following details:
Field Value
ORGANIZATION Default
Field Value
ORGANIZATION Default
7. Configure the From Test to Prod workflow job template so that it contains the following
steps:
• Upon success of the previous step, launch the TEST webservers setup job template.
• Upon success of the previous step, launch the PROD webservers setup job template.
7.2. Click START to add the first action in the workflow. A list of actions to perform displays
in the ADD A NODE pane.
7.3. Click PROJECT SYNC to display the list of available projects. Select tower repository,
and then click SELECT. In the Workflow Visualizer window, this connects the START
node to the node for the tower repository project with a blue line, indicating that
this step will always be performed.
7.4. Move your mouse over the new node, and then click + to add an action after the project
synchronization of tower repository. A list of actions to perform displays.
7.5. In the ADD A NODE pane, click JOBS if not already selected. Select the TEST
webservers setup job template. Depending on the size of your web browser window,
you may need to look at the next page to find the job template. Select On Success from
the RUN list, and then click SELECT.
The workflow visualizer window shows the node for the tower repository project
linked by a green line to the TEST webservers setup job template. This indicates
542 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
that if the project synchronization for tower repository is successful, then the TEST
webservers setup job template will be launched.
7.6. Move your mouse over the new node and click + to add an action after the TEST
webservers setup job template.
7.7. Click JOBS if not there already, and then select the PROD webservers setup job
template. Select On Success from the RUN list, and then click SELECT.
8. Add a Survey containing the following information to the From Test to Prod workflow job
template. Make sure this is a required survey.
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
Field Value
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Selected
8.3. Click ADD to add the survey prompt to the survey. This displays a preview of the survey.
8.4. Add another question to the survey, completing the details as follows:
Field Value
MINIMUM LENGTH 1
MAXIMUM LENGTH 40
REQUIRED Checked
8.5. Click +ADD to add the survey prompt to the survey. This displays a preview of the
survey.
Important
Before saving, make sure that the ON/OFF toggle switch is set to ON in the Survey
editor window.
9. Launch a workflow using the From Test to Prod workflow job template. When prompted
by the survey, enter v1.3 for the page version and your name.
9.2. Click the rocket icon for the From Test to Prod workflow job template to launch the
workflow. This opens the survey that you just created, and prompts for input.
9.3. In the WHAT VERSION ARE YOU DEPLOYING? field, type 1.3. In the WHAT IS
YOUR NAME? field, type in your name. Click NEXT, and then click LAUNCH. This
redirects you to a detailed status page for the running workflow.
544 DO417-RHAE2.8-en-1-20200106
Chapter 11 | Constructing Ansible Tower Workflows
9.4. Observe the running jobs of the workflow. Click DETAILS for a running or completed job
to see a more detailed output from the job.
10. Verify that the web servers have been updated: win2.example.com,
windc.example.com. Open Chrome and access http://win2.example.com:8080 and
http://windc.example.com:8080 .
10.2.When ready, log out from the Ansible Tower web UI.
DO417-RHAE2.8-en-1-20200106 545
Chapter 11 | Constructing Ansible Tower Workflows
Summary
In this chapter, you learned:
• There are three user types: System Administrator, System Auditor, and Normal User.
• System Administrator and System Auditor are singleton roles that grant read-write and
read-only access to all Ansible Tower resources, respectively.
• A team is a group of users, and you can use a team to make it easier to assign particular roles on
Ansible Tower resources to a set of users.
• Use surveys to enable single-step automation. You can prompt users for the values of extra
variables that playbooks use.
• A workflow job template allows you to launch a job that runs several playbooks in sequence.
546 DO417-RHAE2.8-en-1-20200106
Chapter 12
Comprehensive Review
Goal Review tasks from Microsoft Windows Automation
with Red Hat Ansible
DO417-RHAE2.8-en-1-20200106 547
Chapter 12 | Comprehensive Review
Comprehensive Review
Objectives
After completing this section, you should have reviewed and refreshed the knowledge and skills
learned in Microsoft Windows Automation with Red Hat Ansible.
You can refer to earlier sections in the textbook for extra study.
• Describe fundamental concepts of automation with Red Hat Ansible Automation, its basic
design, and common use cases.
• Describe the architecture of a Windows automation implementation using Red Hat Ansible
Tower and a Git repository as a central point of control.
• Retrieve, manage, edit, and store files in a remote Git version control system, such as GitHub or
GitLab, using Visual Studio Code.
• Configure Microsoft Windows systems to provide the prerequisites and access needed for
management by Red Hat Ansible Automation.
• Configure Red Hat Ansible Tower with an inventory of Windows hosts to manage, and
credentials needed to authenticate and connect to those hosts.
• Describe what an Ansible module is, and run a single operation on managed hosts as an ad hoc
command using Red Hat Ansible Tower.
• Configure a job template for a playbook in Red Hat Ansible Tower, and then use it to run the
playbook on managed hosts.
548 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
• Write a playbook that includes multiple plays, and then use per-play privilege escalation to
perform tasks as particular users.
• Create and reference variables that affect specific hosts or host groups, the play, or the global
environment, and describe how variable precedence works.
• Encrypt sensitive variables using Ansible Vault, and run playbooks that reference Vault-
encrypted variables.
• Inspect the Windows Registry and ensure that registry keys are correctly configured.
• Write plays efficiently using loops, and use conditions to control when tasks run.
• Implement tasks that run only when another task makes a change on the managed host.
• Control what happens when a task fails, recover from task failure, and control what conditions
cause a task to report failure.
• Create, install, edit, and remove files on managed hosts, and configure file permissions and other
characteristics.
• Create an Active Directory domain if it does not exist, and configure host membership, users,
and groups in that domain.
• Generate an Ansible inventory dynamically in Red Hat Ansible Tower based on Active Directory
domain membership.
DO417-RHAE2.8-en-1-20200106 549
Chapter 12 | Comprehensive Review
• Run arbitrary PowerShell commands, configure PowerShell modules, and set up scheduled tasks
on managed hosts with Ansible playbooks.
• Manage large playbooks by importing or including other playbooks or tasks from files,
unconditionally or based on a conditional test.
• Create a role to allow code reuse by different Ansible projects, and run it as part of a play in a
playbook.
• Select and retrieve roles from Ansible Galaxy or other sources such as a Git repository, and use
them in playbooks.
• Automate tasks by configuring and running PowerShell Desired State Configuration (DSC)
resources from your Ansible Playbook.
• Describe users and teams in Red Hat Ansible Tower, the roles to which they may be assigned,
and how to create and manage them.
• Create a survey to make it simple for users to launch jobs with Red Hat Ansible Tower.
• Create a sequence of job templates to execute using workflows and workflow job templates in
Red Hat Ansible Tower.
550 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Lab
Outcomes
You should be able to run ad hoc commands and configure Windows Registry keys.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise, you will configure a login message populated with some system facts.
• From Ansible Tower, use the Run Commands feature to run the setup module against
win1.example.com. Note the facts that are available.
• From workstation, open Visual Studio Code and clone the compreview repository
if you have not cloned it previously. The repository is accessible at https://
gitlab.example.com/student/compreview.git.
• Open the lab1.yml playbook, and then complete the tasks so that the following items
are included. After updating the Ansible Playbook, the message should display, in order,
the name of the system, its IP address, the operating system version, the CPU count, and
the total memory.
• legalnoticecaption defines the login message caption.
• legalnoticetext defines the login message text.
• ansible_facts["fqdn"]
• ansible_facts["ip_addresses"][0]
• ansible_facts["distribution"]
• ansible_facts["processor_count"]
• ansible_facts["memtotal_mb"]
• In the Ansible Tower web UI, edit the Run compreview project to use the lab1.yml
playbook, and then launch a job.
DO417-RHAE2.8-en-1-20200106 551
Chapter 12 | Comprehensive Review
Note
If you have logged in to win1 previously, and then logged out, use the Sign
out option before reconnecting. Disconnecting leaves the user session
logged in, so that the login message is not displayed until you log out and
then log in again.
552 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Solution
Outcomes
You should be able to run ad hoc commands and configure Windows Registry keys.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise, you will configure a login message populated with some system facts.
• From Ansible Tower, use the Run Commands feature to run the setup module against
win1.example.com. Note the facts that are available.
• From workstation, open Visual Studio Code and clone the compreview repository
if you have not cloned it previously. The repository is accessible at https://
gitlab.example.com/student/compreview.git.
• Open the lab1.yml playbook, and then complete the tasks so that the following items
are included. After updating the Ansible Playbook, the message should display, in order,
the name of the system, its IP address, the operating system version, the CPU count, and
the total memory.
• legalnoticecaption defines the login message caption.
• legalnoticetext defines the login message text.
• ansible_facts["fqdn"]
• ansible_facts["ip_addresses"][0]
• ansible_facts["distribution"]
• ansible_facts["processor_count"]
• ansible_facts["memtotal_mb"]
• In the Ansible Tower web UI, edit the Run compreview project to use the lab1.yml
playbook, and then launch a job.
DO417-RHAE2.8-en-1-20200106 553
Chapter 12 | Comprehensive Review
Note
If you have logged in to win1 previously, and then logged out, use the Sign
out option before reconnecting. Disconnecting leaves the user session
logged in, so that the login message is not displayed until you log out and
then log in again.
1.1. From workstation, double-click the Ansible Tower shortcut icon on your Desktop
to access your Ansible Tower instance located at http://tower.example.com.
1.2. Log in to Ansible Tower using student as the user name and RedHat123@! as the
password.
1.3. From the main dashboard page, select Inventories from the navigation pane, and then
select Default inventory from the inventories listed.
1.4. From the Default inventory page, click HOSTS, and then select the check box next to
the win1.example.com host entry.
1.5. After selecting win1.example.com, click RUN COMMANDS to enter the ad hoc
command execution pane.
1.6. On the RUN COMMAND page, select setup from the MODULE list. Select the
DevOps machine credential, and then click LAUNCH to run the module.
1.7. Review the output to verify that the module ran successfully, and make a note of the
various facts available.
2. Launch the Visual Studio Code editor. If you have not previously cloned the compreview
repository, clone it to your workstation instance.
2.1. Click Search Windows, search for code, and then open Visual Studio Code.
554 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
4.1. Modify the Configure login message caption task to configure the caption for
the login message. This modifies the legalnoticecaption value.
4.2. Modify the Configure login message text task. This modifies the
legalnoticetext value.
5. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
5.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
5.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and to retrieve any new changes from the
repository.
7.2. Click the Run compreview project job template to select it.
7.4. Click SAVE to update the template, and then click LAUNCH to run the job.
8. After all tasks have completed, verify that the status in the DETAILS section shows
Successful. If the job is not successful, compare your playbook with the solutions/
lab1.sol solution file of the compreview project.
DO417-RHAE2.8-en-1-20200106 555
Chapter 12 | Comprehensive Review
9. From workstation, open the RDP client and connect to win1.example.com as the
devops user, with RedHat123@! as the password. Accept the insecure certificate, and then
verify that the login message displays.
Click OK to continue.
Disconnect from win1.example.com.
556 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Lab
Outcomes
You should be able to work with Microsoft Windows services, and use a template to generate
a file on a managed host.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will disable unnecessary services to reduce the attack surface of the
system, and populate the hosts file with the names and IP addresses for all hosts in the
Windows group.
Note
Note that the playbook contains two plays. The first play gathers facts for
all hosts in the Windows group, so that the template in the second play can
access host variables (hostvars) for all members of the group.
• From workstation, launch the Visual Studio Code editor, and then clone the
compreview repository if you have not cloned it previously. The repository is available at
https://gitlab.example.com/student/compreview.git.
• Open the lab2.yml playbook, and then complete the tasks. The following list describes
the services to disable.
• Application Host Helper Service (AppHostSvc)
• Geolocation Service (lfsvc)
• Print Spooler (Spooler)
• SSDP Discovery (SSDPSVC)
• In the playbook, use the correct module to send to the managed host the hosts.j2
template file. Reuse the variable that points to the directory that contains the hosts file.
• Update the second task to use the module for managing services. Disable and stop the
services listed in the disabled_services loop.
DO417-RHAE2.8-en-1-20200106 557
Chapter 12 | Comprehensive Review
Add the following host variables (hostvars) entries to the for loop at the bottom of the
file. The format should be a space-separated list containing the IP address, the FQDN, and
the host name in that order.
• {{ hostvars[host]['ansible_ip_addresses'][0] }}
• {{ hostvars[host]['ansible_fqdn'] }}
• {{ hostvars[host]['inventory_hostname_short'] }}
• In the Ansible Tower web UI, edit the Run compreview project template to use the
lab2.yml playbook, and then launch a job.
• In the Ansible Tower web UI, edit the Run compreview project template to use the
revert_lab2.yml playbook, and then launch a job.
558 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Solution
Outcomes
You should be able to work with Microsoft Windows services, and use a template to generate
a file on a managed host.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will disable unnecessary services to reduce the attack surface of the
system, and populate the hosts file with the names and IP addresses for all hosts in the
Windows group.
Note
Note that the playbook contains two plays. The first play gathers facts for
all hosts in the Windows group, so that the template in the second play can
access host variables (hostvars) for all members of the group.
• From workstation, launch the Visual Studio Code editor, and then clone the
compreview repository if you have not cloned it previously. The repository is available at
https://gitlab.example.com/student/compreview.git.
• Open the lab2.yml playbook, and then complete the tasks. The following list describes
the services to disable.
• Application Host Helper Service (AppHostSvc)
• Geolocation Service (lfsvc)
• Print Spooler (Spooler)
• SSDP Discovery (SSDPSVC)
• In the playbook, use the correct module to send to the managed host the hosts.j2
template file. Reuse the variable that points to the directory that contains the hosts file.
• Update the second task to use the module for managing services. Disable and stop the
services listed in the disabled_services loop.
DO417-RHAE2.8-en-1-20200106 559
Chapter 12 | Comprehensive Review
Add the following host variables (hostvars) entries to the for loop at the bottom of the
file. The format should be a space-separated list containing the IP address, the FQDN, and
the host name in that order.
• {{ hostvars[host]['ansible_ip_addresses'][0] }}
• {{ hostvars[host]['ansible_fqdn'] }}
• {{ hostvars[host]['inventory_hostname_short'] }}
• In the Ansible Tower web UI, edit the Run compreview project template to use the
lab2.yml playbook, and then launch a job.
• In the Ansible Tower web UI, edit the Run compreview project template to use the
revert_lab2.yml playbook, and then launch a job.
1. From workstation, open Visual Studio Code. If you have not previously cloned the
compreview repository, clone it to your workstation instance.
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2.
Note
Run this step only if you have already cloned the compreview repository.
disabled_services:
- AppHostSvc
- lfsvc
- Spooler
- SSDPSRV
3.2. Complete the Configure hosts file from template task. This populates the C:
\Windows\System32\drivers\etc\hosts file.
560 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
3.3. Modify the Reduce server footprint task. The ignore_errors parameter is
used so that absent services do not cause the whole task to fail.
5. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
5.2. Navigate to the Source Control pane, and then click + for the lab2.yml file to stage
this file.
5.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
5.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and to retrieve any new changes from the
repository.
7.2. Click the Run compreview project job template to navigate to it.
DO417-RHAE2.8-en-1-20200106 561
Chapter 12 | Comprehensive Review
7.5. If you completed Chapter 8: Interacting with Users and Domains, select the AD
Administrator credential from the CREDENTIAL list and update the EXTRA
VARIABLES text field to match the following:
---
ansible_winrm_transport: kerberos
7.6. Click SAVE to update the template, and then click LAUNCH to run the job.
8. After all tasks have completed, verify that the status in the DETAILS pane shows
Successful. If the job is not successful, compare your playbook with the solutions/
lab2.sol and solutions/hosts.sol solution files in the compreview Git repository.
9. Verify all changes have been executed.
9.1. From workstation, connect to win2.example.com with the remote desktop client.
Use EXAMPLE\Administrator as the user name and the AD Administrator
password.
9.3. Open the Services control panel applet, and verify that the appropriate services are
disabled.
10. In the Ansible Tower web UI, edit the Run compreview project template to use the
revert_lab2.yml playbook, and then launch a job.
562 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Lab
Outcomes
You should be able to work with installation packages, and use blocks in playbooks to control
sets of tasks.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will install the 7zip package.
• From workstation, launch Visual Studio Code, and then clone the compreview
repository if you have not cloned it previously.
• Replace the two placeholders for the win_package module with the two parameters
that provide the product ID and the installation arguments to pass.
• Add a second clause in the playbook to instruct Ansible to display the debug message,
and attempt the removal of 7-Zip.
• Add a final clause in the playbook to instruct Ansible to always run the tasks.
• Use the correct Ansible module, with a parameter, to instruct the deletion of the
installation package.
• In the Ansible Tower web UI, edit the Run compreview project template to use the
lab3.yml playbook, and then launch a job.
DO417-RHAE2.8-en-1-20200106 563
Chapter 12 | Comprehensive Review
Solution
Outcomes
You should be able to work with installation packages, and use blocks in playbooks to control
sets of tasks.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will install the 7zip package.
• From workstation, launch Visual Studio Code, and then clone the compreview
repository if you have not cloned it previously.
• Replace the two placeholders for the win_package module with the two parameters
that provide the product ID and the installation arguments to pass.
• Add a second clause in the playbook to instruct Ansible to display the debug message,
and attempt the removal of 7-Zip.
• Add a final clause in the playbook to instruct Ansible to always run the tasks.
• Use the correct Ansible module, with a parameter, to instruct the deletion of the
installation package.
• In the Ansible Tower web UI, edit the Run compreview project template to use the
lab3.yml playbook, and then launch a job.
1. From workstation, launch Visual Studio Code. If you have not previously cloned the
compreview repository, clone it to your workstation instance.
564 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
2.
Note
Skip this step if you previously cloned the repository.
3.1. Correct the block structure so that the uninstall is performed in the rescue section, and
the installation package is always cleaned up.
rescue:
- debug:
msg: "Sorry, it didn't work out :("
...output omitted...
always:
- name: Clean up installation package
3.2. Ensure that the Copy package to target host task is using the correct module.
DO417-RHAE2.8-en-1-20200106 565
Chapter 12 | Comprehensive Review
4. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
4.2. Navigate to the Source Control pane, and then click the + next to lab3.yml to stage
the changes.
4.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
4.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
your local changes to the remote repository, and retrieve any new changes from the
repository.
6.2. Click the Run compreview project job template to navigate to it.
6.4. Click SAVE to update the template, and then click LAUNCH to run the job.
7. After all tasks have completed, verify that the status in the DETAILS pane shows
Successful. If the job is not successful, compare your playbook with the solutions/
lab3.sol file in the compreview Git repository.
8. Verify all changes are complete.
8.1. Connect to win1.example.com using the remote desktop client. Use devops as the
user name and RedHat123@! as the password.
8.2. Click Search Windows, search for 7-zip, and then note that 7-Zip File Manager
appears in the search results.
566 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Lab
Outcomes
You should be able to import roles to manage features, and install software using the
win_chocolatey module.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will configure the SNMP service on win2, and install an SNMP client on
win1. Then, use the SNMP client on win1 to walk the MIB tree on win2.
• Launch the Visual Studio Code editor, and then clone the compreview repository if you
have not cloned it previously.
• Open the lab4.yml playbook, and then populate the variables and complete the tasks in
the SNMP configured on server play.
snmp_access_address
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_community
public
snmp_contact
Adam Admin
snmp_location
Arizona
snmp_monitoring_server
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_password
Password1!
DO417-RHAE2.8-en-1-20200106 567
Chapter 12 | Comprehensive Review
snmp_user
admin
package
snmpb
• In the SNMP configured on server play, use the Ansible import statement to import
the ansible.snmp role.
• In the SNMP configured on client play, use the correct Ansible module to install the
chocolatey package.
• In the last task of the SNMP configured on client play, use the correct Ansible
module to install the package defined by the package variable.
• In the Ansible Tower web UI, edit Run compreview project to use the lab4.yml
playbook, and then launch a job.
• From workstation, use the RDP client to log in to win1 as student, and then use the
snmpb tool to walk the MIB of win2.
568 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Solution
Outcomes
You should be able to import roles to manage features, and install software using the
win_chocolatey module.
This tab also displays information for connecting to all of your systems.
Confirm that all infrastructure machines are running, and that you can access Ansible Tower
and GitLab from the Windows workstation.
Instructions
In this exercise you will configure the SNMP service on win2, and install an SNMP client on
win1. Then, use the SNMP client on win1 to walk the MIB tree on win2.
• Launch the Visual Studio Code editor, and then clone the compreview repository if you
have not cloned it previously.
• Open the lab4.yml playbook, and then populate the variables and complete the tasks in
the SNMP configured on server play.
snmp_access_address
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_community
public
snmp_contact
Adam Admin
snmp_location
Arizona
snmp_monitoring_server
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_password
Password1!
DO417-RHAE2.8-en-1-20200106 569
Chapter 12 | Comprehensive Review
snmp_user
admin
package
snmpb
• In the SNMP configured on server play, use the Ansible import statement to import
the ansible.snmp role.
• In the SNMP configured on client play, use the correct Ansible module to install the
chocolatey package.
• In the last task of the SNMP configured on client play, use the correct Ansible
module to install the package defined by the package variable.
• In the Ansible Tower web UI, edit Run compreview project to use the lab4.yml
playbook, and then launch a job.
• From workstation, use the RDP client to log in to win1 as student, and then use the
snmpb tool to walk the MIB of win2.
1. From workstation, launch Visual Studio Code. If you have not previously cloned the
compreview repository, clone it to your workstation system..
1.1. Click Search Windows, search for code, and then open Visual Studio Code.
3.1. Populate the variables for the ansible.snmp role, as provided earlier in this lab.
vars:
snmp_access_address: >-
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_community: public
snmp_contact: Adam Admin
570 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
snmp_location: Arizona
snmp_monitoring_server: >-
{{ hostvars['win1.example.com']['ansible_ip_addresses'][0] }}
snmp_password: Password1!
snmp_user: admin
Note
The >- sign instructs Ansible to remove the new line at the end of the string.
...output omitted...
snmp_user: admin
import_role:
name: ansible.snmp
3.3. Add the package variable for the second play, as listed in the table. Give it a value of
snmpb.
vars:
package: snmpb
3.4. Complete the Chocolatey is installed task. This task uses the win_chocolatey
module to install the chocolatey package.
3.5. Complete the Packages are installed task, using the variable configured earlier.
4. Save and commit the changes to your local Git repository, and then push them to the remote
repository.
4.2. Navigate to the Source Control pane, and then click the + next to lab4.yml to stage
the changes.
4.3. Enter a brief commit message, and then press Ctrl+Enter to commit the changes.
4.4. The status icons displayed in the lower left corner of the editor indicate that there are
changes ready to push to the remote Git repository. Click Synchronize Changes to push
DO417-RHAE2.8-en-1-20200106 571
Chapter 12 | Comprehensive Review
your local changes to the remote repository, and retrieve any new changes from the
repository.
6.5. If you completed Chapter 8: Interacting with Users and Domains, select the AD
Administrator credential from the CREDENTIAL list and update the EXTRA
VARIABLES text field to match the following:
---
ansible_winrm_transport: kerberos
6.6. Click SAVE to update the template, and then click LAUNCH to run the job.
7. After all tasks have completed, verify that the status in the DETAILS pane shows
Successful. If the job is not successful, compare your playbook with the solutions/
lab4.sol solution file in the compreview Git repository.
8. From workstation, use the RDP client to connect to win1.example.com. Use devops as
the user and RedHat123@! as the password. Use the snmpb tool to walk the MIB for win2.
8.1. The snmpb tool does not create menu entries; browse to C:\Program Files
(x86)\SnmpB using Windows Explorer, and then start the snmpb tool.
8.2. Click Options → Manage Agent Profiles..., and then right-click in the left pane and
select New agent profile. Set the name to win2, and the Agent Address/Name to
win2.example.com. Check all SNMP versions, and then click OK.
8.3. From the Remote SNMP Agent list, switch the host from localhost to win2.
Select SNMPv2c as the SNMP version.
8.4. Right-click the MIB Tree top-level folder, and then select Walk. The query results
appear in the right pane.
Scroll up to the top of the results to see the values defined in the playbook.
572 DO417-RHAE2.8-en-1-20200106
Chapter 12 | Comprehensive Review
Note
If the SNMP query displays a Timeout message, then a restart of the
win2.example.com host may be required.
DO417-RHAE2.8-en-1-20200106 573
574 DO417-RHAE2.8-en-1-20200106
Appendix A
Supplementary Topics
Goal Investigate supplementary topics not included in
the official course.
DO417-RHAE2.8-en-1-20200106 575
Appendix A | Supplementary Topics
Objectives
After completing this section, you should be able to apply user roles to control access to
credentials, projects, and job templates in Red Hat Ansible Tower.
Admin
The inventory Admin role grants users full permissions over an inventory. These permissions
include deletion and modification of the inventory. In addition, this role also grants permissions
associated with the inventory roles Use, Ad Hoc, and Update.
Use
The inventory Use role grants users the ability to use an inventory in a job template resource.
This controls which inventory is used to launch jobs using the job template's playbook.
Ad Hoc
The inventory Ad Hoc role grants users the ability to use the inventory to execute ad hoc
commands. Using Ansible Tower for ad hoc command execution is discussed in detail in
Ansible Tower User Guide.
Update
The inventory Update role grants users the ability to update a dynamic inventory from its
external data source.
Read
The inventory Read role grants users the ability to view the contents of an inventory.
This is done by assigning users and teams appropriate roles as discussed above. The inventory
must be created and saved before users and teams can be assigned roles on it.
Roles are assigned through the PERMISSIONS section of the inventory's editor screen
(accessible through the pencil icon next to its name). The following procedure details the steps to
assign users and teams roles on an inventory:
1. Log in as a user with Admin role on the organization in which the inventory was created.
2. Click Inventories in the navigation pane to display the organization's inventory list.
3. Click the pencil icon for the inventory to enter the inventory's editor screen.
576 DO417-RHAE2.8-en-1-20200106
Appendix A | Supplementary Topics
4. On the inventory's editor screen, click the PERMISSIONS button to enter the permissions
editor.
A list appears, naming users and teams, with their assigned roles. If there is an X next to a
role, click it to remove that role from the user.
6. In the ADD USERS / TEAMS selection screen, click either USERS or TEAMS. Select the
check boxes next to the users or teams to be assigned new roles.
7. Under Please assign roles to the selected users/teams, click the SELECT ROLES list.
Select the desired inventory role for each user or team.
Click KEY for a list of inventory roles and their definitions.
To assign roles to machine credentials, the machine credential must be assigned to an Ansible
Tower organization. Then users and teams in that organization can share that credential through
role assignments.
Admin
The Admin role grants users full permissions for a machine credential. These permissions
include deletion and modification of the credential, as well as the ability to use the credential
in a job template.
Use
The Use role grants users the ability to use a machine credential in a job template.
Read
The Read role grants users the ability to view the details of a machine credential. This still
does not allow them to decrypt the secrets which belong to that machine credential through
the web interface.
Additional roles cannot be assigned until it is first saved, after which they can be set by editing the
machine credential.
Roles are assigned through the PERMISSIONS section of the machine credential editor screen.
The following procedure details the steps for granting permissions to a machine credential which
belongs to an organization after its creation.
1. Log in as a user with Admin role on the organization in which the machine credential was
created.
DO417-RHAE2.8-en-1-20200106 577
Appendix A | Supplementary Topics
3. Click the name of the machine credential to edit in order to enter the credential editor
screen.
4. On the credential editor screen, click the PERMISSIONS button to enter the permissions
editor.
6. On the user and team selection screen, click either USERS or TEAMS and then select the
check boxes for the users or teams to be assigned roles.
7. Under Please assign roles for the selected users/teams, click KEY to display the list of
credential roles and their definitions.
8. Click the SELECT ROLES list and select the desired credential role for each user or team.
Important
Permissions for credentials can also be added through either the user or team
management screens.
The following is the list of roles available for providing users access to SCM credentials:
Admin
The Admin role grants you full permissions for an SCM credential. These permissions include
deletion and modification of the credential. This role also grants to the user the permissions
associated with the credential, which are Use and Read roles.
Use
The Use role grants you the ability to associate an SCM credential with a project. This role also
grants you the permissions associated with the credential Read role.
The Use role does not control whether a user can themselves use the SCM credential to
update a project, only whether they can assign that SCM credential so that it can then be used
by someone who has the Update role for a project.
For example, if you associate an SCM credential with a project, any user with the Update role
on the project can use the associated SCM credential without being granted Use role that
credential.
Read
The Read role grants you the ability to view the details of an SCM credential.
578 DO417-RHAE2.8-en-1-20200106
Appendix A | Supplementary Topics
The assignment of SCM credential roles to users or teams dictates who has permissions to that
credential. You cannot assign these permissions when creating the SCM credential for the first
time. You can manage the permissions by editing the credential after its creation.
Roles are assigned through the PERMISSIONS section of the credential editor screen. The
following list details the steps for granting permissions to an SCM credential that belongs to an
organization.
1. Log in as a user with Admin role in the organization that the SCM credential belongs to.
2. Click Credentials in the navigation pane to enter the credential management interface.
6. In the user and team selection screen, select either a team or a user for which you want to
create a new permission.
7. Click KEY to display the list of credential roles and their definitions.
Select a role from the SELECT ROLES list and select the desired role for the user or the
team.
Important
You can also manage permissions for SCM credentials through either the user or
team management screens available under Ansible Tower's Settings interface.
DO417-RHAE2.8-en-1-20200106 579
Appendix A | Supplementary Topics
Admin
The Admin role grants you full access to the project. With this role, users can delete the
project or modify its properties, including its permissions. In addition, this role also grants you
the Use, Update, and Read roles, which are discussed later in this section.
Use
The Use role grants you the ability to use a project with a job template. This role also grants
you the permissions associated with the project Read role.
Update
The Update role grants you the ability to manually update or schedule an update to the
project's materials from its SCM source. This role also grants you the permissions associated
with the Project Read role.
Read
The Read role grants you the ability to view the details, permissions, and notifications
associated with the project.
You must explicitly configure any other access for other users. You cannot assign roles when you
define the project for the first time, only by editing the project after creation.
You can review roles by accessing the PERMISSIONS section of the project. The following
procedure details the steps to assign roles for a project:
1. Ensure you log in as a user that has the Admin role for the project.
Click the pencil icon for the row of the project that you want to update.
3. On the Project editor screen, select PERMISSIONS to manages the permissions for the
project.
5. In the user and team selection screen, select either a team or a user.
Select KEY to display the list of project roles and their definition.
6. Click the SELECT ROLES list and select the desired project role for each user or team.
580 DO417-RHAE2.8-en-1-20200106
Appendix A | Supplementary Topics
Note
You can also manage roles for projects from either the user or team management
screens.
Admin
The Admin role gives you the permission to delete a job template or edit its properties,
including its associated permissions. This role also grants you the permissions that are
associated with the Execute and Read roles of the job template.
Execute
The Execute role permits you to execute a job using the job template. It also grants you the
permission to schedule a job from a job template but also the permissions that are associated
with the Read role of the job template.
Important
To be able to run a job from a job template, you only need the Execute role of
the job template; you do not need the Use role for any of the resources that are
associated with the job template.
Read
The Read role grants you read-only access to view the properties of a job template. It also
grants access to view other information related to the job template, such as the list of jobs
that run using the job template, as well as its associated permissions and notifications.
DO417-RHAE2.8-en-1-20200106 581
Appendix A | Supplementary Topics
The assignment of the previously discussed job template roles to users or teams, dictates who
has permissions on a job template. You cannot assign these permissions when you create the job
template; you can configure these options by editing the job template after its creation.
Roles are available from the PERMISSIONS section of the job template editor screen. The
following procedure describes the steps for granting permissions to a job template after its
creation.
1. Log in as a user with Admin role on the organization that owns the job template or as the user
that created it.
4. From the user and team selection screen, select a user or a team that requires permissions for
the job template.
5. Click KEY to display the list of job template roles and their definitions.
6. Select the role for user or the team from the SELECT ROLES list.
References
Ansible Tower User Guide
http://docs.ansible.com/ansible-tower/latest/html/userguide/index.html
582 DO417-RHAE2.8-en-1-20200106
Appendix B
Legal Notices
DO417-RHAE2.8-en-1-20200106 583
Appendix B | Legal Notices
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
584 DO417-RHAE2.8-en-1-20200106