Red Hat Enterprise Linux Automation With Ansible
Red Hat Enterprise Linux Automation With Ansible
Install and Configure Ansible on CentOS 8 / RHEL 8 using the steps below.
Overview
Automation is one of the most critical areas of improvement in most organizations.
Today, most companies are in the process of re-inventing themselves in one way or
another to add software development capabilities and as such, take full advantage of
the digitization of everything. Software development release cycles are changing in
order to release faster. Continuous delivery, where every change is potentially it’s
own release is becoming the new standard. Infrastructure is following suit, after all,
continuous delivery is not about just software changes but all changes and
infrastructure plays a key role. For any of this to work of course, 100% automation is
required. To achieve that goal, an automation language that is easy and applicable
to development and operations is needed. Ansible is that language and if you are not
on-board yet, now is your chance not to miss the train because it is leaving the
station. Ansible is easy, Ansible is powerful and Ansible is flexible.
Infrastructure as Code (IAC)
1. A good automation system allows you to implement Infrastructure as Code
practices.
2. IAC means that you can use a machine-readable automation language to
define and describe the state you want your IT infrastructure to be in.
3. If the automation language is represented as simple text files, it can easily be
managed in a version control system like software code.
4. The advantage of this is that every change can be checked into the version
control system.
5. If you want to revert to an earlier known-good configuration, you simply can
check out that version of the code and apply it to your infrastructure.
6. This builds a foundation to help you follow best practices in DevOps.
7. Developers can define their desired configuration in the automation language.
Operators can review those changes more easily to provide feedback, and
use that automation to reproducibly ensure that systems are in the state
expected by the developers.
What is Ansible?
1. Ansible is an open source automation platform.
2. It is a simple automation language
3. It is also an automation engine that runs Ansible Playbooks.
4. It is a deployer tool
5. It is an orchestration tool
6. It is a configuration management tool
7. Architecture is agentless
8. It uses push based mechanism
9. Ansible is idempotent
Ansible Is Simple
1. Ansible Playbooks provide human-readable automation.
2. No special coding skills are required to write Playbooks
Ansible Is Powerful
1. You can use Ansible to deploy applications, for configuration management, for
workflow
automation, and for network automation.
2. Ansible can be used to orchestrate the entire application life cycle.
Ansible Is Agentless
1. Ansible is built around an agentless architecture. Typically, Ansible connects
to the target hosts it manages using OpenSSH or WinRM and runs tasks, by
pushing out small programs called Ansible modules to those hosts.
2. Any modules that are pushed are removed when Ansible is finished with its
tasks.
3. We can start using Ansible almost immediately because no special agents
need to be
deployed to the managed hosts.
--become-method BECOME_METHOD
privilege escalation method to use (default=sudo), use
`ansible-doc -t become -l` to list valid choices.
--become-user BECOME_USER
run operations as this user (default=root)
-K, --ask-become-pass
ask for privilege escalation password
-b, --become run operations with become (does not imply password prompting)
Configuring Connections ⇒
Ansible needs to know how to communicate with its Managed Hosts
By default, Ansible connects to managed hosts using SSH protocol.
Non-SSH Connections ⇒
The protocol used by Ansible to connect to Managed hosts is set by default to
smart, which determines the most efficient way to use SSH.
If we do not have localhost in the inventory file, Ansible sets up an implicit
localhost entry to allow us to run ad hoc commands and playbooks that target
localhost.
[ansible@control rh294]$ ansible localhost --list-hosts
hosts (1):
localhost
Here, instead of using the smart SSH connection type, Ansible connects to the
localhost
using the special local connection type by default.
The local connection type ignores the remote_user parameter setting and runs
commands directly on the local system.
SUMMARY
In this chapter, you learned:
Any system upon which Ansible is installed and which has access to the
required configuration files and playbooks to manage remote systems
(managed hosts) is called a control node.
Managed hosts are defined in the inventory. Host patterns are used to
reference managed hosts defined in an inventory.
Inventories can be static files or dynamically generated by a program from an
external source, such as a directory service or cloud management system.
Ansible looks for its configuration file in a number of places in order of
precedence. The first configuration file found is used; all others are ignored.
The ansible command is used to perform ad hoc commands on managed
hosts.
Ad hoc commands determine the operation to perform through the use of
modules and their arguments, and can make use of Ansible's privilege
escalation features.
Assignments
==========
Task 1 :
1. Setup Ansible Lab using 1 Control Node and 2 Managed Hosts.
2. Register control node with redhat.com and subscribe to the proper channel
for installing Ansible.
3. Install Ansible on the Control Node.
4. Install Python on Control node and Managed hosts.
5. Setup Password-less ssh authentication from control node to managed hosts.
6. Login to control node as ansible user and create a directory called rh294
7. Create an Ansible configuration file within rh294 directory as per the following
specifications -
a. Set the inventory file as /home/ansible/rh294/inventory
b. Remote user should be set to devops [ sudo should have
already been configured ]
c. Configure privilege escalation for the devops user so that he can
perform administrative tasks.
8. Create a custom static inventory file called /home/ansible/inventory as per
the
following specifications :
a. Information about your 2 managed hosts is listed in the following table.
You will
assign each host to multiple groups for management purposes based
on the
purpose of the host,the city where it is located, and the deployment
environment to
which it belongs to.
Task 2 :
1. Execute an ad hoc command on control node to display the content of
/etc/redhat-release file from node1
2. Execute an ad hoc command on control node to create a group on node1 as
per the following specifications :
a. Group Name ⇒ dba
b. GID ⇒ 10001
3. Execute an ad hoc command on control node to create a user on node1 as
per the following specifications :
. User Name ⇒ bob
a. UID ⇒ 5001
b. Login Shell ⇒ /bin/sh
c. Group(Secondary) ⇒ dba
d. Gecos Field ⇒ Devops Operator
4. Using the copy module, execute an ad hoc command on node1 to change the
contents of the /etc/motd file so that it consists of the string "Managed by
Ansible"
followed by a newline.
Clear the content of /etc/motd file using shell module.
Task 3: Write an ad-hoc command to copy the /etc/hosts file from control node
node1 as per
the following specifications.
a. Destination Directory : /tmp
b. File Owner : devops
c. Group Owner : devops
d. Permission : 0640
Implementing Playbooks
Ad hoc commands can run a single, simple task against a set of targeted
hosts as a one-time command.
The real power of Ansible, however, is in learning how to use playbooks to run
multiple,
complex tasks against a set of targeted hosts in an easily repeatable manner.
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.
A playbook is a text file written in YAML format, and is normally saved with the
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 -
a. Data elements at the same level in the hierarchy (such as items
in the same list) must have the same indentation.
b. Items that are children of another item must be indented more
than their parents.
A playbook begins with a line consisting of three dashes (---) as a start of
document marker.
It may end with three dots (...) as an end of document marker.
An item in a YAML list starts with a single dash followed by a space.
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 has a list of 3 items as a value.
name: just an example
hosts: webservers
tasks:
- first
- second
- third
The original example play has three keys, name, hosts, and tasks, because
these keys all have the same indentation.
The first line of the example play starts with a dash and a space (indicating
the play is the first item of a list), and then the first key, the name attribute.
The name key associates an arbitrary string with the play as a label. This
identifies what the play is for.
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 the play's tasks are run.
hosts attribute takes a host pattern as a value, such as the names of
managed hosts or groups in the inventory.
The last key in the play is the tasks attribute, whose value specifies a list of
tasks to run for this play.
Example : Play with a single task
tasks:
- name: alex exists with UID 5000
user:
name: alex
uid: 4000
state: present
Running Playbooks
The ansible-playbook command is used to run playbooks.
ansible-playbook example.yml
Note that the value of the name key for each play and task is displayed when
the playbook is run.
The Gathering Facts task is a special task that the setup module usually runs
automatically at the start of a play.
Syntax Verification
The ansible-playbook command offers a --syntax-check option that you can
use to verify the syntax of a playbook.
ansible-playbook --syntax-check example.yml
Ansible Variables
Ansible supports variables that can be used to store values.
Variables provide a convenient way to manage dynamic values for a given
environment in your ansible project.
Examples of values that variables might include :
a. Users to create
b. Packages to install
c. Services to start
d. Files to remove
e. Partitions to create
Naming Variables
Variable names must start with a letter, and they can only contain letters,
numbers, and
underscores.
Defining Variables
Variables can be defined in a variety of places in an Ansible project.
It can be simplified to three basic scope levels:
• Global scope: Variables set from the command line or Ansible configuration.
• Play scope: Variables set in the play.
• Host scope: Variables set on host groups and individual hosts by the
inventory.
Some disadvantages of this approach are that it makes the inventory file more
difficult to work
with, it mixes information about hosts and variables in the same file, and uses an
obsolete syntax.
Using Directories to Populate Host and Group Variables
The preferred approach to defining variables for hosts and host groups is to
create two directories, group_vars and host_vars, in the same working
directory as the inventory file or directory.
These directories contain files defining group variables and host variables,
respectively.
Consider a scenario where there are two data centers to manage and the data
center hosts are defined in the ~/project/inventory inventory file:
If you need to define a general value for all servers in both data centers, set a
group variable for the datacenters host group:
If the value to define varies for each data center, set a group variable for each
data center host
group:
If the value to be defined varies for each host in every data center, then define
the variables in
separate host variable files:
The directory structure for the example project, project, if it contained all the
example files above, would appear as follows:
vim register.yml
---
- name: Installs a package and prints the result
hosts: web
tasks:
- name: Install a package
yum:
name: httpd
state: installed
register: install_result
- debug: var=install_result
When we run the playbook, the debug module is used to dump the value of the
install_result registered variable to the terminal.
Task : Write a Playbook to perform the following tasks -
a. Install the packages - httpd, firewalld
b. Declare respective variables for packages / services / rules
c. Start and Enable httpd and firewalld services
d. Permit http via firewalld
e. Create an index.html file inside files directory
f. Ensure the index.html file is in webcontent directory on the target
host(s)
g. Check whether the web server is accessible from the control node
using curl
command.
web_pkg: httpd
firewalld_pkg: firewalld
web_service: httpd
firewall_service: firewalld
rule: http
yum:
name:
- “{{ web_pkg }}”
- “{{ firewall_pkg }}”
service:
name: “{{ web_service }}”
state: started
enabled: true
Managing Secrets
Ansible may need access to sensitive data such as passwords or API keys in
order to configure managed hosts.
Normally, this information might be stored as plain text in inventory variables
or other Ansible files.
In that case, however, any user with access to the Ansible files or a version
control system which stores the Ansible files would have access to this
sensitive data. This poses an obvious security risk.
Ansible Vault, which is included with Ansible, can be used to encrypt and
decrypt any structured data file used by Ansible .
To use Ansible Vault, a command-line tool named ansible-vault is used to
create, edit, encrypt,decrypt, and view files.
The cipher used to protect files is AES256 in recent versions of Ansible, but files
encrypted with
older versions may still use 128-bit AES.
Managing Facts
Ansible facts are variables that are automatically discovered by Ansible on a
managed host.
Facts contain host-specific information that can be used just like regular
variables in plays, conditionals,loops, or any other statement that depends on
a value collected from a managed host.
Some of the facts gathered for a managed host might include:
To use the template module, use the following syntax. The value associated with the
src key
specifies the source Jinja2 template, and the value associated with the dest key
specifies the file to be created on the destination hosts.
Using Loops
Jinja2 uses the for statement to provide looping functionality. In the following
example, the user
variable is replaced with all the values included in the users variable, one value per
line.
Task : Create a template file that your playbook will use to install a customized
Message Of the Day file(/etc/motd) on each Managed Host.
The following example tests whether the my_service variable has a value. If it does,
the value of my_service is used as the name of the package to install. If the
my_service variable is not defined, then the task is skipped without an error.
Testing Multiple Conditions
when: ansible_distribution == “Redhat” or ansible_distribution == “Fedora”
when: ansible_distribution_version == “7.6” and ansible_kernel == “3.10.0-
327.el7.x86_64”
when:
ansible_distribution_version == “7.6”
ansible_kernel == “3.10.0-327.el7.x86_64”
COMBINING LOOPS AND CONDITIONAL TASKS
In the following example, the mariadb-server package is installed by the yum module
if there is
a file system mounted on / with more than 300 MB free.
The ansible_mounts fact is a list of dictionaries, each one representing facts
about one mounted file system.
The following playbook restarts the httpd service only if the postfix service is running:
Task 1:
Implement Ansible conditionals using when keyword.
Implement task iteration using the loop keyword in conjunction with
conditionals
Create a playbook called playbook.yml which contains a play with 2 tasks. The first
task installs the MariaDB required packages and the second task ensures that
MariaDB service is running.
Update the first task in such a way so that the package gets installed only if the
managed host is having the operating system as Redhat Enterprise Linux
Implementing Handlers
Ansible modules are designed to be idempotent
Sometimes when a task does make a change to the system, a further task
may need to
be run.For example, a change to a service's configuration file
(httpd.conf) may then require that the service be reloaded so that the
changed configuration takes effect.
Handlers are tasks that respond to a notification triggered by other tasks
Tasks only notify their handlers when the task changes something on a
managed host.
Each handler has a globally unique name and is triggered at the end of a
block of tasks in a playbook.
If no task notifies the handler by name then the handler will not run.
If one or more tasks notify the handler, the handler will run exactly once after
all other tasks in the play have completed.
Handlers can be considered as inactive tasks that only get triggered when
explicitly invoked using a notify statement.
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.
Handlers normally run after all other tasks in the play complete. A handler
called by a task in the tasks part of the playbook will not run until all tasks
under tasks have been processed.
mkfs.xfs /dev/vg1/lv1
mount -t xfs /dev/vg1/lv1 /data
Ansible Roles
Automating Linux Administration Tasks using Ansible
1. Install & Configure Ansible on control node. Create ansible.cfg and inventory
file.
2. Ad Hoc command ⇒ Create repository
3. Install package and package group
4. Install role using Ansible Galaxy
5. Create and use a role
6. Manage LVM
7. Modify file content
8. Manage web content
9. Manage Ansible Vault
10. User and Group Management
11. Jinja2 template