Students will be able to understand
ANSIBLE_KEEP_ALL_FILES=True ansible -i hosts ...
$ cat ansible.cfg
[defaults]
...
Each section has its own directives
[defaults]
hostfile = hosts
private_key_file = ~/.ssh/id_rsa
...
[defaults]
hostfile = hosts
private_key_file = /Users/username/.ssh/id_rsa
nocows = 1
forks = 50
transport = ssh
remote_user = ansibleuser
ask_sudo_pass = True
ask_vault_pass = True
roles_path = roles
[ssh_connection]
pipelining = True
scp_if_ssh = True
placeholder for diagram to show smart, openssh, and paramiko?
http://docs.ansible.com/playbooks_acceleration.html
I mustache you a question.
{{ variable }}
{% for server in groups.webservers %}
{% for server in groups.webservers %}
{{ hostvars[server].ansible_default_ipv4.address }}
{% endfor %}
{% if server == inventory_hostname %}
{{ 127.0.0.1 }}
{% else if server in groups.database %}
{{ hostvars[server].ansible_eth1.address }}
{% else %}
{{ hostvars[server].ansible_default_ipv4.address }}
{% endif %}
The "hostvars" variable contains facts for all hosts that have had facts gathered.
hostvars['web01'].ansible_eth1.address
Ansible configures jinja2 with a set of sane defaults. In some cases these defaults are not optimal, usually in the case of variable_start_string or trim_blocks. The first line of a jinja2 template can include a jinja2 environment configuration line
#jinja2:variable_start_string:'[%' , variable_end_string:'%]'
In some cases there will not be Jinja2 filters that do what you want, such as a lack of a "split" filter. This can be achieved using the ".split()" method on a python string object.
{% set servers = "server1,server2,server3" %}
{% for server in servers.split(",") %}
{{ server }}
{% endfor %}
Jinja2 provides you with a number of filters and tests to manipulate and test data. Ansible also provides a number of filters.
http://docs.ansible.com/playbooks_variables.html#jinja2-filters
Filters are invoked similarly to unix shell pipes and manipulate variables and return the results
variable | replace("-", "_")
Tests can be used to test a variable against a common expression
{% if variable is defined %}
What is your variable and where does it go?
Variables will override each other depending on where they are defined:
Let's go over the various locations you can define variables.
There are a couple of methods for defining variables in your inventory:
localhost ansible_connection=local
[web]
web1.example.com ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50
web2.example.com ansible_ssh_user=mdehaan
[db]
db01.example.com mysql_max_connections=100
[web:vars]
apache_max_clients=100
Here is an example of defining variables in a playbook:
- hosts: webservers
vars:
http_port: 80
You can also override variables from the command line:
ansible-playbook release.yml --extra-vars "version=1.23.45 other_var=foo"
Here is an example of including a variable file based on a condition:
- name: Includiung OS specific variables
include_vars: '{{ ansible_os_family }}.yml'
Ansible Roles also have variables that can be defined:
System facts are sourced from the following sources:
Run the setup module against your local machine to see what returns.
ansible localhost -m setup --connection=local
Here is a sampling of facts discovered by the setup module:
localhost | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.1.37",
"172.17.42.1"
],
"ansible_all_ipv6_addresses": [
"fe80::c685:8ff:fe3b:a916"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "01/29/2013",
"ansible_bios_version": "UX32A.214",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.13.0-27-generic.efi.signed",
"quiet": true,
"ro": true,
"root": "/dev/mapper/kubuntu--vg-root",
"splash": true,
"vt.handoff": "7"
},
"ansible_date_time": {
"date": "2014-05-30",
"day": "30",
"epoch": "1401460386",
"hour": "09",
"iso8601": "2014-05-30T14:33:06Z",
"iso8601_micro": "2014-05-30T14:33:06.057018Z",
"minute": "33",
"month": "05",
"second": "06",
"time": "09:33:06",
"tz": "CDT",
"tz_offset": "-0500",
"weekday": "Friday",
"year": "2014"
},
"ansible_default_ipv4": {
"address": "192.168.1.37",
"alias": "wlan0",
"gateway": "192.168.1.1",
"interface": "wlan0",
"macaddress": "c4:85:08:3b:a9:16",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.1.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_devices": {
"sda": {
"holders": [],
"host": "SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04)",
"model": "Hitachi HTS54323",
"partitions": {
"sda1": {
"sectors": "625137282",
"sectorsize": 512,
"size": "298.09 GB",
"start": "63"
}
},
"removable": "0",
"rotational": "1",
"scheduler_mode": "deadline",
"sectors": "625142448",
"sectorsize": "512",
"size": "298.09 GB",
"support_discard": "0",
"vendor": "ATA"
},
"sdb": {
"holders": [],
"host": "SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04)",
"model": "SanDisk SSD i100",
"partitions": {
"sdb1": {
"sectors": "997376",
"sectorsize": 512,
"size": "487.00 MB",
"start": "2048"
},
"sdb2": {
"sectors": "499712",
"sectorsize": 512,
"size": "244.00 MB",
"start": "999424"
},
"sdb3": {
"sectors": "45404160",
"sectorsize": 512,
"size": "21.65 GB",
"start": "1499136"
}
},
"removable": "0",
"rotational": "0",
"scheduler_mode": "deadline",
"sectors": "46905264",
"sectorsize": "512",
"size": "22.37 GB",
"support_discard": "512",
"vendor": "ATA"
},
"sdc": {
"holders": [],
"host": "USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (rev 04)",
"model": "xD/SD/M.S.",
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "deadline",
"sectors": "0",
"sectorsize": "512",
"size": "0.00 Bytes",
"support_discard": "0",
"vendor": "Generic-"
}
},
"ansible_distribution": "Ubuntu",
"ansible_distribution_major_version": "14",
"ansible_distribution_release": "trusty",
"ansible_distribution_version": "14.04",
"ansible_docker0": {
"active": false,
"device": "docker0",
"id": "8000.56847afe9799",
"interfaces": [],
"ipv4": {
"address": "172.17.42.1",
"netmask": "255.255.0.0",
"network": "172.17.0.0"
},
"macaddress": "56:84:7a:fe:97:99",
"mtu": 1500,
"promisc": false,
"stp": false,
"type": "bridge"
},
"ansible_domain": "onitato.com",
"ansible_env": {
"COLORFGBG": "15;0",
"DBUS_SESSION_BUS_ADDRESS": "unix:abstract=/tmp/dbus-0Rf33lsHZU",
"DEFAULTS_PATH": "/usr/share/gconf/kde-plasma.default.path",
"DESKTOP_SESSION": "kde-plasma",
"DISPLAY": ":0",
"GDMSESSION": "kde-plasma",
"GDM_LANG": "en_US",
"GNOME_KEYRING_CONTROL": "/run/user/1000/keyring-tJuVCy",
"GNOME_KEYRING_PID": "2128",
"GPG_AGENT_INFO": "/tmp/gpg-c2qDOe/S.gpg-agent:2257:1",
"GS_LIB": "/home/linuturk/.fonts",
"GTK2_RC_FILES": "/etc/gtk-2.0/gtkrc:/home/linuturk/.gtkrc-2.0:/home/linuturk/.kde/share/config/gtkrc-2.0",
"GTK_RC_FILES": "/etc/gtk/gtkrc:/home/linuturk/.gtkrc:/home/linuturk/.kde/share/config/gtkrc",
"HOME": "/home/linuturk",
"IM_CONFIG_PHASE": "1",
"INSTANCE": "",
"JOB": "dbus",
"KDE_FULL_SESSION": "true",
"KDE_MULTIHEAD": "false",
"KDE_SESSION_UID": "1000",
"KDE_SESSION_VERSION": "4",
"KONSOLE_DBUS_SERVICE": ":1.410",
"KONSOLE_DBUS_SESSION": "/Sessions/2",
"KONSOLE_DBUS_WINDOW": "/Windows/1",
"KONSOLE_PROFILE_NAME": "Shell",
"LANG": "en_US.UTF-8",
"LANGUAGE": "en_US:en",
"LC_CTYPE": "en_US.UTF-8",
"LESSCLOSE": "/usr/bin/lesspipe %s %s",
"LESSOPEN": "| /usr/bin/lesspipe %s",
"LOGNAME": "linuturk",
"LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:",
"MANDATORY_PATH": "/usr/share/gconf/kde-plasma.mandatory.path",
"PAM_KWALLET_LOGIN": "/tmp//linuturk.socket",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games",
"PROFILEHOME": "",
"PWD": "/home/linuturk/github/ansible-sprint/advanced",
"QT_PLUGIN_PATH": "/home/linuturk/.kde/lib/kde4/plugins/:/usr/lib/kde4/plugins/",
"SELINUX_INIT": "YES",
"SESSION": "kde-plasma",
"SESSIONTYPE": "",
"SESSION_MANAGER": "local/arrow:@/tmp/.ICE-unix/2442,unix/arrow:/tmp/.ICE-unix/2442",
"SHELL": "/bin/bash",
"SHELL_SESSION_ID": "559b7b8e474c4000aa16e447d32e4b27",
"SHLVL": "1",
"SSH_AGENT_LAUNCHER": "upstart",
"SSH_AGENT_PID": "2259",
"SSH_AUTH_SOCK": "/tmp/ssh-NgX9DMrVWBek/agent.2253",
"TERM": "xterm",
"TEXTDOMAIN": "im-config",
"TEXTDOMAINDIR": "/usr/share/locale/",
"UPSTART_EVENTS": "started xsession",
"UPSTART_INSTANCE": "",
"UPSTART_JOB": "startkde",
"UPSTART_SESSION": "unix:abstract=/com/ubuntu/upstart-session/1000/2133",
"USER": "linuturk",
"WINDOWID": "71303194",
"XAUTHORITY": "/tmp/kde-linuturk/xauth-1000-_0",
"XCURSOR_THEME": "oxy-white",
"XDG_CONFIG_DIRS": "/etc/xdg/xdg-kde-plasma:/usr/share/upstart/xdg:/etc/xdg",
"XDG_CURRENT_DESKTOP": "KDE",
"XDG_DATA_DIRS": "/usr/share:/usr/share/kde-plasma:/usr/local/share/:/usr/share/",
"XDG_GREETER_DATA_DIR": "/var/lib/lightdm-data/linuturk",
"XDG_RUNTIME_DIR": "/run/user/1000",
"XDG_SEAT": "seat0",
"XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0",
"XDG_SESSION_ID": "c2",
"XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session0",
"XDG_VTNR": "7",
"_": "/usr/local/bin/ansible"
},
"ansible_form_factor": "Notebook",
"ansible_fqdn": "arrow.onitato.com",
"ansible_hostname": "arrow",
"ansible_interfaces": [
"lo",
"docker0",
"wlan0"
],
"ansible_kernel": "3.13.0-27-generic",
"ansible_lo": {
"active": true,
"device": "lo",
"ipv4": {
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 65536,
"promisc": false,
"type": "loopback"
},
"ansible_lsb": {
"codename": "trusty",
"description": "Ubuntu 14.04 LTS",
"id": "Ubuntu",
"major_release": "14",
"release": "14.04"
},
"ansible_machine": "x86_64",
"ansible_memfree_mb": 677,
"ansible_memtotal_mb": 9884,
"ansible_mounts": [
{
"device": "/dev/mapper/kubuntu--vg-root",
"fstype": "ext4",
"mount": "/",
"options": "rw,errors=remount-ro",
"size_available": 9636679680,
"size_total": 22740668416
},
{
"device": "/dev/sdb2",
"fstype": "ext2",
"mount": "/boot",
"options": "rw",
"size_available": 132574208,
"size_total": 247772160
},
{
"device": "/dev/sdb1",
"fstype": "vfat",
"mount": "/boot/efi",
"options": "rw",
"size_available": 506130432,
"size_total": 509640704
},
{
"device": "/dev/mapper/kubuntu--home--vg-home",
"fstype": "ext4",
"mount": "/home",
"options": "rw",
"size_available": 186540474368,
"size_total": 304337379328
}
],
"ansible_nodename": "arrow",
"ansible_os_family": "Debian",
"ansible_pkg_mgr": "apt",
"ansible_processor": [
"Intel(R) Core(TM) i3-2367M CPU @ 1.40GHz",
"Intel(R) Core(TM) i3-2367M CPU @ 1.40GHz",
"Intel(R) Core(TM) i3-2367M CPU @ 1.40GHz",
"Intel(R) Core(TM) i3-2367M CPU @ 1.40GHz"
],
"ansible_processor_cores": 2,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 2,
"ansible_processor_vcpus": 4,
"ansible_product_name": "UX32A",
"ansible_product_serial": "NA",
"ansible_product_uuid": "NA",
"ansible_product_version": "1.0",
"ansible_python_version": "2.7.6",
"ansible_selinux": false,
"ansible_swapfree_mb": 10211,
"ansible_swaptotal_mb": 10239,
"ansible_system": "Linux",
"ansible_system_vendor": "ASUSTeK COMPUTER INC.",
"ansible_user_id": "linuturk",
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "host",
"ansible_virtualization_type": "kvm",
"ansible_wlan0": {
"active": true,
"device": "wlan0",
"ipv4": {
"address": "192.168.1.37",
"netmask": "255.255.255.0",
"network": "192.168.1.0"
},
"ipv6": [
{
"address": "fe80::c685:8ff:fe3b:a916",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "c4:85:08:3b:a9:16",
"module": "iwlwifi",
"mtu": 1500,
"promisc": false,
"type": "ether"
},
"module_setup": true
},
"changed": false
}
Here is how you reference these variables:
{{ ansible_devices.sda.model }}
{{ ansible_hostname }}
You can set facts manually in a play using the set_facts module:
# Example setting host facts using key=value pairs
- set_fact: one_fact="something" other_fact="{{ local_var * 2 }}"
# Example setting host facts using complex arguments
- set_fact:
one_fact: something
other_fact: "{{ local_var * 2 }}"
You can place files ending in '.fact' in the /etc/ansible/facts.d directory. These can be JSON, INI, or executable files. Here is an example file:
[general]
asdf=1
bar=2
And here is how you reference the asdf variable.
{{ ansible_local.preferences.general.asdf }}
You've seen several examples of variables being referenced. The same method is used to reference these variables in Jinja2 templates.
{{ variable_name }}
There are many useful filters you can use in your Jinja2 templates. Here are a few useful ones:
# Combine two lists
{{ list1 | union(list2) }}
# Get a random number
{{ 59 | random }} * * * * root /script/from/cron
# md5sum of a filename
{{ filename | md5 }}
# Comparisons
{{ ansible_distribution_version | version_compare('12.04', '>=') }}
You can provide a default value for a variable using the following filter:
{{ some_variable | default("foobar") }}
Ansible provides information about other hosts though a series of 'magic variables'.
Hostvars let you ask about the variables of another host, including facts that have been gathered about that host.
{{ hostvars['test.example.com']['ansible_distribution'] }}
The group_names variable contains a list of all the groups the current host is in.
{% if 'webserver' in group_names %}
# some part of a configuration file that only applies to webservers
{% endif %}
groups is a list of all the groups (and hosts) in the inventory.
{% for host in groups['app_servers'] %}
# something that applies to all app servers.
{% endfor %}
Given this play, override the local_var variable using the command line flag.
- hosts: localhost
connection: local
vars:
- local_var: "override me"
tasks:
- name: print out the variable
debug: msg="This should not output 'override me' - {{ local_var }}"
ansible-playbook variable_override.yml --extra-vars "local_var=foobar"
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [print out the variable] ************************************************
ok: [localhost] => {
"msg": "This should not output 'override me' - foobar"
}
PLAY RECAP ********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
$ ./docker.py (--list | --host)
$ ansible -i ./docker.py --list-hosts running
suspicious_ptolemy
ecstatic_albattani
$ tree
.
├── common.yml
├── prod
│ ├── docker.py
│ └── servers
└── site.yml
1 directory, 4 files
$ ansible-playbook -i prod site.yml
For Ubuntu 14.04 Controller Setup
Example credentials file (~/.rackspace_cloud_credentials):
[rackspace_cloud]
username=cloudaccountname
api_key=$#!TuCnP0rt@l
For CentOS 7 Controller Setup
Example credentials file (~/.rackspace_cloud_credentials)
[rackspace_cloud]
username = somenameyouchosetocallyourdamnaccount
api_key = Go0bld13g00k$#!T1337
What are you trying to hide?
Ansible Vault is a tool to encrypt YAML variables files that may contain sensitive data.
ansible-vault create secrets.yml
ansible-vault edit secrets.yml
ansible-vault rekey secrets.yml
ansible-vault encrypt secrets.yml
ansible-vault decrypt secrets.yml
ansible-playbook --ask-vault-pass vault-test.yml
ansible-playbook --vault-password-file ../vault-pw vault-test.yml
Reusing and sharing Ansible content.
Roles use specific file structures.
site.yml
roles/
role1/
files/
templates/
tasks/
handlers/
vars/
meta/
---
- hosts: webservers
roles:
- common
- webservers
---
- hosts: webservers
roles:
- common
- { role: foo, dir: '/opt/a', port: 5000 }
- { role: foo, dir: '/opt/b', port: 5001 }
---
- hosts: webservers
roles:
- { role: foo, when: "ansible_os_family == 'RedHat'" }
---
- hosts: webservers
pre_tasks:
- shell: echo 'Hello.'
roles:
- { role: some_role }
tasks:
- shell: echo 'I called a role!'
post_tasks:
- shell: echo 'Goodbye.'
It is possible to set default variables for your roles.
Role Dependencies allow for roles to automatically pull in other roles.
---
dependencies:
- { role: common, some_parameter: 3 }
- { role: apache, port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 }
You can call a role dependency multiple times with various parameters.
---
allow_duplicates: yes
dependencies:
- { role: apache, port: 80 }
- { role: apache, port: 8080 }
Role-specific custom modules can be packaged with the role.
roles/
my_role/
library/
module1
module2
- hosts: webservers
roles:
- my_role
Sharing is caring. visit http://galaxy.ansible.com
ansible-galaxy init mynewrole
I like things done my way but by somebody else.
Task control keyword: delegate_to
- name: take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: localhost
- name: update packages
yum: name=acme-web-stack state=latest
- name: add back to load balancer pool
command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
delegate_to: localhost
Delegation most often targets another host in your inventory
Uses connection variable data from delegate target
Delegation: not just limited to hosts in your inventory
Make use of add_host to adjust connection details
- name: add delegation host
add_host: name=hubert ansible_ssh_host=192.168.10.2
ansible_ssh_user=fred
Create an ephemeral host and delegate a task to it
---
- name: test play
hosts: localhost
tasks:
- name: add delegation host
add_host: name=hubert ansible_ssh_host=192.168.10.2
ansible_ssh_user=fred
- name: silly echo
command: echo {{ inventory_hostname }}
delegate_to: hubert
$ ansible-playbook test-play.yml -vvvv
Delegated tasks will run for every host in the loop
Tasks will run with configured forks / serial
Be aware of race conditions and concurrency issues
---
- name: MySQL Users
hosts: webservers
tasks:
- name: add a mysql user for the server
mysql_user: name={{ db_username }} host={{ inventory_hostname }}
password='{{ db_password }}' priv='ansible.*:ALL'
state=present
delegate_to: databases[0]
When ran with -vvvv one can clearly see the connection debugging output which will show the delegation in action.
Create playbook and a jinja2 template to achieve the following results
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
{% for server in groups['webservers'] %}
-A INPUT -p tcp -s {{ hostvars[server].ansible_eth1.ipv4.address }} -i eth1 -d {{ ansible_eth1.ipv4.address }} --dport 3306 -j ACCEPT
{% endfor %}
{% for server in groups['databases'] %}
{% if server != inventory_hostname %}
-A INPUT -p tcp -s {{ hostvars[server].ansible_eth1.ipv4.address }} -i eth1 -d {{ ansible_eth1.ipv4.address }} --dport 3306 -j ACCEPT
{% endif %}
{% endfor %}
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
---
- hosts: webservers
gather_facts: true
- hosts: databases
handlers:
- name: Reload iptables
service: name=iptables state=reloaded
tasks:
- name: Template /etc/sysconfig/iptables
template: src=templates/iptables.j2 dest=/etc/sysconfig/iptables
notify: Reload iptables
- name: Ensure iptables is started and enabled
service: name=iptables state=started enabled=yes
fin