DevOps Ebook Final
DevOps Ebook Final
DevOps Ebook Final
DevOps
d e p l oy
e
Cod
Pl
an
o p e r a te
se
lea
re
Build
Monitor
Test
Table of Contents
Starting the DevOps Journey Using Cucumber and Selenium.................................4
An Introduction to Ansible......................................................................................15
Ansible Deployment of LAMP and WordPress.........................................................23
Using Ansible to Deploy Cacti for Monitoring..........................................................34
Ansible Deployment of RabbitMQ...........................................................................47
Deploying Graphite Using Ansible...........................................................................55
Ansible Deployment of Jenkins...............................................................................62
Ansible Build VM for Erlang/OTP...........................................................................70
Using Docker with Ansible......................................................................................79
Provisioning with Ansible........................................................................................87
Using Ansible to Deploy a Piwigo Photo Gallery......................................................98
Deploying Graylog Using Ansible..........................................................................110
Ansible deployment of Nginx with SSL..................................................................122
Ansible Deployment of the Aerospike NoSQL Database........................................134
Ansible Deployment of Elovation...........................................................................144
Ansible Deployment of Nginx to Serve Static Files ................................................154
Using Ansible with the Security TechnicalImplementation Guide (STIG)..............164
Ansible Deployment of Consul..............................................................................174
Ansible Deployment of Monit................................................................................185
Ansible Deployment of Sensu and Uchiwa............................................................199
Ansible Deployment of Bugzilla.............................................................................211
Hardening of Parabola..........................................................................................223
Using Ansible to Build GNU Guile.........................................................................234
Configuring a PostgreSQL Master- Slave Setup Using Ansible..............................241
Using Ansible to Set Up a Load Balancer..............................................................252
Printed, published and owned by Ramesh Chopra. Published from D-87/1, Okhla Industrial Area, Phase I, New
Delhi 110020. Copyright © 2019. All content in this book, except for interviews, verbatim quotes, or unless otherwise
explicitly mentioned, will be released under Creative Commons Attribution-NonCommercial 3.0 Unported License.
Refer to http://creativecommons.org/licenses/by-nc/3.0/ for a copy of the licence. Although every effort is made to
ensure accuracy, no responsibility whatsoever is taken for any loss due to publishing errors. The content published
in this book was first published in the print edition of Open Source For You Magazine. Disputes, if any, will be
settled in a New Delhi court only.
4|
Chapter 1
It is often said that continuous change is the law of the universe and the
same is true in the software industry. We have seen a variety of software
development models, starting from Waterfall, V and spiral models to the
incremental option. All these models have different requirements and
guidelines and suit different scenarios. These days, most organisations
have embraced the Agile methodology for software development.
The Agile method of developing software and applications focuses
on delivering high quality products frequently and consistently,
> > #Y +
the differences between the Waterfall and Agile software development
approaches.
You can see that the Waterfall model can cause overshooting in time
and resources, which can lead to huge losses to the company in terms
$ $ > # Y
adopting the Agile model. There are other reasons too, for choosing this
model, some of which are listed below.
Client engagement: In the Agile model, the client is engaged in the
software development process at every step — before, during and
after the sprint. This helps the development team to understand
> [ > $>$ <
software can be developed and delivered in less time.
Transparency: Since the client is actively involved in all the sprint
activities, ranging from feature prioritisation and planning to
" >
the client.
Chapter 1: Starting DevOps Cucumber and Selenium | 5
4. Cycle: If all the features are completed and tested successfully, then
the cycle stops; otherwise, additional sprints are planned to carry out
the remaining work.
Develop
Agile me
nt
IT Operations
n ce
ra
su
As
ty
ali
Qu
Figure 1: Agile and DevOps complement each other Figure 2: Wall of confusion between the development
with the support of the QA and IT operations teams and operations teams
Chapter 1: Starting DevOps Cucumber and Selenium | 7
Now, let’s look at how we can integrate Cucumber with Selenium for
automated testing in DevOps.
The prerequisites are any IDE (I will be taking Eclipse Neon for tutorial
10 | Chapter 1: Starting DevOps Cucumber and Selenium
Figure 3: The file hierarchy in the Figure 4: Methods’ skeleton being generated by Cucum-
project will look like this ber by parsing the feature file
package cucumberTest;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(
features = “src/resources/Files/testCase.feature”,
)
@cucumber
Scenario Outline:
Given <required> browser is opened
When <url> is opened
And <keyword> is searched in search box
And browser is closed
Examples:
| required | url | keyword |
| “chrome” | “http://www.google.com” | “DevOps” |
12 | Chapter 1: Starting DevOps Cucumber and Selenium
5. Now run your runner > "
methods being auto generated in the console output of Eclipse for
each test step in the feature # Y > > $ "
that Cucumber reads test steps from your feature >
for the corresponding method in the package mentioned in the glue
option of the runner # Y
arguments to the methods, to make use of them while scripting.
So you can see how beautifully Cucumber has taken care of every
minute detail while designing this framework.
6. Now copy the following code in the TestCase.java:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
Figure 5: Output of the script depicting one scenario and five steps being passed
RELEASE PIPELINE
Figure 6: Complete release pipeline with CI/CD tools implemented (Image courtesy: Pinterest)
@Then(“^browser is closed$”)
public void browser_is_closed() throws Throwable {
driver.close();
'# > > runner >
$" >> > #
8. Once execution is complete, you can see the execution status of
the steps and scenarios in the console as shown in Figure 5.
> >" > > "
14 | Chapter 1: Starting DevOps Cucumber and Selenium
Chapter 2
An Introduction to Ansible
With this article, we begin a new series on DevOps, starting out
with Ansible, which helps you to build a strong foundation. As
the Ansible website proclaims, proudly, “Deploy apps. Manage
systems. Crush complexity.”
Installation
You can install Ansible using your GNU/Linux distribution package
manager.
On Fedora, you can use Yum to install Ansible, as follows:
Q 6
Q 6
16 | Chapter 2: An Introduction to Ansible
You can then install the software using the following commands:
Q 6
Q 6
Q 6Y
The latest Ansible version 2.2 (as of date) is what we will use in
this article. Ansible is also available for BSD variants, Mac OS X, and
Windows. You are encouraged to refer to the Ansible documentation for
more information.
Virtualisation
> " > > "#
Instead of using bare metal machines, you can create multiple virtual
machines (VMs) on your system. Lots of free and open source software
(FOSS) virtualisation software is available.
QEMU is a machine emulator and virtualiser. It can also use host CPU
support to run guest VMs for better performance. It is written by Fabrice
Bellard, and released under the GNU General Public License (GPL). You
> ?* = $ >"" X
Q 6YZ
$ lscpu
Chapter 2: An Introduction to Ansible | 17
Architecture: x86_64
62 %XLK6 6
Byte Order: Little Endian
CPU(s): 4
62 % X6L
2 % XK
2 % XK
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 78
X 2%2%6KK"L
Stepping: 3
XKK"L8
#XK"
X"
BogoMIPS: 4801.00
X6#
8XLK7
8XLK7
KXK7
LXLK7
2 %X6L
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
! L #'# K 5
nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl
xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl
!# K L '#8# V8 VK#K !
popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch
V V +!# 5 ! ' V 8!#K
K ! # # # ! # !# !8
xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp
The version of Ansible used for this article is given below:
If you have the sshd daemon running on your local machine, you
can use Ansible to test it. For example, a ping test on the localhost is
shown below:
You can also check how long the system has been up and running
using the following commands:
“ansible_all_ipv6_addresses”: [
'XX'KX''X'X8
''XXX'8X'XKL
],
“ansible_architecture”: “x86_64”,
V V X &8K&K8
V V! X -28"K%
“ansible_cmdline”: {
4 V-X &!6#6
“cryptdevice”: “/dev/sda1:cryptroot”,
“quiet”: true,
“root”: “/dev/mapper/cryptroot”,
“rw”: true
....
8K"8"8KK"K
ubuntu
You can now do a ping test from the host to the Ubuntu VM using
the following command sequence for the user ‘xetex’:
To avoid prompting for the password, you can add the localhost
public SSH key to the VM, as follows:
& && 6 56X XY'52 % X && &" &
id_rsa.pub”
Chapter 2: An Introduction to Ansible | 21
& && 6 56X X + +52 %
out any that are already installed
& && 6 56X X852 % 66'5
prompted now it is to install the new keys
# # H +X
Now try logging into the machine, with ssh xetex@ubuntu and check
to make sure that only the key(s) you wanted were added.
You can now issue the following command to get the same result:
You can now try the earlier Ansible commands on the target
Ubuntu VM as illustrated below:
Y8KXLKXYK8
Q 6
ubuntu | SUCCESS => {
“ansible_facts”: {
“ansible_all_ipv4_addresses”: [
8K"8"8KK"K
],
“ansible_all_ipv6_addresses”: [
''KXXLX''X''X8KL
],
“ansible_architecture”: “x86_64”,
V V X &8&K8
V V! X 8"8"86K88KKV8K6
“ansible_cmdline”: {
4 V-X & &!6L"8"686
“quiet”: true,
“ro”: true,
X 'LKK666L68KLKLK'
“splash”: true,
“vt.handoff”: “7”
…
| 23
Chapter 3
Ansible Deployment
of LAMP and WordPress
This is the second article in the DevOps series, and covers the installation of
a LAMP stack and WordPress, using Ansible.
Installing Linux
?* = =& " "#
An Ubuntu 15.04 image runs as a guest OS using KVM/QEMU. Ansible
is installed on the host system using the distribution package manager.
You should be able to issue commands from Ansible to the guest OS.
For example:
The /etc/hosts $ #
8K"8"8KK"K
On the host system, we will create a project for our playbooks. It has
the following directory structure:
24 | Chapter 3: Ansible Deployment of LAMP and WordPress
ansible/inventory/kvm/
& 5 & &
/playbooks/admin/
Installing Apache
j > j
system. Let’s then create a
the following content:
666
6X + !
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [web]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6 K
6+ V'X
port: 80
On the Ubuntu guest system, the playbook runs apt-get update and
then installs the apache2 >- # Y - $
has started, and is listening on port 80. Open a terminal, enter the
ansible/ folder, and execute the playbook as shown below:
Y _[ " $ $ _==[ #
You can increase the level of verbosity in the Ansible output by passing
_[ $ ansible-playbook command. The more number
of times ‘v’ occurs, the greater is the verbosity level.
If you now open http://192.168.122.250, you should be able to see
the default Apache2 index.html page as shown in Figure 1.
The next step is to install the MySQL database server. The
corresponding playbook is provided below:
666
6X 5Y¤ !
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [database]
tasks:
6X ' + 5
apt:
update_cache: yes
6X 5Y¤
package:
X
state: latest
with_items:
65 Z6 !
65 Z6
6 5 65 Z
6XY !
26 | Chapter 3: Ansible Deployment of LAMP and WordPress
service:
name: mysql
state: started
6+ V'X
port: 3306
65 ZV X
name: guest
+X¥94-8 L884K4KH
encrypted: yes
!X¥9"9XH
state: present
You can compute the hash for a password from the MySQL client,
as shown below:
¦6666666666666666666666666666666666666666666¦
1 row in set (0.00 sec)
Installing PHP
"" $ X =
Preprocessor (a recursive acronym). Although we have used PHP5 in this
example, it is recommended that you use the latest PHP for security
reasons. The Ansible playbook for installing PHP is given below:
666
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
28 | Chapter 3: Ansible Deployment of LAMP and WordPress
tags: [web]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6
6 65 Z
Installing WordPress
j # Y
complete playbook is as follows:
666
6XY
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [database]
vars:
Chapter 3: Ansible Deployment of LAMP and WordPress | 29
j > $ j
target installation path. After updating the software repository, a database is
created for the WordPress application. The download and target directories
are created on the guest system, before actually downloading the latest
j > # > >
settings are updated. Although we explicitly specify the password here, the
recommended practice is to store the encrypted passwords in an Ansible
$> " -# : $ > :
" > # $ >" >
Web server is restarted. An execution run of the playbook is shown below:
+ "567
SUDO password:
PLAY [Setup Wordpress] ********************************************************
*
Y7? I999999999999999999999999999999999999999999999999999999999999999999
*
ok: [ubuntu]
Y7? ' + 5I999999999999999999999999999999999
*
changed: [ubuntu]
Y7? '+ I9999999999999999999999999999999999999999
*
changed: [ubuntu]
Y7? + 5I999999999999999999999999999
ok: [ubuntu]
Y7? 5I999999999999999999999999999999
changed: [ubuntu]
Y7? + + I9999999999999999999999999999
ok: [ubuntu]
Y7?-# &!&+++& I99999999999999999999999999999
changed: [ubuntu]
Y7? 5+ 66 " + 6" I999999999999999999999999999999
changed: [ubuntu]
Y7? I999999999999999
X? I£2 H# HXH VVHH HX
H+ H%
X? I£2 H# HXH VHH HXH H%
X? I£2 H# HXH +VHH HXH '5H%
Y7? K !I9999999999999999999999999999999
changed: [ubuntu]
PLAY RECAP **************************************************
ubuntu : ok=10 changed=7 unreachable=0 failed=0
666
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [web]
vars:
wordpress_dest: “/var/www/html”
tasks:
6X + '
X
X + V &+
state: absent
6X
mysql_db:
name: wordpress
state: absent
666
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [web]
tasks:
6X
package:
X
state: absent
with_items:
6 65 Z
Chapter 3: Ansible Deployment of LAMP and WordPress | 33
6
666
6X 5Y¤
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [database]
tasks:
6XY !
service:
name: mysql
state: stopped
6X 5Y¤
package:
X
state: absent
with_items:
6 5 65 Z
65 Z6
65 Z6 !
666
6X + !
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [server]
s tasks:
6XY + !
service:
X K
state: stopped
6X K
package:
X
state: absent
with_items:
6 K
Chapter 4
Setting up Cacti
We will use a CentOS 6.8 virtual machine (VM) running on KVM to set
up Cacti. Just for this demonstration, we will disable SELinux. You will
need to set the following in and reboot the VM:
SELINUX=disabled
ansible/inventory/kvm/inventory
ansible/inventory/kvm/group_vars/all/all.yml
ansible_password=password
Add an entry for ‘centos’ in the /etc/hosts > X
8K"8"8KK"
The contents of the all.yml for use with the playbook are as follows:
666
5 ZV V +V X ! V5 ZV V +V
Vault
Ansible provides the Vault feature, which allows you to store sensitive
$" - > # > %:Y,!
environment variable to the text editor of your choice, as shown below:
$ export EDITOR=nano
666
! V5 ZV V +V X 9KL--L-4K-4L-4-
vault_mysql_user: “cacti”
! V5 ZV +X 8KL
> " $ $ >"" X
Apache
> " > >- $
install is the Apache HTTP server.
666
6X + !
hosts: centos
gather_facts: true
tags: [httpd]
tasks:
6X ' + 5
yum:
X¥9H
update_cache: yes
6+ V'X
port: 80
server is started, and the Ansible playbook waits for the server to listen
on port 80.
tasks:
6X &+
package:
X
state: latest
with_items:
65 Z
65 Z6 !
65Y¤6 5
6 65 Z
6 6
6 6
6 6
6 6!
6
6 6
6 6
6 6
6 6
6 6 6
6 6 6
6
6XY !
service:
name: snmpd
state: started
service:
name: mysqld
state: started
6+ V'X
port: 3306
Cacti
Cacti is available in the EPEL repository for CentOS. The GPG key for
the CentOS repositories is enabled before installing the EPEL repository.
A‘yum update’ is performed and the Cacti package is installed. A Cacti
user is then created in the MySQL database.
6X
hosts: centos
become: yes
become_method: sudo
gather_facts: true
tags: [cacti]
tasks:
6X --5
rpm_key:
5X X&&"' "& & &667-§6--6
state: present
6X§
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: https://dl.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: yes
6X
package:
X
state: latest
with_items:
42 | Chapter 4: Using Ansible to Deploy Cacti for Monitoring
6
Fixing a bug
Y " " #+#'@&# :
to resolve this bug, the mysql_test_data_timezone.sql
imported and the ‘cacti’ user needs to be given the SELECT privilege to
do this.
Chapter 4: Using Ansible to Deploy Cacti for Monitoring | 43
tasks:
6X 5 ZV V V " Z
mysql_db:
state: import
name: mysql
target: /usr/share/mysql/mysql_test_data_timezone.sql
6X !
mysql_user:
name: cacti
append_privs: true
!X¥5 Z" VVXY--H
state: present
Y > > #
6X
hosts: centos
become: yes
become_method: sudo
gather_facts: true
X?I
tasks:
6X '
mysql_db:
name: cacti
state: present
mysql_db:
state: import
name: cacti
X& & && 68""& " Z
6X+
X 66 66 6 66
--Y4Y- 6-
6X
dest: /etc/cron.d/cacti
# X¥Mª2"9%QH
X¥©8H
backrefs: yes
6+ V'X
port: 3306
Chapter 4: Using Ansible to Deploy Cacti for Monitoring | 45
6+ V'X
port: 80
A database called ‘cacti’ is created for the application, and the cacti.
sql " # Y > $
> > # Y >"
HTTP requests for port 80. The periodic cron poller is then enabled in /
etc/cron.d/cacti:
The result
The entire playbook can now be invoked as follows:
It will prompt you for the Vault password, following which all the
Chapter 5
In this fourth article in the DevOps series, we will learn to install RabbitMQ
using Ansible. RabbitMQ is a free and open source message broker system
that supports a number of protocols such as the Advanced Message
Queuing Protocol (AMQP), Streaming Text Oriented Messaging Protocol
(STOMP) and Message Queue Telemetry Transport (MQTT). The software
has support for a large number of client libraries for different programming
languages. RabbitMQ is written using the Erlang programming language
and is released under the Mozilla Public License.
Setting it up
A CentOS 6.8 virtual machine (VM) running on KVM is used for the
installation. Do make sure that the VM has access to the Internet. The
?* = =&
##+#K# Y *$ > $ X
ansible/inventory/kvm/inventory
& 5 & & Z"5
& 5 && 6 Z"5
Also, add an entry for the rabbitmq host in the /etc/hosts
indicated below:
8K"8"8KK"88 Z
Installation
RabbitMQ requires the Erlang environment, and uses the Open Telecom
Platform (OTP) framework. There are multiple sources for installing Erlang
>
provided by RabbitMQ. In this article, we will use the EPEL repository for
installing Erlang.
666
6X ¤ !
hosts: rabbitmq
gather_facts: true
tags: [server]
tasks:
6X --5
rpm_key:
5X X&&"' "& & &667-§6--6
state: present
6X§
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: https://dl.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: yes
service:
X Z6 !
state: started
6+ V'X
XK
Username:
Password:
Login
After importing the EPEL GPG key and adding the EPEL repository to
the system, the yum update command is executed. The RabbitMQ server
and its dependencies are then installed. We wait for the RabbitMQ server
to start and listen on port 5672. The above playbook can be invoked as
follows:
tasks:
6XY
X& && Z&& Z6 ZV
management
6+ V'X
X8K
6X+ 8K
X 66 66 8K6 66
--Y4Y- 6-
The default user name and password for the dashboard are
‘guest:guest’. From your host system, you can start a browser and
open http://192.168.122.161:15672 to view the login page as shown
in Figure 1. The default ‘Overview’ page is shown in Figure 2.
&
We will use a Ruby client example to demonstrate that our installation
$ ! - # Y ! !
be used to install Ruby as shown below:
6X5
hosts: rabbitmq
gather_facts: true
tags: [ruby]
tasks:
6X 5
X K665 ! X&&5 " " 66!65
448KK8L88L44K L -L
6X
X6 Y X&& "!" 6
6X 5
X & & "&!" ¬¬! 56K"K"
6X 5
X 566! £K""
After importing the required GPG keys, RVM and Ruby 2.2.6 are
installed on the CentOS 6.8 VM. The bunny Ruby client for RabbitMQ
is then installed. The Ansible playbook to set up Ruby is given below:
#!/usr/bin/env ruby
require “bunny”
chan = conn.create_channel
queue = chan.queue(“temperature”)
begin
puts “ ... waiting. CTRL+C to exit”
queue.subscribe(:block => true) do |info, properties, body|
!ª5
end
rescue Interrupt => _
conn.close
exit(0)
end
#!/usr/bin/env ruby
require “bunny”
chan = conn.create_channel
queue = chan.queue(“temperature”)
values.each do |v|
chan.default_exchange.publish(v, :routing_key => queue.name)
end
Y ! ! "
conn.close
Chapter 5: Ansible Deployment of RabbitMQ | 53
As soon as you start the consumer, you will get the following output:
$ ruby consumer.rb
... waiting. CTRL+C to exit
You can then run the producer.rb script that writes the values to the
queue:
$ ruby producer.rb
The received values at the consumer side are printed out as shown
below:
$ ruby consumer.rb
Uninstall
It is good to have an uninstall script to remove the RabbitMQ server for
administrative purposes. The Ansible playbook for the same is available
in the playbooks/admin folder and is shown below:
666
6X ¤ !
hosts: rabbitmq
gather_facts: true
tags: [remove]
tasks:
6XY ¤ !
service:
X Z6 !
state: stopped
6X Z
package:
X
state: absent
with_items:
6 Z6 !
Chapter 6
Setting it up
A CentOS 6.8 virtual machine (VM) running on KVM is used for the
installation. Please make sure that the VM has access to the Internet.
Y ?* = =&
is 2.2.1.0. The ansible* $ > $ X
ansible/inventory/kvm/inventory
& 5 & & "5
& 5 && 6 "5
Also, add an entry for the graphite host in the /etc/hosts
indicated below:
8K"8"8KK"8K
Graphite
The playbook to install the Graphite server is given below:
666
6X ' +
hosts: graphite
gather_facts: true
tags: [graphite]
tasks:
6X --5
rpm_key:
5X X&&"' "& & &667-§6--6
state: present
6X§
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: https://dl.fedoraproject.org/pub/epel/$releasever/$basearch/
gpgcheck: yes
j " - $ = >- $ =
$ >- # Y _
web’ package is then installed using Yum. The above playbook can be
invoked using the following command:
Chapter 6: Deploying Graphite Using Ansible | 57
A backend database is required by Graphite. By default, the SQLite3
database is used, but we will install and use MySQL as shown below:
6X 5Y¤
hosts: graphite
become: yes
become_method: sudo
gather_facts: true
tags: [database]
tasks:
6X
package:
X
state: latest
with_items:
65 Z
65 Z6 !
65Y¤6 5
6 #6 5
6+ V'X
port: 3306
name: graphite
state: present
6X 5
X& && 5 K"& 6 & &" 5 5
66
6X+
X 66 66 6 66
--Y4Y- 6-
6X
X
X& & &'"& 6+"'
' X¥ª K"KH
X¥+'H
6XY !
service:
name: httpd
state: started
6X
hosts: graphite
become: yes
become_method: sudo
gather_facts: true
tags: [carbon]
tasks:
6X +
package:
X
state: latest
with_items:
6 5 6
6 5 6+
6XY 6
X& & "&6
Uninstalling Graphite
An uninstall script to remove the Graphite server and its dependency
60 | Chapter 6: Deploying Graphite Using Ansible
666
6X
hosts: graphite
gather_facts: true
tags: [remove]
tasks:
6XY 6 !
X& & "&6
6X +
package:
X
state: absent
with_items:
6 5 6+
6 5 6
6XY !
service:
name: httpd
state: stopped
Chapter 7
In this article, we will install Jenkins using Ansible and set up a continuous
integration (CI) build for a project that uses Git. Jenkins is free and open
source automation server software that is used to build, deploy and
automate projects. It is written in Java and released under the MIT licence.
There are a number of plugins available to integrate Jenkins with other
tools such as version control systems, APIs and databases.
Setting it up
A CentOS 6.8 virtual machine (VM) running on KVM will be used for the
installation. Internet access should be available from the guest machine.
Y ?* = =&
is 2.3.0.0. The ansible/ folder > $ X
ansible/inventory/kvm/inventory
& 5 & & "5
& 5 && 6 "5
An entry for the Jenkins host is also added to the /etc/hosts
indicated below:
Chapter 7: Ansible Deployment of Jenkins | 63
8K"8"8KK"8K
Installation
The playbook to install the Jenkins server on the CentOS VM is given
below:
666
6X ° ' +
hosts: jenkins
gather_facts: true
become: yes
become_method: sudo
tags: [jenkins]
tasks:
6X ' + 5
yum:
X¥9H
update_cache: yes
6X °
package:
X
64 | Chapter 7: Ansible Deployment of Jenkins
state: latest
with_items:
6
6X+
X 66 66 6 66
--Y4Y- 6-
6+ V'X
port: 8080
You can now open http://192.168.122.120:8080 in the browser on the
> - # Y j "
enter the initial administrator password from /var/lib/jenkins/secrets/
initialAdminPassword to proceed further. This is shown in Figure 1.
The second step is to install the plugins. For this demonstration, you
can select the ‘Install suggested plugins’ option, and later install any of
the plugins that you require. Figure 2 displays the selected option.
After you select the ‘Install suggested plugins’ option, the plugins will
get installed as shown in Figure 3.
An admin user is required for managing Jenkins. After installing the
plugins, a form is displayed for you to enter the user name, password,
" " $ " # > $
shown in Figure 4.
Once the administrator credentials are stored, a ‘Jenkins is ready!’
page will be displayed, as depicted in Figure 5.
You can now click on the ‘Start using Jenkins’ button to open the
default Jenkins dashboard shown in Figure 6.
The next step is to add the GitHub repo to the Repositories section.
The GitHub HTTPS URL is provided as we are not going to use any
credentials in this example. By default, the master branch will be built.
The form to enter the GitHub URL is shown in Figure 8.
- ]> > > > >
simply invoke make to build the project. The Execute shell option is chosen
in the Build step, and the make clean; make command is added to the Build
step, as shown in Figure 9.
From the left panel, you can click on the Build Now link for the project
to trigger a build. After a successful build, you should see a screenshot
Chapter 7: Ansible Deployment of Jenkins | 69
Uninstalling
An uninstall script to remove the Jenkins server is available in the
playbooks/admin folder. It is given below for reference:
666
666
6X °
hosts: jenkins
gather_facts: true
become: yes
become_method: sudo
tags: [remove]
tasks:
6XY ° !
service:
name: jenkins
state: stopped
Chapter 8
Setting it up
A CentOS 6.8 virtual machine (VM) running on KVM is used for the
installation. Internet access should be available from the guest machine.
The VM should have at least 2GB of RAM allotted to build the Erlang/
OTP documentation. The Ansible version used on the host (Parabola
?* = =& #@#K#K# Y ansible/ folder contains the
$ X
ansible/inventory/kvm/inventory
Chapter 8: Creating a Virtual Machine for Erlang/OTP | 71
An entry for the erlang host is also added to the /etc/hosts
indicated below:
8K"8"8KK"8
vars:
-V-Y X V V! ' 2¥8"H%
-V X V!" -& &
-V X -V &-V-Y
-YVY--V X -V & & & V !
The ERL_DIR variable represents the directory where the tarball will
be downloaded, and the ERL_TOP $ >
location containing the source code. The path to the test directory from
where the tests will be invoked is given by the TEST_SERVER_DIR variable.
Erlang/OTP has mandatory and optional package dependencies.
72 | Chapter 8: Creating a Virtual Machine for Erlang/OTP
tasks:
6X ' + 5
become: true
yum:
X¥9H
update_cache: yes
6X
X -V
with_items:
6 V
environment:
-V X -V
6X-#
X -YVY--V ¬¬-V &&6 6
6 6 V 6
You need to verify that the tests have passed successfully by checking
the $ERL_TOP/release/tests/test_server/index.html page in a browser.
A screenshot of the test results is shown in Figure 1.
The built executables and libraries can then be installed on the system
using the make install command. By default, the install directory is /
usr/local.
6X
X -V
with_items:
6
become: true
environment:
-V X -V
6X
X -V ¬¬
environment:
-V X -V
V -X -V &'
V YX 6²#K
6X
become: true
X -V ¬¬ 6
environment:
-V X -V
Y ! } > FOP_OPTS environment
variable. The complete playbook to download, compile, execute the tests,
and also generate the documentation is given below:
666
6XY -
hosts: erlang
gather_facts: true
tags: [release]
vars:
-V-Y X V V! ' 2¥8"H%
-V X V!" -& &
-V X -V &-V-Y
-YVY--V X -V & & & V !
tasks:
6X ' + 5
become: true
yum:
X¥9H
update_cache: yes
remote_src: yes
6X
X -V
with_items:
6 V
environment:
-V X -V
6X-#
X -YVY--V ¬¬-V &&6
6 6 6 V 6
6X
X -V
with_items:
6
become: true
environment:
-V X -V
6X
X -V ¬¬
environment:
-V X -V
V -X -V &'
V YX 6²#K
6X
become: true
X -V ¬¬ 6
environment:
-V X -V
vars:
GIT_VERSION: “otp”
-V X V!" -& &
-V X -V &V-Y
-YVY--V X -V & & & V !
tasks:
6X ' + 5
become: true
yum:
X¥9H
update_cache: yes
The ‘git’ and ‘autoconf’ software packages are required for downloading
and building the sources from the Git repository. The Ansible Git module
is used to clone the remote repository. The source directory provides an
otp_build script to create the script. You can invoke the above
playbook as follows:
Chapter 9
Setting it up
Y " ?* =
=& #@#K#K# : >>
system. The ansible/ $ > $ X
Installation
The following playbook is used to install Docker on the host system:
666
6XY
80 | Chapter 9: Using Docker with Ansible
hosts: localhost
gather_facts: true
become: true
tags: [setup]
tasks:
6X ' + 5
pacman:
update_cache: yes
6 !X
name: docker
state: started
6X 6+
docker_container:
X6+
X5&6+
changed: [localhost]
Y7? !I9999999999999999999999999999999999999999999999
ok: [localhost]
Q 6+
' ³
An example
A deep learning (DL) Docker project is available (https://github.com/
! with support for frameworks, libraries and software
tools. We can use Ansible to build the entire DL container from the
source code of the tools. The base OS of the container is Ubuntu 14.04,
and will include the following software packages:
TensorFlow
Caffe
Theano
Keras
Lasagne
Torch
iPython/Jupyter Notebook
Numpy
SciPy
Pandas
Scikit Learn
Matplotlib
OpenCV
The playbook to build the DL Docker image is given below:
6X4 6
hosts: localhost
gather_facts: true
become: true
X? 6I
vars:
V4 V X & &6
V 7-V-X 5&6
tasks:
6X +6
git:
X X&& "& &6"
X V4 V
6X4+
docker_image:
X V4 V
X V 7-V-
X "
buildargs:
Chapter 9: Using Docker with Ansible | 83
Depending on the CPU and RAM you have, it will take a considerable
amount of time to build the image with all the software. So be patient!
vars:
V 7-V-X 5&6
tasks:
6X '° 5
docker_container:
X 66
X V 7-V-X
state: started
command: sh run_jupyter.sh
Y %>- = &&&& >
need to specify the same in the above docker_container > #
After you run the playbook, using the ‘docker ps’ command on the host
system, you can obtain the container ID as indicated below:
84 | Chapter 9: Using Docker with Ansible
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
'85&6X V 5 " 88
& & 66
Logout
Name
Split on underscores
Smoothing
0.6
Horizontal Axis
RELATIVE WALL
Runs
./log
Figure 2: TensorBoard
You can now log in to the running container using the following
command:
Q #6 &&
Chapter 9: Using Docker with Ansible | 85
> _ $>[ >"" > :
(‘172.17.0.2’ in this case), and then open http://172.17.0.2:8888 in a
browser on your host system to see the Jupyter Notebook. A screenshot
is shown in Figure 1.
TensorBoard
TensorBoard consists of a suite of visualisation tools to understand the
TensorFlow programs. It is installed and available inside the Docker
container. After you log in to the Docker container, at the root prompt,
you can start TensorBoard by passing it a log directory as shown below:
ª 66"&
6X '
hosts: localhost
gather_facts: true
become: true
tags: [facts]
vars:
V 7-V-X 5&6
tasks:
6X '
docker_image_facts:
X V 7-V-X
“Architecture”: “amd64”,
“Author”: “Sai Soundararaj <[email protected]>”,
X
“Cmd”: [
“/bin/bash”
],
“Env”: [
& & & &X& &''&& X& &''& 5 X&
usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”,
“CAFFE_ROOT=/root/caffe”,
“PYCAFFE_ROOT=/root/caffe/python”,
§ & &''& 5 X
V& &" & &&"8&´"& &" & &
&"8&´& "& & & & &&"8&´"& & & &
&&"8&´& ""&´"& & & & & 6K"8"6
8&´"& && &&"8&´"& && &&"8&´& "
lua”,
V& & & &&´" & &" &&&"8&´" &
& & &&&"8&´" "&´" & &&&&"8&´" & &
local/lib/lua/5.1/loadall.so”,
V4§V& & & &X
§ V4§V& & & &X
],
“ExposedPorts”: {
& X
& X
X K8668L8X8LX8"KK8Kµ
“DockerVersion”: “1.11.1”,
“Os”: “linux”,
You are encouraged to read the ‘Getting Started with Docker’ user
guide available at http://docs.ansible.com/ansible/latest/guide_docker.
html to know more about using Docker with Ansible.
| 87
Chapter 10
Setting it up
Let’s create an Ansible playbook for the ‘Get started with Docker
Compose’ composetest example available at https://docs.docker.com/
compose/gettingstarted/. The Ansible version used on the host system
=& ##K#K# %>-
>->" # ^
at https://docs.docker.com/engine/ installation/linux/docker-ce/
ubuntu/#install-using-the-repository to install Docker CE. You can
>->" Y >- " X
composetest/app.py
&6 "5
&
composetest/provision.yml
composetest/requirements.txt
88 | Chapter 10: Using Docker with Ansible
app = Flask(__name__)
2 H H L%
" 2¥&H%
def hello():
"2¥ H%
¥³! "©H"' 2 %
if __name__ == “__main__”:
app.run(host=”0.0.0.0”, debug=True)
redis
5 XL"6
ADD . /code
7 &
6Z " #
CMD [“python”, “app.py”]
! X¥KH
services:
Chapter 10: Using Docker with Ansible | 89
web:
build: .
ports:
6 X
redis:
image: “redis:alpine”
ports:
6 LXL
Provisioning
The Python Web application will be running on port 5000, whereas the
! @'# j
the application using the following code:
Q6
Creating composetest_web_1
Creating composetest_redis_1
Attaching to composetest_web_1, composetest_redis_1
V88X 88XX"ª
oO0OoO0OoO0Oo
If you start a browser on the host system and open the URL
http://0.0.0.0:5000, you will see the text from the Flask application. You
can continue to refresh the page making requests to the application, and
you will see the count increasing in the text: ‘Hello World! I have been seen
N times.’ Pressing Ctrl+c in the above terminal will stop the application.
Let’s now create an Ansible playbook to launch these containers:
tasks:
6V !X
project_name: composetest
X
! X¥KH
services:
web:
X 5V&"
ports:
6 X
redis:
image: “redis:alpine”
register: output
6X
var: output
Chapter 10: Using Docker with Ansible | 91
6 X
that:
6 +" V+V8" "
6 " V V8" "
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
03f6f6a3d48f composetest_web “python app.py” 18 seconds ago
8 """X6£& V+V8
'8L X 6 5 """8
8 L& V V8
Scaling
You can use the docker_service Ansible module to increase the number
of Web services to two, as shown in the following Ansible playbook:
tasks:
6V !X
project_src: “/home/guest/composetest”
scale:
+XK
register: output
6X
92 | Chapter 10: Using Docker with Ansible
var: output
The execution of the playbook will create one more Web application
server, and this will listen on Port 5001. You can verify the running
containers as follows:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
8LL V+ 5 " 5
"""X86£& V+VK
LL X 6 5 """88 8
"""XL6£L& V V8
03f6f6a3d48f composetest_web “python app.py” 55 seconds ago Up 54
"""X6£& V+V8
You can open another tab in the browser with the URL http://
localhost:5001 on the host system, and the text count will continue to
increase if you keep refreshing the page repeatedly.
Cleaning up
You can stop and remove all the running instances. First, stop the newly
created Web application, as follows:
You can use the following Ansible playbook to stop the containers
that were started using Docker compose:
6XY ³
hosts: localhost
connection: local
become: true
gather_facts: true
tags: [stop]
tasks:
6V !X
project_name: composetest
V X 5V&"
state: absent
You can also verify that there are no containers running in the system,
as follows:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
ª696X5696
# vi: set ft=ruby :
j " " >
bit Ubuntu image is downloaded, started and the Ansible playbook is
executed after the instance is launched. The contents of the playbook.
yml $ X
666
6 X
become: true
gather_facts: no
pre_tasks:
6X 5 K
Chapter 10: Using Docker with Ansible | 95
tasks:
6X
apt: update_cache=yes
The minimal Ubuntu machine has Python 3 by default, and the Ansible
that we use requires Python 2. Hence, we install Python 2, update the APT
repository and install the Apache Web server. A sample debug execution
of the above playbook from the test directory is given below:
test_vm:
test_vm: Inserting generated public key within guest...
PLAY ********************************************************
> " >
Virtual Machine Manager to see the instance running. You can also log
in to the instance using the following command from the test directory:
$ vagrant ssh
Chapter 10: Using Docker with Ansible | 97
$ " > :
the % command. You can then open a browser on the host system
with this IP address to see the default Apache Web server home page, as
shown in Figure 1.
98 |
Chapter 11
Linux
The Piwigo installation will be on an Ubuntu 15.04 image running as a
, *# Y " ?* =
=& "# "
distribution package manager. The version of Ansible used is:
8K"8"8KK"
You should be able to issue commands from Ansible to the guest OS.
For example:
ansible/inventory/kvm/
& 5 & &
/playbooks/admin/
V 8K"8"8KK" V V # #
ansible_password=pass
Apache
Y > j
VM. The Ansible playbook for the same is as follows:
become_method: sudo
gather_facts: true
tags: [web]
tasks:
6X ' + 5
apt:
update_cache: yes
6+ V'X
port: 80
Y7?+ V'I999999999999999999999999999999999999999999999
ok: [ubuntu]
PLAY RECAP **************************************************
XK'
Chapter 11: Using Ansible to Deploy a Piwigo Photo Gallery | 101
< $ >-
version 5.0. As the second step, you can install the same using the
following Ansible playbook:
tags: [database]
tasks:
6X ' + 5
apt:
update_cache: yes
6X 5Y¤
package:
X
state: latest
with_items:
65 Z6 !
65 Z6
6 5 65 Z
6+ V'X
port: 3306
Y Y $ <
packages are then installed. The database server is started, and the Ansible
playbook waits for the server to listen on port 3306. For this example, a
guest database user account with osfy as the password is chosen for the
gallery Web application. In production, please use a stronger password.
The hash for the password can be computed from the MySQL client as
indicated below:
¦6666666666666666666666666666666666666666666¦
94-8 L884K4K
¦6666666666666666666666666666666666666666666¦
1 row in set (0.00 sec)
Also, the default MySQL root password is empty. You should change
it after installation. The playbook can be invoked as follows:
PHP
Piwigo is written using PHP (PHP Hypertext Preprocessor), and it requires
at least version 5.0 or later. The documentation website recommends
version 5.2. The Ansible playbook to install PHP is given below:
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [php]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6
6 65 Z
Update the software package repository, and install PHP5 and the
" < >> >- # Y - $
this can be invoked as follows:
66 67
$
Y > # Y -
for this is given below:
6XY +
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [piwigo]
vars:
piwigo_dest: “/var/www/html”
tasks:
6X ' + 5
apt:
update_cache: yes
service:
X K
state: restarted
Backup
The Piwigo data is present in both the installation folder and in the
MySQL database. It is thus important to periodically make backups,
> > $ < # Y
following Ansible playbook creates a target backup directory, makes a
tarball of the installation folder, and dumps the database contents to
a .sql # Y > " " "# Y >-
folder can be rsynced to a different system or to secondary backup.
6X4 +
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [backup]
vars:
piwigo_dest: “/var/www/html”
Chapter 11: Using Ansible to Deploy a Piwigo Photo Gallery | 107
tasks:
6X 5
X
X +V &5&
state: directory
6X4 '
archive:
X +V &5& +
X +V &5& & +6 6 V V
" " "K
Y >- > $" => -
are piwigo-1510053932.sql and piwigo-backup-1510053932.tar.bz2.
Cleaning up
You can uninstall the entire Piwigo installation using an Ansible playbook.
Y # "
followed by PHP, MySQL and Apache. A playbook to do this is included
in the playbooks/admin folder and given below for reference:
666
6X +
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [uninstall]
vars:
piwigo_dest: “/var/www/html”
108 | Chapter 11: Using Ansible to Deploy a Piwigo Photo Gallery
tasks:
6X +'
X
X +V &5
state: absent
with_items:
6 K
Chapter 12
Graylog is a free and open source log management software that allows
you to store and analyse all your logs from a central location. It requires
%} >" ? " $"
> $" # Y > "
Elasticsearch. It is written using the Java programming language and
released under the GNU General Public License (GPL) v3.0.
Access control management is built into the software, and you can
create roles and user accounts with different permissions. If you already
have an LDAP server, its user accounts can be used with the Graylog
software. It also provides a REST API, which allows you to fetch data to
build your own dashboards. You can create alerts to take actions based on
the log messages, and also forward the log data to other output streams.
In this article, we will install the Graylog software and its dependencies
using Ansible.
GNU/Linux
An Ubuntu 16.04.3 LTS guest virtual machine (VM) instance will be
used to set up Graylog using KVM/QEMU. The host system is a Parabola
?* = =& "# "
using the distribution package manager. The version of Ansible used is:
8K"8"8KK"K
ansible/inventory/kvm/
& 5 & &
/playbooks/admin/
$<
The Graylog software has a few dependency packages that need to be
< # Y Y >-
666
6X6Z
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [prerequisite]
tasks:
6X ' + 5
apt:
update_cache: yes
Y _[ " $ $ _[ #
> " _[ $ - >
a more verbose output.
=,
%} " $" >
changes. The MongoDB software package that ships with Ubuntu 16.04
is supported by the latest Graylog software. The Ansible playbook to
install the same is as follows:
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [mongodb]
tasks:
6X 4
package:
X6 !
state: latest
6+ V'X
XK8
Y $ >- $ %} > _"
server’. It is installed, and the database server is started. The Ansible
playbook waits for the MongoDB server to start and listen on the default
port 27017. The above playbook can be invoked using the following
command:
Elasticsearch
Elasticsearch is a search engine that is written in Java and released
under the Apache licence. It is based on Lucene (an information retrieval
$ $= > $ # Y elastic.co
website provides .deb packages that can be used to install the same on
Ubuntu. The Ansible playbook for this is provided below:
tasks:
6X5
apt_key:
X X&& ' " "&67-§6
state: present
state: latest
6X
systemd: daemon_reload=yes
6+ V'X
XK
6X Z5
X6²-¥ XK&´ 5H
Q6²-¥ XK&´ 5H
{
X 6L§
“cluster_name” : “elasticsearch”,
“cluster_uuid” : “nuBTSlFBTk6PDGyrfDCr3A”,
“version” : {
“number” : “5.6.5”,
“build_hash” : “6a37571”,
V X K868K6XX8"µ
“build_snapshot” : false,
“lucene_version” : “6.6.1”
X §7+'Y
-
Y $# Y .deb package available from
the graylog2.org > _ [
>- # Y > >
for the ‘admin’ user with a hashed string for the password ‘osfy’. The
Web interface is also enabled with the default IP address of the guest
# Y > # Y -
Graylog is as follows:
Chapter 12: Deploying Graylog Using Ansible | 119
6X 5
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [graylog]
tasks:
6X 5
apt:
X X&& "5K"& & &56K"L6
repository_latest.deb
6X 5
package:
X56 !
state: latest
service:
X56 !" !
state: started
Web interface
You can now open the URL http://192.168.122.25:9000 in a browser on
the host system to see the default Graylog login page as shown in Figure 1.
The user name is ‘admin’ and the password is ‘osfy’. You will then be
taken to the Graylog home page as shown in Figure 2.
The guest VM is a single node, and hence if you traverse to System
-> Nodes, you will see this node information as illustrated in Figure 3.
You can now test the Graylog installation by adding a data source as
input by traversing System -> Input in the Web interface. The ‘random
HTTP message generator’ is used as a local input, as shown in Figure 4.
The newly created input source is now running and visible as a local
input in the Web page as shown in Figure 5.
After a few minutes, you can observe the created messages in the
Search link as shown in Figure 6.
tasks:
6XY 5 !
service:
X56 !" !
state: stopped
package:
X56 !
state: absent
6X 4
package:
X6 !
state: absent
Chapter 13
The default installation on the guest VM does not come with Python2,
and hence you need to install this on the guest machine, manually, as
shown below:
Chapter 13: Ansible Deployment of Nginx with SSL | 123
Q 6
Q 6 5 6
You should add an entry to the /etc/hosts $
VM, as follows:
8K"8"8KK"K
ansible/inventory/kvm/
& 5 & &
/playbooks/admin/
& &
You should now be able to issue commands to the guest OS, using
Ansible. For example:
Installing Nginx
The Nginx software package in Ubuntu can be installed on the guest
" > # Y Y >- $
the Nginx Web server. The Uncomplicated Firewall (UFW) is then used to
enable both HTTP and HTTPS access on the guest OS. The Web server
is then started, and the playbook waits for the server to listen on port
80. The Ansible playbook is provided below for reference:
666
6X #
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [nginx]
tasks:
6X ' + 5
apt:
update_cache: yes
6X #
package:
X
state: latest
with_items:
6#
6X+#
ufw:
rule: allow
name: Nginx Full
state: enabled
6X+#
ufw:
rule: allow
X YY
state: enabled
6XY #
service:
name: nginx
Chapter 13: Ansible Deployment of Nginx with SSL | 125
state: started
6+ V'X
port: 80
The -K option prompts for the sudo password of the Ubuntu user.
You can append multiple -v to the end of the playbook invocation to get
a more verbose output.
If you open a browser on the host system with the URL
http://192.168.122.244, you should see the default Nginx home page
as shown in Figure 1.
gather_facts: true
tags: [ssl]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6
6 5 6
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
V Y!8Y!8"8Y!8"K
ssl_prefer_server_ciphers on;
V -- ¦-YX- ¦-YX-YK¦-- X-YK¦-
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ª YY'+"§
that includes
# the “preload” directive if you understand the implications.
ªVY 6 6Y 5 #6LKY
preload”;
VY 6 6Y 5 #6LKY
V²66 -§
V²6 65 6 ''
server {
128 | Chapter 13: Ansible Deployment of Nginx with SSL
listen 80;
root /var/www/html;
##"#6"
tasks:
6 5X
X""&""& & '6 "'
X& &#& & '6 "'
owner: root
group: root
mode: 0644
6 5X
X""&""& & 6 "'
X& &#& & 6 "'
owner: root
group: root
mode: 0644
6 5X
X""&""& &"
X& &#& 6&"
owner: root
group: root
mode: 0644
Chapter 13: Ansible Deployment of Nginx with SSL | 129
6X #
service:
name: nginx
state: restarted
6+ V'X
port: 443
Q X&&8K"8"8KK"K6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
' 6'5X 6 '
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
+" Z"¶& £
<a href=”http://nginx.com/”>nginx.com</a>.</p>
Validation
> " $ >>- > > >
to ascertain that it still holds good and meets your requirements. A few
= " $ >>- > $" > >
below for reference:
tasks:
6X + ! 5
V X
X& & &  ' "
privatekey_path: /etc/ssl/private/ansible.com.pem
provider: assertonly
You can invoke the above validation checks in the playbook using
the following command:
Uninstalling
An uninstall playbook is provided in the playbooks/admin/uninstall-nginx.
yml ? = j >>
" $ $" X
666
6X #
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [server]
tasks:
6XY + !
service:
name: nginx
state: stopped
6X #
ufw:
rule: deny
name: Nginx Full
state: enabled
package:
X
state: absent
with_items:
6#
To Action From
666666666666
Nginx Full DENY Anywhere
YY 5+
Nginx Full (v6) DENY Anywhere (v6)
YY2!% 5+2!%
Chapter 14
GNU/Linux
A host system running Ubuntu 16.04.3 LTS (Xenial) with Vagrant and
VirtualBox is used to launch three CentOS 6.9 virtual machines, on
Chapter 14: Ansible Deployment of the Aerospike NoSQL Database | 135
which the Aerospike server will be installed and set up. The Vagrant
> X
The three instances are named ‘as1’, ‘as2’ and ‘as3’, and are assigned
private IP addresses that can be accessed from the host system. The
machines are brought up using the following command:
$ vagrant up
ansible/inventory/vbox/
& 5 & &
[nodes]
136 | Chapter 14: Ansible Deployment of the Aerospike NoSQL Database
666
aerospike_edition: “community”
aerospike_version: “latest”
amc_version: 3.6.13
Installing Aerospike
The entire set of playbooks is available in the
aerospike.yml # Y -
the three nodes using Ansible, as shown below:
666
6X
hosts: nodes
become: yes
become_method: sudo
gather_facts: true
tags: [server]
tasks:
6X + 5
X && V &+ 5
6 V' X
Chapter 14: Ansible Deployment of the Aerospike NoSQL Database | 137
6X§
yum: name=* update_cache=yes state=present
6X
X && V & & !V! #V
2¥©" H¥H%¬¬ "&
vars:
V X V 8?¥ !HI?¥ HI
V X V
tasks:
6XY !
command: service aerospike stop
> $ " > > $
the virtual machines, and using the Aerospike Admin (asadm) tool as
illustrated below:
Found 3 nodes
X8"""88XL8"""8LXL8"""8KXL
Admin> exit
?! 8 IQ
tasks:
6 V' X
VX VV 5VV"
with_items:
6
6 5 6!
6X
X 6! V
6XY !2%
shell: sudo service amc start
Y7? I999999999999999999999999999999999999999999999999
ok: [as1]
X? KI
ok: [as3]
Y7? I99999999999999999999999999999999999999
changed: [as1]
X? KI
changed: [as3]
Uninstalling Aerospike
An uninstall playbook is written to stop the services, and uninstalls both
the Aerospike Management Console (AMC) and the Aerospike server, as
follows:
6X
hosts: nodes
become: yes
become_method: sudo
gather_facts: true
tags: [uninstall]
tasks:
6XY !
service:
name: amc
state: stopped
142 | Chapter 14: Ansible Deployment of the Aerospike NoSQL Database
6X
X5! 66965
6XY !
command: service aerospike stop
Chapter 15
The Elovation application uses the Elo rating system created by Arpad
" > > $ # >
Trueskill rating system for teams with multiple players and still provide
rankings for individual players. Elovation requires at least Ruby on Rails
5.1 and uses the PostgreSQL database for its backend. It is free and open
source software and has been released under the MIT licence.
GNU/Linux
An Ubuntu 16.04.1 LTS guest virtual machine (VM) instance using KVM/
QEMU has been chosen to set up Elovation.
Y " ?* = =& "
Ansible is installed on the host system using the distribution package
manager. The version of Ansible used is 2.4.3.0 as indicated below:
You should add an entry to the /etc/hosts $ ‘Ubuntu’
VM as follows:
8K"8"8KK"K
Chapter 15: Ansible Deployment of Elovation | 145
ansible/inventory/kvm/
& 5 & &
The Ubuntu 16.04.1 LTS server has Python 3 by default, and hence
we can use the same with Ansible. The inventory/kvm/inventory
contains the following:
?! 6 I
V 8K"8"8KK"K V V
V + 8KL
Dependencies
Y # > $ $
16.04.1 LTS. If we need to install software, the APT lock held by this
> "# > >#
The APT software package repository is then updated before installing
the dependencies to set up Ruby.
666
6X
hosts: ubuntu
become: yes
become_method: sudo
gather_facts: true
tags: [apt]
146 | Chapter 15: Ansible Deployment of Elovation
tasks:
6XY 65" !
X 5 666+ 65" !
The -vv represents the verbosity of the Ansible output. You can use
up to four ‘v’s. The -K option prompts for the sudo password for the
ubuntu user.
Rbenv
Let’s use Rbenv to set up Ruby on this virtual instance. It allows the
installation of multiple Ruby versions, and the version in production
> ># Y > $ ! >
and make are executed. The Rbenv PATH and initialisation
are then updated in the ~/.bashrc .
6X4!
hosts: ubuntu
tags: [rbenv]
tasks:
6X !
git:
Chapter 15: Ansible Deployment of Elovation | 147
6X4!
X && V &"!¬¬ &¬¬6
src”
6XY !
X
X && V &"
state: present
X¥# Q -&"!&XQH
6X!
X
X && V &"
state: present
X¥! Q2! 6%H
Y7? !I99999999999999999999999999999999999999999999999999999999999999
*******************************************
ok: [ubuntu]
Y7?4!I999999999999999999999999999999999999999999999999999999999999
*******************************************
changed: [ubuntu]
Y7?Y !I999999999999999999999999999999999999999999999999999999999
*******************************************
ok: [ubuntu]
Y7?! I9999999999999999999999999999999999999999999999999999999999999
*******************************************
ok: [ubuntu]
&
! >"" !# :
needs to be cloned into the Rbenv plugins folder. Ruby 2.4.0 is then
Chapter 15: Ansible Deployment of Elovation | 149
installed using the rbenv command, and the same is set as the default
global Ruby version in the following playbook:
6X45
hosts: ubuntu
tags: [ruby]
vars:
!V X && V &"!
tasks:
6X !
XQY-6 6 !V &
6X 56
git:
X¥ X&& "&!&56" H
X !V & &56
6X 5K""
XQY-6 !V &&! K""
The above playbook can be invoked with the ‘ruby’ tags option as
shown below:
$
Elovation uses the PostgreSQL database, by default, as its backend data
store. After updating the APT software package repository, we can install
the PostgreSQL server and a few other dependencies. The PostgreSQL
database server is started, and the Ansible playbook waits for the database
to listen on Port 5432. A separate application user account is created in
# > = "
production, it is recommended that you use Vault to encrypt and decrypt
the passwords with Ansible. The local authentication is changed from
peer to md5 in the PostgreSQL pg_hba.conf >
database is restarted. The Ansible playbook again waits for the server
to listen on Port 5432, as shown below:
150 | Chapter 15: Ansible Deployment of Elovation
6X Z
hosts: ubuntu
become: yes
become_method: sudo
tags: [postgresql]
tasks:
6X ' + 5
apt:
update_cache: yes
6+ V'X
XLK
H
6+ V'X
XLK
Elovation
Y ! ! > # Y
bundler software is used to track gems and the versions required by the
! > # :
cloned to the HOME folder. The >
database credentials are updated. The bundle install command is executed
to fetch and install the required gems for the application. The database is
created for the application and the migrations are executed to create the
necessary tables. The entire playbook to set up Elovation is as follows:
6X-!
hosts: ubuntu
tags: [elovation]
vars:
!V X && V &"!
tasks:
6X
X !V & &
copy:
X && V &! && "5"#
X && V &! && "5
remote_src: yes
6X '!
X
X && V &! && "5
insertafter: “ database: elovation_development”
X X © +X 8KL
6X '
X
X && V &! && "5
insertafter: “ database: elovation_test”
X X © +X 8KL
6X
X !V & &
args:
X && V &!
You can then log in to the VM, and manually start the RAILS application
using the following command:
$ cd elovation
QYV-! # !668K"8"8KK"K
Name
Allow ties
Name
Rating type
Allow ties
shown in Figure 1.
> " "
shown in Figure 2.
You can start a new game using the Trueskill rating system, as shown
in Figure 3.
You can also create a new game with the Elo rating system, as shown
in Figure 4.
154 |
Chapter 16
This is the 15th article in the DevOps series, in which the author
! "
content (HTML, CSS, JavaScript), and to use Goaccess for log analysis.
Nginx is a free and open source Web server written in C by Igor Sysoev.
It is designed to handle thousands of client connections. It is also
popularly used as a load balancer. It does not require much memory
and can also be used as an HTTP cache server or a mail proxy server.
: KK }% - >>#
>> $ > $ # : " j
log analyser written in C by Gerardo Orellana. You can run it remotely on
a *nix terminal or access it through a browser. It requires only ncurses
as a dependency when used from a terminal. It supports a number of
Web log formats such as Apache, Nginx, Elastic load balancing, etc. You
can also use a terminal dashboard with it and export reports to HTML.
: K+K :Y >>#
GNU/Linux
% =& " > > *
QEMU is chosen to install Nginx.
Y " ?* = =& "
Ansible is installed on it using the distribution package manager. The
version of Ansible used is 2.5.0 as indicated below:
You should add an entry to the /etc/hosts $ ‘debian’
VM as follows:
8K"8"8KK"8
ansible/inventory/kvm/
& 5 & &
& &
& &V
/example.domain
/goaccessrc
The default Debian 9 installation does not install the sudo package.
Start the new Debian VM, log in as the root user, and install the sudo
package. You should also provide sudo access to the user account,
which is ‘debian’ (in this example).
You should now be able to issue commands from the host system to
the guest OS, using Ansible. For example:
Nginx
Y ? = j # Y $ >-
repository is updated, and then the Nginx package is installed. The
Nginx Web server is started and we wait for the server to listen on port
80. The playbook to install Nginx is as follows:
666
6X #
hosts: debian
become: yes
become_method: sudo
gather_facts: true
tags: [nginx]
tasks:
6X ' + 5
apt:
update_cache: yes
6X #
package:
X
state: latest
with_items:
6#
6XY #
service:
name: nginx
state: started
6+ V'X
port: 80
The above playbook can be invoked using the command shown below:
The -vv represents the verbosity in the Ansible output. You can use
up to four v’s for a more detailed output. The -K option prompts for the
sudo password for the debian user account. You can now open a Web
browser on the local host with the URL http://192.168.122.140 and you
should see the default Nginx home page as shown in Figure 1.
6X 5
hosts: debian
become: yes
become_method: sudo
gather_facts: true
tags: [static]
tasks:
6XY # !
service:
name: nginx
state: stopped
mode: 0755
6X
X
X& &#& 6!&# "
X& &#& 6&# "
owner: root
group: root
force: yes
state: link
6XY #
service:
name: nginx
state: started
6+ V'X
port: 80
server {
listen 80;
listen [::]:80;
server_name example.domain www.example.domain;
root /var/www/html;
location / {
return 301 $scheme://www.example.domain/home$request_uri;
location /home {
5V QQ&
The Nginx Web server is then started to serve the newly copied
># Y - $ > >
can be invoked as follows:
Goaccess
Y >> > " j
Debian package repository. After updating the software APT repository,
>> # Y > $" ? =
is made available in the goaccessrc # : > $ X
6X
hosts: debian
become: yes
become_method: sudo
gather_facts: true
tags: [goaccess]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6
6X 5
copy:
X""&""& &
X && V V &"
*******************************************
L 5 5 & &#"5
You can now log in to the guest VM and run Goaccess from the terminal
for the Nginx access.log $ X
You can also export the dashboard to an HTML report that you can
view in a browser:
Chapter 17
Setting things up
A CentOS 6.8 virtual machine (VM) running on KVM is used for the
setup. Please ensure that the VM has access to the Internet. The Ansible
?* = =& ##K#
ansible/inventory/kvm/inventory
& 5 & & "5
& 5 &  "5
Also, add an entry for the centos guest in /etc/hosts >
below:
8K"8"8KK"8
&%@JKJJJJJM
Y Y::% !KKKKKK "
must send an email to the designated staff members when the storage
volume reaches its capacity. The ‘ >$ > ’ variable in /etc/
audit/auditd.conf should be set to an email address of an administrator.
The following Ansible code snippet checks the same, and asserts if an
‘@’ symbol for the email address exists.
666
6XY
hosts: centos
166 | Chapter 17: Security Technical Implementation Guide (STIG)
become: true
gather_facts: true
tags: [STIG]
tasks:
6X -66 5
staff members”
shell: “grep ^space_left_action /etc/audit/auditd.conf”
register: space_left_action_result
6 X
that:
6 HH V' V V "
&%@JKJJJJJQ
This rule states that the Red Hat GPG keys need to be installed in order
to cryptographically verify that the packages are actually from Red Hat.
The ‘-’ software package should be installed in the system.
6 X
that:
6 V 5V " ³¥H
&%@JKJJJJXX
The system should always be up to date with the latest software. This
can be checked from the output of ‘" >>- ’. The remedy
is to run ‘yum update’ to pull the latest software packages from the
repositories, as follows:
6 X
that:
6 5VV V "
Chapter 17: Security Technical Implementation Guide (STIG) | 167
&%@JKJJJJXY
This rule states that the downloaded packages need to be cryptographically
$ > # Y ‘gpgcheck=1’ >
should exist in the /etc/yum.conf #
6 X
that:
6 H8H V "
&%@JKJJJJXK
Y " # > :
%> " :% > >>-
released under the GPL. It can be installed on CentOS, as follows:
6 X
that:
6 V " ³¥H
&%@JKJJJJXQ
Y :% " $ #
database needs to be created for its use. The database consists of regular
= $" > # " $
algorithms such as md5, sha1, sha256, sha512, crc32, etc, are used to
>>- $ #
6 X
that:
6 VV " "#
168 | Chapter 17: Security Technical Implementation Guide (STIG)
&%@JKJJJJXZ
The .rhosts and /etc/hosts.equiv rsh daemon can allow
unauthorised access to the system. Hence, these should not exist in the
"# Y " >>- > $
#
6 X
that:
6 V V " "# '
6 X
that:
6 V " "# '
&%@JKJJJJ[J
The SELinux policy needs to be set to ‘Enforcing’ in the /etc/selinux/
# Y - $$> $" "
enforces limits on system services.
6 X
that:
6 H'H #V "
&%@JKJJJJ[Y
The SELinux targeted policy ensures that processes that are targeted
> " >
domain. The SELINUXTYPE variable needs to be set to ‘targeted’ in /
Chapter 17: Security Technical Implementation Guide (STIG) | 169
6 X
that:
6 H H #V 5 V "
&%@JKJJJJY[
We need to ensure that there is only one root user in the system. The /
etc/passwd > >>-
UID 0.
6 X
that:
6 V V " V 8
PLAY [STIG]*************************************************
changed: [centos]
170 | Chapter 17: Security Technical Implementation Guide (STIG)
changed: [centos]
changed: [centos]
Y7? I99999999999999999999999999999999999999999999999
ok: [centos] => {
“changed”: false,
“msg”: “All assertions passed”
changed: [centos]
Y7? I99999999999999999999999999999999999999999999999
ok: [centos] => {
“changed”: false,
Chapter 17: Security Technical Implementation Guide (STIG) | 171
Y7? I99999999999999999999999999999999999999999999999
ok: [centos] => {
“changed”: false,
“msg”: “All assertions passed”
Y7? I99999999999999999999999999999999999999999999999
ok: [centos] => {
“changed”: false,
“msg”: “All assertions passed”
“changed”: false,
“msg”: “All assertions passed”
Y7? I99999999999999999999999999999999999999999999999
ok: [centos] => {
“changed”: false,
“msg”: “All assertions passed”
Fixing STIG
We will also need to create a Ansible playbook, to set up the
" " < Y: > > # Y $ -
provides the necessary steps to set up the system for the above mentioned
Y::% #
tasks:
6X -6688Y5 5
be installed”
ª -666 !5
must be installed
yum:
X¥9H
state: latest
6X -66 5
Chapter 17: Security Technical Implementation Guide (STIG) | 173
staff members”
X
dest: “/etc/audit/auditd.conf”
# X¥M V' V H
X¥ V' V "H
> Y: > > >" $"
https://iase.disa.mil/stigs/os/unix-linux/Pages/index.aspx.
174 |
Chapter 18
Consul is a tool that has been written by HashiCorp, and can be used
for creating health checks for services and systems. It provides a simple
HTTP API for using it as a key/value store. Consul is distributed, highly
available, and is data centre aware. The recommended number of Consul
> $ #
centre can contain a Consul cluster. Consul is released under the Mozilla
Public License 2.0.
Setting up Consul
j > > %
=& " > *#
Y " ?* = =& "
Ansible is installed using the distribution package manager. The version
of Ansible used is 2.5.3 as indicated below:
ansible/inventory/kvm/
& 5 & &
& &
[consul1]
8 V 8K"8"8KK"8 V V
ansible_password=password
? KI
K V 8K"8"8KK"K V V
ansible_password=password
[consul3]
L V 8K"8"8KK" V V
ansible_password=password
[bootstrap:children]
consul1
[server:children]
K
consul3
[all:children]
bootstrap
server
We have three Consul guest VMs running that are labelled as ‘consul1’,
‘consul2’ and ‘consul3’# > + # Y
other members (consul2 and consul3) of the Consul cluster belong to
the server group. The ‘all’ group consists of all the three nodes.
The default Debian 9 installation does not have the sudo package
installed. Log in as the root user, and install the sudo package on all the
three VMs. The ‘debian’ user also requires sudo access:
You can now test connectivity from Ansible to the individual Consul
nodes as well as collectively, by using the following commands:
Consul
Y # Y $
package repository is updated, and a few network tools are installed.
The ‘> [ = > $" ¢ [
website and copied to /usr/local/bin/consul. The execution of the
# ‘consul’ user account is created in the system,
and the /var/consul directory is created and owned by the ‘consul’
Chapter 18: Ansible Deployment of Consul | 177
666
6X
hosts: all
become: yes
become_method: sudo
gather_facts: yes
tags: [consul]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
unarchive:
src: https://releases.hashicorp.com/consul/1.1.0/consul_1.1.0_linux_
amd64.zip
dest: /usr/local/bin
remote_src: yes
6X'5
X 66!
register: consul_version
6 X
that:
6 H H V! "
The ‘[ # >
up to four ‘v’s for a more detailed output. The ‘[ " $
the sudo password for the debian user account.
You can also now log in to any one of the nodes and check the version
output by running Consul as indicated below:
K 5' K L2 + 5
£K+ %
Bootstrap node
Y ># Y /etc/consul.d/
bootstrap > > >
json > # : > $ X
{
“bootstrap”: true,
“client_addr”: “0.0.0.0”,
“server”: true,
“datacenter”: “chennai”,
“data_dir”: “/var/consul”,
5 X 'Z& 7K+
“log_level”: “INFO”,
“enable_syslog”: true
[Unit]
Description=Consul service discovery agent
Z +6"
' +6"
[Service]
-! ² YK
6'
-#Y & &&& 6 !66 6& &
6 866& & "& 66 6
-#&&6Q
7YY-
[Install]
45 6 "
The ‘ ’ j $ $ #
The bootstrap node’s name is ‘host1’. The entire playbook to set up
and start the bootstrap node is as follows:
tasks:
6X 5
X
path: /etc/consul.d/bootstrap
state: directory
mode: 0755
copy:
X""&""& & 6"
X& & "& &"
changed: [host1]
{
“bootstrap”: false,
“server”: true,
“datacenter”: “chennai”,
“data_dir”: “/var/consul”,
5 X 'Z& 7K+
“log_level”: “INFO”,
“enable_syslog”: true,
VX?¹' ?¥HI¹ ! ? I"
V' V !" ¹' " ¹¹'¹¹'
¹I
[Unit]
Description=Consul service discovery agent
Z +6"
' +6"
182 | Chapter 18: Ansible Deployment of Consul
[Service]
-! ² YK
6'
-#Y & &&& 6 !6 6& & 6
! 5V 66& & "& !66 6
checks=true
-#&&6Q
7YY-
[Install]
45 6 "
tasks:
6X ! 5
X
path: /etc/consul.d/server
state: directory
mode: 0755
name: consul.service
state: started
You can now verify the nodes that are part of the Consul cluster using
Consul 3 passing
host1 1 services
host2 1 services
host3 1 services
/+
Create Key
$ consul members
Node Address Status Type Build Protocol DC Segment
88K"8"8KK"8XL8! !8"8"K¶£
K8K"8"8KK"KXL8! !8"8"K¶£
L8K"8"8KK"XL8! !8"8"K¶£
The web UI listens on Port 8500 on host1, and you can make a Curl
request for the same as shown below:
$ curl localhost:8500/v1/catalog/nodes
[
X'6'6KL68L6'''8LK
“Node”:”host1”,
X8K"8"8KK"8
“Datacenter”:”chennai”,
X X8K"8"8KK"8+X8K"8"8KK"8
X 6 +6 X
#X'5#X
XK''6K6LL66L
X K
X8K"8"8KK"K
“Datacenter”:”chennai”,
X X8K"8"8KK"K+X8K"8"8KK"K
X 6 +6 X
#X8'5#X8L
X'8L66686''K'L
“Node”:”host3”,
X8K"8"8KK"
“Datacenter”:”chennai”,
X X8K"8"8KK"+X8K"8"8KK"
X 6 +6 X
#X8K'5#X8
Chapter 19
Monit is a free and open source process supervision tool for *nix
" # : > " > $"
maintenance or repair tasks. The system status check can be done on
the command line and viewed in a browser. It is written entirely in C and
released under the AGPL 3.0 licence. In this 18th article in the DevOps
series, we will learn to install and set up Monit for the system, as well
as the SSH daemon and Nginx Web server monitoring.
Setting it up
% =& " > *
be set up and monitored using Monit.
Y " ?* = =& "
Ansible is installed using the distribution package manager. The version
of Ansible used is 2.6.0, as indicated below:
ansible/inventory/kvm/
& 5 & &
The default Debian 9 installation does not have the sudo package
installed. Log in to the VM and install the sudo package. The ‘debian’
user also requires sudo access:
8K"8"8KK"8
You can now test connectivity from Ansible to the Debian 9 VM using
the following command:
Installation
Y % $ >-
is installed. The net-tools package is installed to provide the netstat
command in the system. The Monit service is then started using systemd.
The Ansible playbook for the above tasks is provided below, for reference:
666
Chapter 19: Ansible Deployment of Monit | 187
6X
hosts: debian
become: yes
become_method: sudo
gather_facts: yes
tags: [install]
tasks:
6X ' + 5
apt:
update_cache: yes
6X
package:
X
state: latest
with_items:
6 6
6
The -vv represents the verbosity in the Ansible output. You can use
up to four ‘v’s for a more detailed output. The -K option prompts for the
sudo password for the Debian user account.
Web interface
Monit software provides a Web interface that listens on port 2812. The
$ > $ > /etc/monit/monitrc. The
Web UI port needs to be enabled with basic login credentials. After making
> > > # Y
Ansible playbook to enable the Monit’s Web interface is as follows:
6X
188 | Chapter 19: Ansible Deployment of Monit
hosts: debian
become: yes
become_method: sudo
gather_facts: true
tags: [ui]
tasks:
6X
path: /etc/monit/monitrc
# X¥ K8KH
X¥ K8KH
6X
path: /etc/monit/monitrc
# X¥ª+X H
X¥+X H
6+ V'X
XK8K
§?I999999999999999999999999999999999999999999
Y7?I99999999999999999999999999999999999999999999
Chapter 19: Ansible Deployment of Monit | 189
changed: [debian]
Y7?I99999999999999999999999999999999999999999999
changed: [debian]
Y7?+ V'I999999999999999999999999999999999999999999999
ok: [debian]
You can use the netstat command to verify that Monit is listening on
port 2812 as shown below:
Q 6
5 # 7
Y $ > > > X
Y5 ¥H
status Running
monitoring status Monitored
monitoring mode active
on reboot start
!?"I?"KI?"I
cpu 0.4%us 0.3%sy 0.0%wa
memory usage 45.5 MB [4.6%]
swap usage 0 B [0.0%]
uptime 56m
°K88XLX
°K88XXK
The status of the Monit service can also be checked from the command
line using systemctl, as shown below:
CGroup: /system.slice/monit.service
»KL& && 6& & &
SSH
We can now set up Monit to monitor the SSH daemon running inside the
# >>- >- $ >
> # Y -
< " > X
6X '#
hosts: debian
become: yes
become_method: sudo
gather_facts: true
tags: [ssh]
tasks:
6X
X
path: /etc/monit/monitrc
marker_begin: “ssh BEGIN”
marker_end: “ssh END”
block: |
+ &!&& "
group system
group sshd
start program = “/etc/init.d/ssh start”
stop program = “/etc/init.d/ssh stop”
'' KK+
if 5 restarts with 5 cycles then timeout
depend on sshd_bin
depend on sshd_rc
depend on sshd_rsa_key
depend on sshd_dsa_key
include /etc/monit/templates/rootstrict
¥ H
status Running
monitoring status Monitored
monitoring mode active
on reboot start
pid 381
parent pid 1
uid 0
effective uid 0
gid 0
uptime 1h 6m
threads 1
children 5
cpu 0.0%
cpu total 0.0%
5"¹?"K4I
5 L"L¹?LL"K4I
" XKK 5 &
YY
°K88XX
194 | Chapter 19: Ansible Deployment of Monit
¥ VH
status Accessible
monitoring status Monitored
monitoring mode active
on reboot start
permission 755
uid 0
gid 0
K"4
K88LX8X
8'K88K2 %
°K88XX
¥ VH
status Accessible
monitoring status Monitored
Chapter 19: Ansible Deployment of Monit | 195
Y5 ¥H
status Running
monitoring status Monitored
monitoring mode active
on reboot start
load average [0.00] [0.00] [0.00]
cpu 0.0%us 0.0%sy 0.0%wa
memory usage 47.6 MB [4.8%]
swap usage 0 B [0.0%]
uptime 1h 6m
°K88XLX
°K88XX
Nginx
We can also set up Nginx on the guest VM and monitor it using Monit. The
$ >- ? = #
The service is started and we wait for it to listen on port 80. The Nginx
" >>- >
Monit service is restarted. The Ansible playbook for the above tasks is
provided below, for reference:
tasks:
6X ' + 5
apt:
update_cache: yes
6X #
196 | Chapter 19: Ansible Deployment of Monit
package:
X
state: latest
with_items:
6#
6XY #
service:
name: nginx
state: started
6+ V'X
port: 80
6X#
X
path: /etc/monit/monitrc
marker_begin: “nginx BEGIN”
marker_end: “nginx END”
block: |
#+ &!&&#"
group www
group nginx
start program = “/etc/init.d/nginx start”
stop program = “/etc/init.d/nginx stop”
if 5 restarts with 5 cycles then timeout
depend nginx_bin
depend nginx_rc
include /etc/monit/templates/rootbin
The Monit home page now contains the status of the system, the SSH
daemon and the Nginx Web server, as shown in Figure 3.
Clicking on the ‘sshd’ or ‘nginx’ link on the Monit home page provides
a more detailed status page, as shown in Figures 4 and 5, respectively.
You are encouraged to read the Monit manual at https://mmonit.
com/monit/documentation/monit.html to learn more about its options
and usage.
| 199
Chapter 20
Setting them up
, ' =& " > *
be used to set up Sensu.
Y " ?* = =& "
Ansible is installed using the distribution package manager. The version
of Ansible used is 2.6.0 as indicated below:
ansible/inventory/kvm/
& 5 & &
& &
8K"8"8KK"L
You can now test connectivity from Ansible to the CentOS 7 VM using
the following command:
[sensu]
name=sensu
baseurl=https://sensu.global.ssl.fastly.net/yum/$releasever/$basearch/
gpgcheck=0
enabled=1
666
6X 5
hosts: sensu
become: yes
become_method: sudo
gather_facts: yes
tags: [repo]
tasks:
6X 6
yum:
X 6
state: present
6X "
copy:
X""&""& & "
dest: /etc/yum.repos.d/sensu.repo
The -vv represents the verbosity in the Ansible output. You can use up
to four v’s for a more detailed output. The -K option prompts for the sudo
password for the centos user account.
Redis
Y ! "" $ #
You can install it using the YUM tool. In the following example, the
>" ! > "
mode and the server is started. We wait for the Redis server to run on
@'# Y - $ >
Redis is as follows:
6X
hosts: sensu
become: yes
become_method: sudo
gather_facts: true
202 | Chapter 20: Ansible Deployment of Sensu and Uchiwa
tags: [redis]
tasks:
6X
yum:
name: redis
state: present
6X
path: /etc/redis.conf
# X¥M 65 H
X¥ 6H
6XY
systemd:
name: redis
state: started
6+ V'X
XL
Sensu
You can now proceed to install Sensu and the Uchiwa dashboard. The
jq tool is used to process JSON data in the command line. The Sensu
' > > $ ! : >>
information as shown below:
{
“transport”: {
“name”: “redis”
“api”: {
X 8K"""8
“port”: 4567
{
“client”: {
“environment”: “development”,
“subscriptions”: [
“linux”
]
{
“sensu”: [
{
“name”: “sensu”,
X 8K"""8
“port”: 4567,
“timeout”: 10
],
“uchiwa”: {
“host”: “0.0.0.0”,
“port”: 3000,
“refresh”: 10
tags: [sensu]
tasks:
6X
yum:
X
state: present
with_items:
6
6+
6Z
6X "
copy:
X""&""& &"
X& & &"
6X "
copy:
X""&""& & "
dest: /etc/sensu/conf.d/client.json
6X +"
copy:
X""&""& &+"
dest: /etc/sensu/uchiwa.json
6X
path: /etc/sensu
owner: sensu
group: sensu
recurse: yes
6+X
port: 3000/tcp
state: enabled
6XY !
systemd:
X
state: started
with_items:
6 6 !
6 6
6 6
Chapter 20: Ansible Deployment of Sensu and Uchiwa | 205
6+
The execution output for installing Sensu and Uchiwa is shown below:
Y7?I99999999999999999999999999999999999999999999999999
changed: [sensu]
Y7?+I999999999999999999999999999999999999999999999
changed: [sensu]
Checks
The monitoring checks for CPU, disk and memory can be set up on the
guest VM and viewed in the Uchiwa dashboard. The sensu-install command
is used to install the Ruby script checks that will be run periodically.
Y >>- > $ - "" > /
etc/sensu/conf.d directory and provided below for reference:
6X-
hosts: sensu
become: yes
become_method: sudo
gather_facts: true
tags: [checks]
tasks:
6X
X 6 6
args:
chdir: /opt/sensu/embedded/bin
with_items:
6 6
6 6
656
copy:
X ""&""& & "
X & & &'"& "
with_items:
6V V#
6V V V#
6V5V#
6X !
systemd:
X
state: restarted
with_items:
6 6 !
6 6
6 6
6+
66 6!!67
The Sensu dashboard will now have the installed checks as shown
in Figure 3.
The results of the check output are also available in the dashboard
as shown in Figure 4.
You are encouraged to read the Sensu Core documentation available
at https://docs.sensu.io/sensu-core/1.4/ to learn more about the
framework and its usage.
| 211
Chapter 21
Bugzilla is Web based and written using the Perl programming language.
Released on August 26, 1998, it is used by a number of other FLOSS
projects such as the Linux kernel, GNOME, Red Hat, Apache and KDE.
It requires a database, Web server and at least Perl 5 to run. You can
> Y " " # :
released under the Mozilla Public License.
Setup
, ' =& " > *
> } # Y "
?* = =& "
using the distribution package manager. The version of Ansible used
is 2.6.0 as indicated below:
ansible/inventory/kvm/
& 5 & &
& &
212 | Chapter 21: Ansible Deployment of Bugzilla
A ‘centos’ user is created in the guest VM, and sudo access is provided
for this user using the visudo command. SELinux needs to allow access
for port 80. You should also add an entry in the /etc/hosts $
CentOS VM, as shown below:
8K"8"8KK"
You can now test connectivity from Ansible to the CentOS 7 VM using
the following command:
&!
The installation of Bugzilla requires additional repositories — deltarpm
and epel-release# Y _" [
is required to update the cache. The Ansible playbook for installing the
repositories is given below:
666
6X 5
hosts: bugzilla
become: yes
become_method: sudo
gather_facts: yes
tags: [repo]
tasks:
6X
yum:
X
state: present
with_items:
6
Chapter 21: Ansible Deployment of Bugzilla | 213
6 6
6X§
yum: name=* update_cache=yes state=present
Y _[ # >
$ [ $ " # Y _[ " $
the sudo password for the ‘centos’ user account.
HTTPD
Bugzilla does require a Web server and the Apache HTTP (httpd) server
>- > # Y
allow port 80. After installing the packages, the httpd service is started,
and we wait for the server to listen on port 80. The Ansible playbook for
the above tasks is as follows:
6X
hosts: bugzilla
become: yes
become_method: sudo
gather_facts: true
tags: [httpd]
tasks:
6+X
214 | Chapter 21: Ansible Deployment of Bugzilla
port: 80/tcp
state: enabled
6XY
service:
name: httpd
state: started
6+ V'X
port: 80
6X 4
hosts: bugzilla
Chapter 21: Ansible Deployment of Bugzilla | 215
become: yes
become_method: sudo
gather_facts: true
tags: [mariadb]
tasks:
6X 4 5
yum:
X
state: present
with_items:
6 6 !
6
6 6!
6 5Y¤6 5
6X+#+
X
path: /etc/my.cnf
X¥#V+V H
6XY
service:
name: mariadb
state: started
6+ V'X
port: 3306
Bugzilla
Perl is required for Bugzilla, and we need to install the same and a few
other Comprehensive Perl Archive Network (CPAN) dependencies. The
} #K > /var/www/html/
bugzilla. The sources come with a checksetup.pl script that you can
invoke to see if the minimum installation requirements are met. The
" - > =
Perl modules are missing. You can then use the install-module.pl script
to install the Perl dependencies. You should then rerun the checksetup.
pl script to check against the installed Perl modules. The /var/www/
)
password. A bugzilla.conf for the Web server is created at /etc/httpd/
conf.d/bugzilla $ > > X
6X 4
hosts: bugzilla
become: yes
become_method: sudo
gather_facts: true
tags: [bugzilla]
tasks:
6X 4 5
yum:
X
state: present
#X 6
with_items:
6
6 6¦¦
Chapter 21: Ansible Deployment of Bugzilla | 217
6X +4
unarchive:
X X&&' ""& &"&+ &6"" "
gz
dest: /var/www/html
remote_src: yes
6X6"
X!&!&+++& &6"&!&+++& &
6X
command: ./checksetup.pl
args:
chdir: /var/www/html/bugzilla
ignore_errors: true
6X
X& && 6" 66
args:
chdir: /var/www/html/bugzilla
6X
command: ./checksetup.pl
args:
chdir: /var/www/html/bugzilla
ignore_errors: true
6X
X
X&!&+++& &&
# X¥MQV H
X QV H 8KLH
X
path: /var/www/html/bugzilla/.htaccess
# X¥M 6H
X ª 6#
\
> checksetup.pl manually, as it prompts
for user credentials. You can change to the /var/www/html/bugzilla
directory, and execute the sudo ./checksetup.pl script, which will again
check the installed Perl modules, create tables in the database, and prompt
for the Administrator user account name and password. This has to be
entered manually. A sample execution output is shown below for reference:
'°Y 6²Y2!K"8%X'!L"
"&"""
' 4 65 Z2!"8%X'!"KL
'5Y¤2!""8%X'!""6 4
"
Creating xt/.htaccess...
Precompiling templates...done.
# """
Initializing “Dependency Tree Changes” email_setting ...
Initializing “Product/Component Changes” email_setting ...
Marking closed bug statuses as such...
' ¥ H"""
Setting up foreign keys...
Y ' ++"""
Creating default groups...
Setting up user preferences...
You can now restart the httpd server using the following command:
Chapter 22
Hardening of Parabola
Every computer offers security measures to isolate it from outside attacks. In
this 21st article in the DevOps series, we will learn how to harden, automate
and verify a Parabola GNU/Linux-libre system using Ansible.
Setup
?* = =& K+&#K#K :,
guest virtual machine (VM) with KVM/QEMU. The host system is also a
?* = =& "
the distribution package manager. The version of Ansible used is 2.6.0, as
is indicated below:
ansible/inventory/kvm/
& 5 & &
& &
You should add an entry in the /etc/hosts " $
the Parabola guest VM as indicated below:
8K"8"8KK"8K
You can now test connectivity from Ansible to the Parabola guest VM
using the following Ansible commands:
$#
The pwgen utility is useful to generate passwords. It has a number of
options that you can use to generate strong passwords with a combination
of numerals, symbols and characters. The Ansible playbook to install
pwgen is given below for reference:
6X
hosts: parabola
become: yes
become_method: sudo
Chapter 22: Hardening of Parabola | 225
gather_facts: yes
tags: [security]
tasks:
6X +
package:
name: pwgen
state: latest
6 X
that:
6 +" " +V¥ H
6 +" "
6 +" " '
6 +" " '
6 +" "+
6 +" "+ '
6 +" "+ '
6 +" "# '
6 +" "# '
6 +" "# '
6 X
226 | Chapter 22: Hardening of Parabola
that:
6 +" " +V¥ H
6 +" "
6 +" "
6 +" "
6 +" "+
6 +" "+ '
6 +" "+ '
6 +" "# '
6 +" "# '
6 +" "# '
= " !
It is recommended that your disk be encrypted, and you use a strong
passphrase that can be provided as input when booting the system. The
Parabola wiki has useful documentation on disk encryption at https://
wiki.parabola.nu/Disk_encryption. You can verify that the disk is encrypted
using the following Ansible code snippet:
6 X
that:
6 5 "
6X&
X & 6-¥ "9!H
register: tmp
6 X
that:
6 "
6X&!&
X &!& 6-¥ "9!"9#H
register: tmp
6 X
that:
6 "
The account can only be unlocked after a certain time ( & !
or by the root user.
hence one needs to restrict access to it. The folder has
both 50-dmesg-restrict.conf and 50-kptr-restrict.conf >
be copied to etc/sysctl.d for the above functionality.
The console logins for root can also be disabled by commenting them
*>* > #
230 | Chapter 22: Hardening of Parabola
Execution
The entire playbook is provided below for reference:
666
6X
hosts: parabola
become: yes
become_method: sudo
gather_facts: yes
tags: [security]
tasks:
6X +
package:
name: pwgen
state: latest
6 X
that:
6 +" " +V¥ H
6 +" "
6 +" " '
6 +" " '
6 +" "+
6 +" "+ '
6 +" "+ '
6 +" "# '
6 +" "# '
6 +" "# '
path: /etc/passwd
register: passwd
6 X
that:
6 +" " +V¥ H
6 +" "
6 +" "
6 +" "
6 +" "+
6 +" "+ '
6 +" "+ '
6 +" "# '
6 +" "# '
6 +" "# '
6X & & "& +
X
path: /etc/pam.d/passwd
'X¥M +"9Z"9 V#" H
X¥ +Z V" 5K
8' 68 68 68 68H
6 X
that:
6 5 "
6X&
X & 6-¥ "9!H
register: tmp
6 X
that:
6 "
6X&!&
X &!& 6-¥ "9!"9#H
register: tmp
6 X
232 | Chapter 22: Hardening of Parabola
that:
6 "
The -vv represents the verbosity in the Ansible output. You can use
up to four v’s for a more detailed output. The -K option prompts for the
sudo password for the guest Parabola user account.
You are encouraged to read the security guide and best practices for
?* = https://wiki.parabola.nu/Security
for more information.
234 |
Chapter 23
GNU Guile was designed by Aubrey Jaffer, Tom Lord and Miles Bader
" +@# > - j
command line applications in GNU Guile. The latest stable version, as of
July 2018, is v 2.2.4. It is released under the GPL and is available for both
:@ =& $" #
Setup
?* = =& K+&#K#K :,
a guest virtual machine (VM) using KVM/QEMU. The host system is
?* = =& "
using the distribution package manager. The version of Ansible used is
2.6.0 as indicated below:
ansible/inventory/kvm/
& 5 & &
Chapter 23: Using Ansible to Build GNU Guile | 235
8K"8"8KK"8
You can now test the connectivity from Ansible to the Parabola guest
VM using the following Ansible command:
* #!#
GNU Guile requires a number of software dependencies, such as gmp,
* % and readline. The essential build tools—autoconf,
* ***and make — are also needed for building
GNU Guile. The Ansible playbook to install the above software is given
below:
666
6X 5
hosts: guile
become: yes
become_method: sudo
gather_facts: yes
tags: [packages]
tasks:
236 | Chapter 23: Using Ansible to Build GNU Guile
The -vv represents the verbosity in the Ansible output. You can use
up to four ‘v’ s for a more detailed output. The -K option prompts for the
sudo password for the guest Parabola user account.
GNU Guile
The master branch from the GNU Guile Git repository (git.sv.gnu.org/guile.
git) will be used as the source for the build process. The source code is cloned
to the /home/parabola/guile directory. The basic GNU Autotools procedure
of running autogen.sh, and make in the source code will compile
GNU Guile. The build will take a few hours to complete, even on the latest
hardware. The Ansible playbook to compile GNU Guile is as follows:
6X4
hosts: guile
tags: [guile]
vars:
guile_home: “/home/parabola/guile”
Chapter 23: Using Ansible to Build GNU Guile | 237
tasks:
6X'
git:
X¥ X&& " !""&" H
X V
6X "
command: ./autogen.sh
args:
X V
6X
X"&
args:
X V
6X
command: make
args:
X V
Installation
Y => >
guest VM. By default, the make install command will install the artifacts
to /usr/local. The Ansible playbook for installation is given below for
reference:
6X
hosts: guile
become: yes
become_method: sudo
tags: [install]
vars:
guile_home: “/home/parabola/guile”
tasks:
6X
238 | Chapter 23: Using Ansible to Build GNU Guile
Tests
The GNU Guile source code comes with a comprehensive test suite that
you can invoke using make check to run tests against the built binary.
The following Ansible playbook will run the GNU Guile tests:
6X
hosts: guile
tags: [test]
vars:
guile_home: “/home/parabola/guile”
tasks:
6X
command: make check
args:
X V
Documentation
Y < %^ $" >" >
in the GNU Guile code repository. The following Ansible playbook will
generate the PDF documentation:
tags: [docs]
vars:
guile_home: “/home/parabola/guile”
tasks:
6X #!6
package:
X #!6
state: latest
The following PDFs are built and available in the GNU Guile sources
directory:
Q"69" '
./doc/ref/scheme.pdf
./doc/ref/gds.pdf
./doc/ref/guile.pdf
./doc/ref/hierarchy.pdf
./doc/r5rs/r5rs.pdf
Benchmarking
A benchmark-guile script is available to run benchmarks against the built
binaries. The following Ansible playbook can be used to run benchmarking:
6X
hosts: guile
gather_facts: yes
tags: [benchmarks]
vars:
guile_home: “/home/parabola/guile”
tasks:
6X
X"&6
args:
X V
You can learn more about GNU Guile from its home page at https://
www.gnu.org/software/guile/.
| 241
Chapter 24
Master-Slave Setup Using Ansible
PostgreSQL is a free and open source, ACID-compliant,
transactional database written in the C programming
language. It supports updatable views, triggers, stored
procedures and foreign keys, and manages concurrency
using multi-version concurrency control (MVCC). In this 23rd
article in the DevOps series, we will learn how to install and
configure a PostgreSQL master-slave replication setup.
ansible/inventory/kvm/
& 5 & &
[pgmaster]
8 V 8K"8"8KK"8 V V
V + 8KL
[pgslave]
K V 8K"8"8KK"88L V V
V + 8KL
[all:children]
pgmaster
pgslave
The host1 and host2 entries are added in the /etc/hosts
host system as shown below:
8K"8"8KK"8 8
8K"8"8KK"88L K
You can test connectivity from Ansible to the CentOS guest VMs using
the following Ansible commands:
666
6X 6Z
hosts: all
become: yes
become_method: sudo
gather_facts: yes
tags: [common]
vars:
V +X 8KL
tasks:
6X 6
package:
X X&&5" Z"&"& &66#V& 6
6"6L""
state: present
systemd:
X Z6"
enabled: yes
state: started
6XY +
systemd:
X+
enabled: yes
state: started
6X+
X+666
6X +
X+666 6
The -vv represents the verbosity in the Ansible output. You can use
up to four ‘v’ s for a more detailed output. The -K option prompts for
the sudo password for the guest CentOS user account.
6XY
hosts: pgmaster
become: yes
become_method: sudo
gather_facts: yes
tags: [pgmaster]
vars:
V +X¥ 8KLH
tasks:
6X &!&& Z&"& & Z"'
X
X&!&& Z&"& & Z"'
# X "#
X "
with_items:
6# X ª V ¥ HX V
¥ V' V !" H
6# X¥ª+V!HX¥+V! V 5H
6# X¥ª 5 V HX¥ 5 V
H
6# X¥ª!V''HX¥!VH
6# X ª!V¥HX !V¥ ¹ &
!&& Z&"&!&¹'H
6# X¥ª#V+V HX¥#V+V KH
6# X¥ª+V V HX¥+V V KH
6# X ª 5 V 5V ¥HX 5 V
5V ¥ !8H
6X V"'
246 | X
X
X&!&& Z&"& & V"'
' X¥ª XX8&8K
H
block: |
# Localhost
8K"""8&LK
ª Y¤Y!
host replication replica
! ?¥ KHI" V' V !" &LK
ok: [host1]
Y7? V"'I99999999999999999999999999999999999
changed: [host1]
changed: [host1]
6XY !
hosts: pgslave
become: yes
become_method: sudo
gather_facts: yes
tags: [pgslave]
vars:
V +X¥ 8KLH
tasks:
6XY Y¤ !
systemd:
X Z6"
state: stopped
6X!
X! 6
args:
X&!&& Z&"&
state: directory
6X !5"'
X
X&!&& Z&"& &!5"'
block: |
5V¥H
5V'¥ ! ?¥ 8HI" V' V !"
LK + V + V
!8H
V¥& & Z" "LKH
mode: 0600
owner: postgres
group: postgres
state: present
create: yes
Testing
You can log in to the master instance, become a Postgres user, and run
the following psql commands to see the synchronisation state of the setup:
ª 6
6 6"KQ Z6 V 5V 5 5V
from pg_stat_replication;”
application_name | state | sync_priority | sync_state
666666666666666666¦66666666666¦666666666666666¦666666666666
slave01 | streaming | 1 | sync
(1 row)
You can create tables and insert records on the master instance. An
example is given below:
6 6"KQ Z
Z2""88%
Type “help” for help.
You can now verify that the records exist on the slave instance using
the following set of commands:
If you try to insert records on the slave instance, the database will
throw a ‘ > ’ error as shown below:
Chapter 25
Setup
Y = ? = , ' =&
operating system. A single instance is launched using KVM for running
=# > $ , >
Nginx. The centos users in all the VMs are given sudo access using the
visudo command. SELinux is disabled for the exercise.
Y " ?* = =& "
Ansible is installed using the distribution package manager. The version
of Ansible used is 2.6.0 as indicated below:
ansible/inventory/kvm/
& 5 & &
& &
[front]
#5 V 8K"8"8KK"88L V V
ansible_password=password
[web1]
#8 V 8K"8"8KK"K V V
ansible_password=password
?+KI
#K V 8K"8"8KK"8 V V
ansible_password=password
[web:children]
web1
+K
“ping”: “pong”
Q 6! 5&!&! 5#K6
#KY-YY£
“changed”: false,
“ping”: “pong”
Nginx
j ? = j # Y !
installed and the HAProxy server IP address is added to /etc/hosts
the instances. The YUM package manager is used to install Nginx, and
&K # j ? = j
server and wait for the server to listen on port 80. The Ansible playbook
to install and set up Nginx is as follows:
666
6XY #+ !
hosts: web
become: yes
become_method: sudo
gather_facts: yes
tags: [web]
tasks:
6X --
package:
X 6
state: present
path: /etc/hosts
X ! ?¥ #5HI" V #5
state: present
6X #
package:
name: nginx
state: present
6X+
X 66 66 6 66
--Y4Y- 6-
The -vv represents the verbosity in the Ansible output. You can use
up to four ‘v’ s for a more detailed output. The -K option prompts for the
sudo password for the guest CentOS user account.
You can now open the Nginx Web server URLs (http://192.168.122.248
and http://192.168.122.147) in a browser to see the default Nginx home
page as shown in Figure 1.
%$'
The YUM package repository needs to be updated before proceeding
to install HAProxy. The Nginx server IP addresses and hostnames
are added to the /etc/hosts > # Y $ /etc/
haproxy/haproxy.cfg directory is backed up and a new haproxy.cfg
> > X
global
8K"""8K
chroot /var/lib/haproxy
&!&& #5"
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
6 !6
'+'# 8K"""&
option redispatch
retries 3
6Z 8
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
6 6!8
timeout check 10s
maxconn 3000
option httpclose
stats enable
+6
stats refresh 5s
stats uri /stats
#5©Y
stats auth admin:password
stats admin if TRUE
' V 6
frontend main
bind *:80
6 !6
option forwardfor
' V 6
6
balance roundrobin
- &&8"8©© X©
¹' ?¥+HI¹
! ! ? I?¥! 5V HI ! ? I
?¥ V' V !HI?¥ HIX
¹'¹
The rsyslog software will be used to collect the HAProxy logs. The /
etc/rsyslog.conf > % :
Module (imudp) and to run a UDP server on Port 514. A /etc/rsyslog.d/
haproxy.conf > > > $ >
follows:
Y &K&K
# Y = $
it to listen on Port 8080. The complete Ansible playbook to install and
> = X
6XY #5
hosts: front
become: yes
become_method: sudo
258 | Chapter 25: Using Ansible to Set Up HAProxy as a Load Balancer for Nginx
gather_facts: yes
tags: [haproxy]
tasks:
6X§
yum: name=* update_cache=yes state=present
6X #5
package:
name: haproxy
state: present
6X+
X 66 66 6 66
--Y4Y- 6-
6X 5
systemd:
name: rsyslog
state: restarted
changed: [haproxy]
Y7?Y #5 !I999999999999999999999999999999999
changed: [haproxy]
Testing
You can open the HAProxy Web page using http://192.168.122.113:8080/
stats and you will be prompted to log in as shown in Figure 2.
You can use the credentials (admin:password > /etc/
haproxy/haproxy.cfg to log in, and you will see the HAProxy stats page
as shown in Figure 3.
> " - " < = $
browser or using curl http://192.168.122.113:8080 from the command
line. You will observe that the requests are being sent to both the Nginx
j $ > > "
section of the HAProxy stats page.
262 |
Shakthi Kannan
The author is a free software enthusiast and blogs at shakthimaan.com.
" #
The author works as an automation engineer at Infosys Limited, Pune. He has
worked on different testing technologies and automation tools like QTP, Selenium
and Coded UI. He can be contacted at [email protected].