A template
is one of the core modules of Ansible. It is used to easily generate files (for example, configuration files) based on a common set of facts. It uses the Jinja2 template engine to interpret template files.
For this recipe, we'll use a simple kickstart
script that is generic enough to deploy any host. Refer to Chapter 2, Deploying RHEL "En Masse", to find out about kickstart
files.
The facts that we need for this host are repo_url
, root_password_hash
, ntp_servers
, timezone
, ipv4_address
, ipv4_netmask
, ipv4_gateway
, and dns_servers
.
Create the kickstart
file in your playbook's template folder (~/playbooks/templates/kickstart/rhel7.ks
) with the following content:
install url --url={{ repo_url }} skipx text reboot lang en_US.UTF-8 keyboard us selinux --enforcing firewall --enabled --ssh rootpw –iscrypted {{ root_password_hash }} authconfig --enableshadow --passalgo=sha512 timezone --utc --ntpservers {{ ntp_servers|join(',') }} {{ timezone }} zerombr clearpart --all bootloader --location=mbr --timeout=5 part /boot --asprimary --fstype="xfs" --size=1024 --ondisk=sda part pv.1 --size=1 --grow --ondisk=sda volgroup {{ hostname }}_system pv.1 logvol / --vgname={{ inventory_hostname }}_system --size=2048 --name=root --fstype=xfs logvol /usr --vgname={{ inventory_hostname }}_system --size=2048 --name=usr --fstype=xfs logvol /var --vgname={{ inventory_hostname }}_system --size=2048 --name=var --fstype=xfs logvol /var/log --vgname={{ inventory_hostname }}_system --size=2048 --name=varlog --fstype=xfs logvol swap --vgname={{ inventory_hostname }}_system --recommended --name=swap --fstype=swap network --device=eth0 --bootproto=static --onboot=yes --activate --ip={{ ipv4_address }} --netmask={{ ipv4_netmask }} --gateway={{ ipv4_gateway }} --nameserver={{ dns_servers|join(',') }} %packages --excludedocs @Core vim-enhanced %end
The Jinja2 engine replaces all the variables enclosed by {{ }}
with whichever facts are available for the specified host in the inventory, resulting in a correct kickstart
file, assuming all variables have been correctly set.
Jinja2 can do more than just replace variables with whatever is in the inventory. It was originally developed as a rich templating language for web pages and supports major features such as conditions, loops, and so on.
Using Jinja, you can easily loop over a list or array within the inventory and use the resultant variable or even dictionaries and objects. For example, consider that your host has the following fact:
{ 'nics': [ { 'device': 'eth0', 'ipv4': { 'address':'192.168.0.100', 'netmask':'255.255.255.0','gateway':'192.168.0.1'} }, { 'device': 'eth1', 'ipv4': { 'address':'192.168.1.100', 'netmask':'255.255.255.0','gateway':'192.168.1.1'} } ] }
This would allow you to replace the network portion of your kickstart
script with the following:
{% for nic in nics %} network –device={{ nic.device }} --bootproto=static --onboot=yes --activate --ip={{ nic.ipv4.address }} --netmask={{ nic.ipv4.netmask }} --gateway={{ nic.ipv4.gateway }} {% endfor %}
There is one consideration with provisioning new systems such as this and the inventory: you can only use the facts that you have introduced yourself, not those that Ansible gets from the system. This is because firstly, they don't exist yet, and secondly, the task is executed on a different host.
For more information about templating with Ansible, read the Jinja2 Template Designer documentation at http://jinja.pocoo.org/docs/dev/templates/.
For more information on the Ansible template module, go to http://docs.ansible.com/ansible/template_module.html.