mirror of
https://github.com/Apress/Beginning-Ansible-Concepts-and-Application.git
synced 2024-12-08 22:44:54 +01:00
Initial Commit
This commit is contained in:
commit
7cb6997da9
133 changed files with 1829 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
BIN
9781484281727.JPG
Normal file
BIN
9781484281727.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
14
Contributing.md
Normal file
14
Contributing.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Contributing to Apress Source Code
|
||||
|
||||
Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
|
||||
|
||||
## How to Contribute
|
||||
|
||||
1. Make sure you have a GitHub account.
|
||||
2. Fork the repository for the relevant book.
|
||||
3. Create a new branch on which to make your change, e.g.
|
||||
`git checkout -b my_code_contribution`
|
||||
4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
|
||||
5. Submit a pull request.
|
||||
|
||||
Thank you for your contribution!
|
27
LICENSE.txt
Normal file
27
LICENSE.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
Freeware License, some rights reserved
|
||||
|
||||
Copyright (c) 2022 Shaun R Smith and Peter Membrey
|
||||
|
||||
Permission is hereby granted, free of charge, to anyone obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to work with the Software within the limits of freeware distribution and fair use.
|
||||
This includes the rights to use, copy, and modify the Software for personal use.
|
||||
Users are also allowed and encouraged to submit corrections and modifications
|
||||
to the Software for the benefit of other users.
|
||||
|
||||
It is not allowed to reuse, modify, or redistribute the Software for
|
||||
commercial use in any way, or for a user’s educational materials such as books
|
||||
or blog articles without prior permission from the copyright holder.
|
||||
|
||||
The above copyright notice and this permission notice need to be included
|
||||
in all copies or substantial portions of the software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Apress Source Code
|
||||
|
||||
This repository accompanies [*Beginning Ansible Concepts and Application: Provisioning, Configuring, and Managing Servers, Applications and their Dependencies*](https://www.link.springer.com/book/10.1007/9781484281727) by Shaun R Smith and Peter Membrey (Apress, 2022).
|
||||
|
||||
[comment]: #cover
|
||||
![Cover image](9781484281727.JPG)
|
||||
|
||||
Download the files as a zip using the green button, or clone the repository to your machine using Git.
|
||||
|
||||
## Releases
|
||||
|
||||
Release v1.0 corresponds to the code in the published book, without corrections or updates.
|
||||
|
||||
## Contributions
|
||||
|
||||
See the file Contributing.md for more information on how you can contribute to this repository.
|
82
Vagrantfile
vendored
Normal file
82
Vagrantfile
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "ubuntu/focal64"
|
||||
|
||||
# globally disable the default synced folder
|
||||
config.vm.synced_folder ".", "/vagrant", disabled: true
|
||||
|
||||
# do not create a secure private key per host, we want to use a single key
|
||||
# this allows the controller to connect to the target hosts
|
||||
config.ssh.insert_key = false
|
||||
|
||||
# Set provider virtualbox to use GUI, for two reasons:
|
||||
# 1. More obvious to the user what is running, so they don't consume too much background resource
|
||||
# 2. To work around an x64 boot issue in Virtualbox when hardware virtualization is disabled in BIOS
|
||||
config.vm.provider "virtualbox" do |v|
|
||||
# v.gui = true
|
||||
v.cpus = 1
|
||||
end
|
||||
|
||||
# The Ansible controller machine
|
||||
config.vm.define :controller, primary: true do |controller|
|
||||
controller.vm.hostname = "ansible-controller"
|
||||
controller.vm.network "private_network", ip: "192.168.98.100"
|
||||
|
||||
# Sync the local directory with ansible-friendly permissions
|
||||
controller.vm.synced_folder ".", "/vagrant",
|
||||
owner: "vagrant",
|
||||
mount_options: ["dmode=755,fmode=644"]
|
||||
|
||||
controller.vm.provision "file", source: "~/.vagrant.d/insecure_private_key", destination: "$HOME/.ssh/id_rsa"
|
||||
|
||||
controller.vm.provision "shell", inline: <<-SHELL
|
||||
chmod 600 /home/vagrant/.ssh/id_rsa
|
||||
apt-get install -y ansible sshpass
|
||||
SHELL
|
||||
end
|
||||
|
||||
|
||||
# Example web servers
|
||||
(1..2).each do |i|
|
||||
config.vm.define "web-00#{i}" do |node|
|
||||
node.vm.hostname = "web-00#{i}"
|
||||
node.vm.network "private_network", ip: "192.168.98.11#{i}"
|
||||
end
|
||||
end
|
||||
|
||||
# Example load balancer
|
||||
(1..1).each do |i|
|
||||
config.vm.define "lb-00#{i}" do |node|
|
||||
node.vm.hostname = "lb-00#{i}"
|
||||
node.vm.network "private_network", ip: "192.168.98.12#{i}"
|
||||
end
|
||||
end
|
||||
|
||||
# Example database server
|
||||
(1..1).each do |i|
|
||||
config.vm.define "db-00#{i}" do |node|
|
||||
node.vm.hostname = "db-00#{i}"
|
||||
node.vm.network "private_network", ip: "192.168.98.13#{i}"
|
||||
end
|
||||
end
|
||||
|
||||
# Generic provisioner to ensure we have python available
|
||||
# This is an ansible requirement for all managed nodes
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
# Disable hardware based sha256sum in apt, not ideal - but Windows 10 WSL breaks VirtualBox
|
||||
# and we can't really ask everyone to disable that
|
||||
# See: https://askubuntu.com/questions/1235914/hash-sum-mismatch-error-due-to-identical-sha1-and-md5-but-different-sha256/1241893
|
||||
mkdir /etc/gcrypt
|
||||
echo all >> /etc/gcrypt/hwf.deny
|
||||
|
||||
apt-get update
|
||||
apt-get install -y python3-minimal python3-apt avahi-daemon tree
|
||||
|
||||
rm -f /etc/update-motd.d/*
|
||||
sed -i "s/^ENABLED=.*/ENABLED=0/" /etc/default/motd-news
|
||||
SHELL
|
||||
|
||||
config.vm.boot_timeout = 360
|
||||
end
|
3
chapter02/ansible.cfg
Normal file
3
chapter02/ansible.cfg
Normal file
|
@ -0,0 +1,3 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = hosts
|
2
chapter02/hosts
Normal file
2
chapter02/hosts
Normal file
|
@ -0,0 +1,2 @@
|
|||
web-001.local
|
||||
web-002.local
|
3
chapter03/ansible.cfg
Normal file
3
chapter03/ansible.cfg
Normal file
|
@ -0,0 +1,3 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
17
chapter03/hosts
Normal file
17
chapter03/hosts
Normal file
|
@ -0,0 +1,17 @@
|
|||
[webservers]
|
||||
web-001.local
|
||||
web-002 ansible_host=192.168.98.112 ansible_port=22
|
||||
|
||||
[webservers:vars]
|
||||
http_port=8080
|
||||
|
||||
[load_balancers]
|
||||
lb-001.local
|
||||
|
||||
[staging]
|
||||
web-002
|
||||
|
||||
[production]
|
||||
web-001.local
|
||||
lb-001.local
|
||||
|
4
chapter03/inventory/load_balancers
Normal file
4
chapter03/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
9
chapter03/inventory/webservers
Normal file
9
chapter03/inventory/webservers
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002:
|
||||
ansible_host: 192.168.98.112
|
||||
vars:
|
||||
http_port: 8080
|
||||
|
2
chapter03/ranges
Normal file
2
chapter03/ranges
Normal file
|
@ -0,0 +1,2 @@
|
|||
[webservers]
|
||||
web-0[01:10]
|
24
chapter03/regional
Normal file
24
chapter03/regional
Normal file
|
@ -0,0 +1,24 @@
|
|||
[germany]
|
||||
web-de-00[1:2]
|
||||
|
||||
[france]
|
||||
web-fr-001
|
||||
|
||||
[netherlands]
|
||||
web-nl-001
|
||||
|
||||
[spain]
|
||||
web-es-00[1:3]
|
||||
|
||||
[usa]
|
||||
web-us-00[1:4]
|
||||
|
||||
[europe:children]
|
||||
germany
|
||||
france
|
||||
netherlands
|
||||
spain
|
||||
|
||||
[americas:children]
|
||||
usa
|
||||
|
3
chapter04/ansible.cfg
Normal file
3
chapter04/ansible.cfg
Normal file
|
@ -0,0 +1,3 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
1
chapter04/files/index.html
Normal file
1
chapter04/files/index.html
Normal file
|
@ -0,0 +1 @@
|
|||
This is my website which was setup using Ansible
|
4
chapter04/inventory/load_balancers
Normal file
4
chapter04/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
9
chapter04/inventory/webservers
Normal file
9
chapter04/inventory/webservers
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002:
|
||||
ansible_host: 192.168.98.112
|
||||
vars:
|
||||
http_port: 8080
|
||||
|
15
chapter04/webservers.yml
Normal file
15
chapter04/webservers.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Push website content to the web root
|
||||
copy :
|
||||
src: index.html
|
||||
dest: /var/www/html/
|
||||
mode: u=rw,g=r,o=r
|
||||
|
4
chapter05/ansible.cfg
Normal file
4
chapter05/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
15
chapter05/exploring-apt.yml
Normal file
15
chapter05/exploring-apt.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- hosts: web-001.local
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: latest
|
||||
cache_valid_time: 60
|
||||
|
||||
- name: Uninstall tree command
|
||||
apt:
|
||||
name: tree
|
||||
state: absent
|
||||
|
1
chapter05/files/index.html
Normal file
1
chapter05/files/index.html
Normal file
|
@ -0,0 +1 @@
|
|||
This is my website which was setup using Ansible
|
4
chapter05/inventory/load_balancers
Normal file
4
chapter05/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
9
chapter05/inventory/webservers
Normal file
9
chapter05/inventory/webservers
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002:
|
||||
ansible_host: 192.168.98.112
|
||||
vars:
|
||||
http_port: 8080
|
||||
|
12
chapter05/upgrade.yml
Normal file
12
chapter05/upgrade.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
- hosts: web-001.local
|
||||
become: true
|
||||
tasks:
|
||||
- name: Upgrade all packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
|
||||
- name: Reboot the host
|
||||
reboot:
|
||||
|
41
chapter05/webservers.yml
Normal file
41
chapter05/webservers.yml
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Push website content to the web root
|
||||
copy:
|
||||
src: index.html
|
||||
dest: /var/www/html/
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: index.html also known as main.html
|
||||
file:
|
||||
state: link
|
||||
src: /var/www/html/index.html
|
||||
dest: /var/www/html/main.html
|
||||
|
||||
- name: Update the website content
|
||||
lineinfile:
|
||||
path: /var/www/html/index.html
|
||||
line: "Just re-decorating a little!"
|
||||
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: "Nginx Full"
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
4
chapter06/ansible.cfg
Normal file
4
chapter06/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
1
chapter06/files/index.html
Normal file
1
chapter06/files/index.html
Normal file
|
@ -0,0 +1 @@
|
|||
This is my website which was setup using Ansible
|
2
chapter06/inventory/group_vars/all
Normal file
2
chapter06/inventory/group_vars/all
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
2
chapter06/inventory/group_vars/webservers
Normal file
2
chapter06/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter06/inventory/load_balancers
Normal file
4
chapter06/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter06/inventory/webservers
Normal file
6
chapter06/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
|
15
chapter06/upgrade.yml
Normal file
15
chapter06/upgrade.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- hosts: web-001.local
|
||||
gather_facts: no
|
||||
become: true
|
||||
tasks:
|
||||
- name: Upgrade all packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
register: upgrade_result
|
||||
|
||||
- name: Reboot the host
|
||||
reboot:
|
||||
when: upgrade_result.changed
|
||||
|
48
chapter06/webservers.yml
Normal file
48
chapter06/webservers.yml
Normal file
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Change the nginx port
|
||||
replace:
|
||||
path: /etc/nginx/sites-enabled/default
|
||||
regexp: "listen [0-9]+"
|
||||
replace: "listen {{ http_port }}"
|
||||
|
||||
- name: Reload nginx for new config
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
|
||||
- name: Push website content to the web root
|
||||
copy:
|
||||
src: index.html
|
||||
dest: /var/www/html/
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ http_port }}"
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
||||
- name: Validate that the http_port is working
|
||||
wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: "{{ http_port }}"
|
||||
timeout: 5
|
||||
connection: local
|
||||
|
4
chapter07/ansible.cfg
Normal file
4
chapter07/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
17
chapter07/hostname.yml
Normal file
17
chapter07/hostname.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: Raw value for inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname }}"
|
||||
|
||||
- name: Uppercase inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname | upper }}"
|
||||
|
||||
- name: Raw value for inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname }}"
|
||||
|
2
chapter07/inventory/group_vars/all
Normal file
2
chapter07/inventory/group_vars/all
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
2
chapter07/inventory/group_vars/webservers
Normal file
2
chapter07/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter07/inventory/load_balancers
Normal file
4
chapter07/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter07/inventory/webservers
Normal file
6
chapter07/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
status_url: "status"
|
16
chapter07/templates/index.html.j2
Normal file
16
chapter07/templates/index.html.j2
Normal file
|
@ -0,0 +1,16 @@
|
|||
My website, served from {{ inventory_hostname }}
|
||||
|
||||
<p>
|
||||
IP Addresses:<br />
|
||||
{% for ip in ansible_all_ipv4_addresses %}
|
||||
{{ ip }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Operating System:<br />
|
||||
{% for key, value in ansible_lsb.items() %}
|
||||
{{ key }}: {{ value }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
14
chapter07/templates/nginx-default.j2
Normal file
14
chapter07/templates/nginx-default.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen {{ http_port }} default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
server_name _;
|
||||
|
||||
{% if status_url is defined -%}
|
||||
location /{{ status_url | default('status') }} {
|
||||
stub_status on;
|
||||
}
|
||||
{%- endif %}
|
||||
}
|
||||
|
15
chapter07/upgrade.yml
Normal file
15
chapter07/upgrade.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- hosts: web-001.local
|
||||
gather_facts: no
|
||||
become: true
|
||||
tasks:
|
||||
- name: Upgrade all packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
register: upgrade_result
|
||||
|
||||
- name: Reboot the host
|
||||
reboot:
|
||||
when: upgrade_result.changed
|
||||
|
48
chapter07/webservers.yml
Normal file
48
chapter07/webservers.yml
Normal file
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Configure nginx
|
||||
template:
|
||||
src: nginx-default.j2
|
||||
dest: /etc/nginx/sites-available/default
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Reload nginx for new config
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
|
||||
- name: Push website content to the web root
|
||||
template:
|
||||
src: index.html.j2
|
||||
dest: /var/www/html/index.html
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ http_port }}"
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
||||
- name: Validate that the http_port is working
|
||||
wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: "{{ http_port }}"
|
||||
timeout: 5
|
||||
connection: local
|
||||
|
4
chapter08/ansible.cfg
Normal file
4
chapter08/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
17
chapter08/hostname.yml
Normal file
17
chapter08/hostname.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: Raw value for inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname }}"
|
||||
|
||||
- name: Uppercase inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname | upper }}"
|
||||
|
||||
- name: Raw value for inventory_hostname
|
||||
debug:
|
||||
msg: "{{ inventory_hostname }}"
|
||||
|
2
chapter08/inventory/group_vars/all
Normal file
2
chapter08/inventory/group_vars/all
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
2
chapter08/inventory/group_vars/webservers
Normal file
2
chapter08/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter08/inventory/load_balancers
Normal file
4
chapter08/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter08/inventory/webservers
Normal file
6
chapter08/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
status_url: "status"
|
16
chapter08/templates/index.html.j2
Normal file
16
chapter08/templates/index.html.j2
Normal file
|
@ -0,0 +1,16 @@
|
|||
My website, served from {{ inventory_hostname }}
|
||||
|
||||
<p>
|
||||
IP Addresses:<br />
|
||||
{% for ip in ansible_all_ipv4_addresses %}
|
||||
{{ ip }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Operating System:<br />
|
||||
{% for key, value in ansible_lsb.items() %}
|
||||
{{ key }}: {{ value }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
14
chapter08/templates/nginx-default.j2
Normal file
14
chapter08/templates/nginx-default.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen {{ http_port }} default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
server_name _;
|
||||
|
||||
{% if status_url is defined -%}
|
||||
location /{{ status_url | default('status') }} {
|
||||
stub_status on;
|
||||
}
|
||||
{%- endif %}
|
||||
}
|
||||
|
15
chapter08/upgrade.yml
Normal file
15
chapter08/upgrade.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- hosts: web-001.local
|
||||
gather_facts: no
|
||||
become: true
|
||||
tasks:
|
||||
- name: Upgrade all packages
|
||||
apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
register: upgrade_result
|
||||
|
||||
- name: Reboot the host
|
||||
reboot:
|
||||
when: upgrade_result.changed
|
||||
|
52
chapter08/webservers.yml
Normal file
52
chapter08/webservers.yml
Normal file
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
handlers:
|
||||
- name: Reload nginx
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
listen: "Reload web services"
|
||||
|
||||
- name: Validate that the http_port is working
|
||||
wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: "{{ http_port }}"
|
||||
timeout: 5
|
||||
connection: local
|
||||
listen: "Reload web services"
|
||||
|
||||
tasks:
|
||||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Configure nginx
|
||||
template:
|
||||
src: nginx-default.j2
|
||||
dest: /etc/nginx/sites-available/default
|
||||
mode: u=rw,g=r,o=r
|
||||
notify: "Reload web services"
|
||||
|
||||
- name: Push website content to the web root
|
||||
template:
|
||||
src: index.html.j2
|
||||
dest: /var/www/html/index.html
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ http_port }}"
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
4
chapter09/ansible.cfg
Normal file
4
chapter09/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
2
chapter09/inventory/group_vars/all
Normal file
2
chapter09/inventory/group_vars/all
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
2
chapter09/inventory/group_vars/webservers
Normal file
2
chapter09/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter09/inventory/load_balancers
Normal file
4
chapter09/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter09/inventory/webservers
Normal file
6
chapter09/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
status_url: "status"
|
11
chapter09/roles/firewall/tasks/main.yml
Normal file
11
chapter09/roles/firewall/tasks/main.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
2
chapter09/roles/webserver/defaults/main.yml
Normal file
2
chapter09/roles/webserver/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
15
chapter09/roles/webserver/handlers/main.yml
Normal file
15
chapter09/roles/webserver/handlers/main.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: Reload nginx
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
listen: "Reload web services"
|
||||
|
||||
- name: Validate that the http_port is working
|
||||
wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: "{{ http_port }}"
|
||||
timeout: 5
|
||||
connection: local
|
||||
listen: "Reload web services"
|
||||
|
3
chapter09/roles/webserver/meta/main.yml
Normal file
3
chapter09/roles/webserver/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
dependencies:
|
||||
- role: firewall
|
23
chapter09/roles/webserver/tasks/main.yml
Normal file
23
chapter09/roles/webserver/tasks/main.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Configure nginx
|
||||
template:
|
||||
src: nginx-default.j2
|
||||
dest: /etc/nginx/sites-available/default
|
||||
mode: u=rw,g=r,o=r
|
||||
notify: "Reload web services"
|
||||
|
||||
- name: Push website content to the web root
|
||||
template:
|
||||
src: index.html.j2
|
||||
dest: /var/www/html/index.html
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ http_port }}"
|
||||
|
16
chapter09/roles/webserver/templates/index.html.j2
Normal file
16
chapter09/roles/webserver/templates/index.html.j2
Normal file
|
@ -0,0 +1,16 @@
|
|||
My website, served from {{ inventory_hostname }}
|
||||
|
||||
<p>
|
||||
IP Addresses:<br />
|
||||
{% for ip in ansible_all_ipv4_addresses %}
|
||||
{{ ip }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Operating System:<br />
|
||||
{% for key, value in ansible_lsb.items() %}
|
||||
{{ key }}: {{ value }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
14
chapter09/roles/webserver/templates/nginx-default.j2
Normal file
14
chapter09/roles/webserver/templates/nginx-default.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen {{ http_port }} default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
server_name _;
|
||||
|
||||
{% if status_url is defined -%}
|
||||
location /{{ status_url | default('status') }} {
|
||||
stub_status on;
|
||||
}
|
||||
{%- endif %}
|
||||
}
|
||||
|
8
chapter09/webservers.yml
Normal file
8
chapter09/webservers.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build webservers
|
||||
include_role:
|
||||
name: webserver
|
||||
|
4
chapter10/ansible.cfg
Normal file
4
chapter10/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
3
chapter10/inventory/group_vars/all
Normal file
3
chapter10/inventory/group_vars/all
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
http_port: 80
|
||||
https_port: 443
|
2
chapter10/inventory/group_vars/webservers
Normal file
2
chapter10/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter10/inventory/load_balancers
Normal file
4
chapter10/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter10/inventory/webservers
Normal file
6
chapter10/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
status_url: "status"
|
20
chapter10/provision.yml
Normal file
20
chapter10/provision.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build webservers
|
||||
include_role:
|
||||
name: webserver
|
||||
tags:
|
||||
- always
|
||||
|
||||
- hosts: load_balancers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build load balancers
|
||||
include_role:
|
||||
name: load_balancer
|
||||
tags:
|
||||
- always
|
||||
|
||||
|
15
chapter10/roles/firewall/tasks/main.yml
Normal file
15
chapter10/roles/firewall/tasks/main.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
tags:
|
||||
- firewall
|
||||
|
6
chapter10/roles/load_balancer/handlers/main.yml
Normal file
6
chapter10/roles/load_balancer/handlers/main.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- name: Reload HAProxy
|
||||
service:
|
||||
name: haproxy
|
||||
state: reloaded
|
||||
|
3
chapter10/roles/load_balancer/meta/main.yml
Normal file
3
chapter10/roles/load_balancer/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
dependencies:
|
||||
- role: firewall
|
42
chapter10/roles/load_balancer/tasks/main.yml
Normal file
42
chapter10/roles/load_balancer/tasks/main.yml
Normal file
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
- name: Install HAProxy
|
||||
apt:
|
||||
name: haproxy
|
||||
state: present
|
||||
cache_valid_time: 60
|
||||
|
||||
- name: Create configuration directory
|
||||
file:
|
||||
path: /etc/haproxy/fragments
|
||||
state: directory
|
||||
|
||||
- name: Copy original configuration file
|
||||
copy:
|
||||
src: /etc/haproxy/haproxy.cfg
|
||||
dest: /etc/haproxy/fragments/00_defaults.cfg
|
||||
remote_src: yes
|
||||
force: no
|
||||
|
||||
- name: Setup frontends
|
||||
template:
|
||||
src: frontends.cfg.j2
|
||||
dest: /etc/haproxy/fragments/40_frontends.cfg
|
||||
|
||||
- name: Build configuration from fragments
|
||||
assemble:
|
||||
src: /etc/haproxy/fragments/
|
||||
dest: /etc/haproxy/haproxy.cfg
|
||||
validate: "haproxy -f %s -c"
|
||||
notify: Reload HAProxy
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
loop:
|
||||
- "{{ http_port }}"
|
||||
- "{{ https_port }}"
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
|
6
chapter10/roles/load_balancer/templates/backends.cfg.j2
Normal file
6
chapter10/roles/load_balancer/templates/backends.cfg.j2
Normal file
|
@ -0,0 +1,6 @@
|
|||
backend web_servers
|
||||
balance roundrobin
|
||||
{% for host in groups.webservers %}
|
||||
server {{ host }} {{ host }}:{{ hostvars[host].http_port }}
|
||||
{% endfor %}
|
||||
|
4
chapter10/roles/load_balancer/templates/frontend.cfg.j2
Normal file
4
chapter10/roles/load_balancer/templates/frontend.cfg.j2
Normal file
|
@ -0,0 +1,4 @@
|
|||
frontend awesome_ansible
|
||||
bind *:{{ http_port }}
|
||||
stats uri /haproxy?stats
|
||||
default_backend web_servers
|
2
chapter10/roles/webserver/defaults/main.yml
Normal file
2
chapter10/roles/webserver/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 80
|
15
chapter10/roles/webserver/handlers/main.yml
Normal file
15
chapter10/roles/webserver/handlers/main.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: Reload nginx
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
listen: "Reload web services"
|
||||
|
||||
- name: Validate that the http_port is working
|
||||
wait_for:
|
||||
host: "{{ ansible_host }}"
|
||||
port: "{{ http_port }}"
|
||||
timeout: 5
|
||||
connection: local
|
||||
listen: "Reload web services"
|
||||
|
3
chapter10/roles/webserver/meta/main.yml
Normal file
3
chapter10/roles/webserver/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
dependencies:
|
||||
- role: firewall
|
25
chapter10/roles/webserver/tasks/main.yml
Normal file
25
chapter10/roles/webserver/tasks/main.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
- name: Ensure nginx is installed
|
||||
apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Configure nginx
|
||||
template:
|
||||
src: nginx-default.j2
|
||||
dest: /etc/nginx/sites-available/default
|
||||
mode: u=rw,g=r,o=r
|
||||
notify: "Reload web services"
|
||||
|
||||
- name: Push website content to the web root
|
||||
template:
|
||||
src: index.html.j2
|
||||
dest: /var/www/html/index.html
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
- name: Firewall - Allow website connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ http_port }}"
|
||||
tags:
|
||||
- firewall
|
||||
|
16
chapter10/roles/webserver/templates/index.html.j2
Normal file
16
chapter10/roles/webserver/templates/index.html.j2
Normal file
|
@ -0,0 +1,16 @@
|
|||
My website, served from {{ inventory_hostname }}
|
||||
|
||||
<p>
|
||||
IP Addresses:<br />
|
||||
{% for ip in ansible_all_ipv4_addresses %}
|
||||
{{ ip }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Operating System:<br />
|
||||
{% for key, value in ansible_lsb.items() %}
|
||||
{{ key }}: {{ value }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
14
chapter10/roles/webserver/templates/nginx-default.j2
Normal file
14
chapter10/roles/webserver/templates/nginx-default.j2
Normal file
|
@ -0,0 +1,14 @@
|
|||
server {
|
||||
listen {{ http_port }} default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
server_name _;
|
||||
|
||||
{% if status_url is defined -%}
|
||||
location /{{ status_url | default('status') }} {
|
||||
stub_status on;
|
||||
}
|
||||
{%- endif %}
|
||||
}
|
||||
|
4
chapter11/ansible.cfg
Normal file
4
chapter11/ansible.cfg
Normal file
|
@ -0,0 +1,4 @@
|
|||
[defaults]
|
||||
host_key_checking = false
|
||||
inventory = inventory
|
||||
stdout_callback = yaml
|
4
chapter11/inventory/databases
Normal file
4
chapter11/inventory/databases
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
databases:
|
||||
hosts:
|
||||
db-001.local:
|
11
chapter11/inventory/group_vars/all
Normal file
11
chapter11/inventory/group_vars/all
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
http_port: 80
|
||||
https_port: 443
|
||||
|
||||
database:
|
||||
host: db-001.local
|
||||
name: wordpress
|
||||
username: wordpress_rw
|
||||
password: SomeSuperStrongPassword
|
||||
root_password: EvenStrongerPassword
|
||||
|
2
chapter11/inventory/group_vars/webservers
Normal file
2
chapter11/inventory/group_vars/webservers
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
http_port: 8080
|
4
chapter11/inventory/load_balancers
Normal file
4
chapter11/inventory/load_balancers
Normal file
|
@ -0,0 +1,4 @@
|
|||
load_balancers:
|
||||
hosts:
|
||||
lb-001.local:
|
||||
|
6
chapter11/inventory/webservers
Normal file
6
chapter11/inventory/webservers
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
webservers:
|
||||
hosts:
|
||||
web-001.local:
|
||||
web-002.local:
|
||||
status_url: "status"
|
35
chapter11/provision.yml
Normal file
35
chapter11/provision.yml
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
- hosts: webservers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build webservers
|
||||
include_role:
|
||||
name: webserver
|
||||
tags:
|
||||
- always
|
||||
|
||||
- name: Install Wordpress
|
||||
include_role:
|
||||
name: wordpress
|
||||
tags:
|
||||
- always
|
||||
|
||||
- hosts: databases
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build Databases
|
||||
include_role:
|
||||
name: database
|
||||
tags:
|
||||
- always
|
||||
|
||||
- hosts: load_balancers
|
||||
become: true
|
||||
tasks:
|
||||
- name: Build load balancers
|
||||
include_role:
|
||||
name: load_balancer
|
||||
tags:
|
||||
- always
|
||||
|
||||
|
5
chapter11/roles/database/handlers/main.yml
Normal file
5
chapter11/roles/database/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: Restart MySQL
|
||||
service:
|
||||
name: mysql
|
||||
state: restarted
|
50
chapter11/roles/database/tasks/main.yml
Normal file
50
chapter11/roles/database/tasks/main.yml
Normal file
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
- name: Install MySQL
|
||||
apt:
|
||||
name:
|
||||
- mysql-server
|
||||
- python3-pymysql
|
||||
state: present
|
||||
|
||||
- name: Set the root password
|
||||
mysql_user:
|
||||
name: root
|
||||
password: "{{ database.root_password }}"
|
||||
state: present
|
||||
login_user: root
|
||||
login_password: "{{database.root_password }}"
|
||||
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||
no_log: True
|
||||
|
||||
- name: Create the wordpress database
|
||||
mysql_db:
|
||||
name: "{{ database.name }}"
|
||||
state: present
|
||||
login_user: root
|
||||
login_password: "{{database.root_password }}"
|
||||
|
||||
- name: Create the wordpress user
|
||||
mysql_user:
|
||||
name: "{{ database.username }}"
|
||||
password: "{{database.password }}"
|
||||
priv: "{{ database.name }}.*:ALL"
|
||||
host: "%"
|
||||
state: present
|
||||
login_user: root
|
||||
login_password: "{{database.root_password }}"
|
||||
no_log: True
|
||||
|
||||
- name: Ensure MySQL listens on the network
|
||||
lineinfile:
|
||||
path: /etc/mysql/mysql.conf.d/mysqld.cnf
|
||||
regexp: '^bind-address'
|
||||
line: 'bind-address = 0.0.0.0'
|
||||
notify:
|
||||
- Restart MySQL
|
||||
|
||||
- name: Firewall - Allow database connections
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "3306"
|
||||
tags:
|
||||
- firewall
|
15
chapter11/roles/firewall/tasks/main.yml
Normal file
15
chapter11/roles/firewall/tasks/main.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: Firewall - Allow SSH connections
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
- name: Firewall - Deny everything else
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
tags:
|
||||
- firewall
|
||||
|
6
chapter11/roles/load_balancer/handlers/main.yml
Normal file
6
chapter11/roles/load_balancer/handlers/main.yml
Normal file