An approach to explaining precedence more by convention.
This commit is contained in:
parent
33d13a6888
commit
585b4d03a8
1 changed files with 453 additions and 13 deletions
|
@ -2,21 +2,45 @@ Variables
|
|||
=========
|
||||
|
||||
All of your systems are likely not the same. On some systems you may want to set some behavior
|
||||
or configuration that is slightly different from others. Also, some of the observed behavior or state
|
||||
of remote systems might need to influence how you configure those systems.
|
||||
or configuration that is slightly different from others.
|
||||
|
||||
Also, some of the observed behavior or state
|
||||
of remote systems might need to influence how you configure those systems. (Such as you can find out the IP
|
||||
address of a system and even use it as a configuration value on ANOTHER system).
|
||||
|
||||
You might have some templates for configuration files that are mostly the same, but slightly different
|
||||
based on those variables.
|
||||
|
||||
Variables in Ansible are how we manage with differences between systems. Once understanding variables you'll
|
||||
also want to dig into `playbooks_conditionals` and `playbooks_loops`.
|
||||
Variables in Ansible are how we deal with differences between systems.
|
||||
|
||||
Once understanding variables you'll also want to dig into `playbooks_conditionals` and `playbooks_loops`.
|
||||
Useful things like the "group_by" module
|
||||
and the "when" conditional can also be used with variables, and to help manage differences between systems.
|
||||
|
||||
It's highly recommended that you consult `the Ansible-Examples github repository <http://github.com/ansible/ansible-examples/>_` to see a lot of examples of variables put to use.
|
||||
|
||||
.. contents::
|
||||
:depth: 2
|
||||
|
||||
What Makes A Valid Variable Name
|
||||
````````````````````````````````
|
||||
|
||||
Before we start using variables it's important to know what are valid variable names.
|
||||
|
||||
Variable names should be letters, numbers, and underscores. Variables should always start with a letter.
|
||||
|
||||
"foo_port" is a great variable. "foo5" is fine too.
|
||||
|
||||
"foo-port", "foo port", "foo.port" and "12" are not valid variable names.
|
||||
|
||||
Easy enough, let's move on.
|
||||
|
||||
Variables Defined in Inventory
|
||||
``````````````````````````````
|
||||
|
||||
We've actually already covered a lot about variables in another section, so so far this shouldn't be terribly new, but
|
||||
a bit of a refresher.
|
||||
|
||||
Often you'll want to set variables based on what groups a machine is in. For instance, maybe machines in Boston
|
||||
want to use 'boston.ntp.example.com' as an NTP server.
|
||||
|
||||
|
@ -33,8 +57,10 @@ In a playbook, it's possible to define variables directly inline like so::
|
|||
|
||||
This can be nice as it's right there when you are reading the playbook.
|
||||
|
||||
Variables defined from includes
|
||||
-------------------------------
|
||||
Variables defined from included files and roles
|
||||
-----------------------------------------------
|
||||
|
||||
It turns out we've already talked about variables in another place too.
|
||||
|
||||
As described in `intro_roles`, variables can also be included in the playbook via include files, which may or may
|
||||
not be part of an "Ansible Role". Usage of roles is preferred as it provides a nice organizational system.
|
||||
|
@ -42,9 +68,11 @@ not be part of an "Ansible Role". Usage of roles is preferred as it provides a
|
|||
Using Variables: About Jinja2
|
||||
`````````````````````````````
|
||||
|
||||
We've referenced various ways to define variables above, but how do you reference them? Ansible allows you to
|
||||
It's nice enough to know about how to define variables, but how do you use them?
|
||||
|
||||
Ansible allows you to
|
||||
reference variables in your playbooks using the Jinja2 templating system. While you can do a lot of complex
|
||||
things in Jinja, only the basics are things you really need to learn.
|
||||
things in Jinja, only the basics are things you really need to learn at first.
|
||||
|
||||
For instance, in a simple template, you can do something like
|
||||
|
||||
|
@ -56,15 +84,40 @@ This is also valid directly in playbooks, and you'll occasionally want to do thi
|
|||
|
||||
template: src=foo.cfg.j2 dest={{ remote_install_path}}/foo.cfg
|
||||
|
||||
.. note:: ansible allows Jinja2 loops and conditionals in templates, but in playbooks, we do not use them. Ansible
|
||||
templates are pure machine-parseable YAML.
|
||||
In the above example, we used a variable to help decide where to place a file.
|
||||
|
||||
Inside a template you automatically have access to all of the variables that are in scope for a host. Actually
|
||||
it's more than that -- you can also read variables about other hosts. We'll show how to do that in a bit.
|
||||
|
||||
.. note:: ansible allows Jinja2 loops and conditionals in templates, but in playbooks, we do not use them. Ansible
|
||||
templates are pure machine-parseable YAML. This is an rather important feature as it means it is possible to code-generate
|
||||
pieces of files, or to have other ecosystem tools read Ansible files. Not everyone will need this but it can unlock
|
||||
possibilities.
|
||||
|
||||
Hey Wait, A YAML Gotcha
|
||||
```````````````````````
|
||||
|
||||
YAML syntax requires that if you start a value with {{ foo }} you quote the whole line, since it wants to be
|
||||
sure you aren't trying to start a YAML dictionary. This is covered on the `YAMLSyntax` page.
|
||||
|
||||
This won't work::
|
||||
|
||||
- hosts: app_servers
|
||||
vars:
|
||||
app_path: {{ base_path }}/22
|
||||
|
||||
Do it like this and you'll be fine::
|
||||
|
||||
- hosts: app_servers
|
||||
vars:
|
||||
app_path: "{{ base_path }}/22"
|
||||
|
||||
.. note:: YAML syntax requires that if you start a value with {{ foo }} you quote the whole line, since it wants to be
|
||||
sure you aren't trying to start a YAML dictionary. This is covered on the `YAMLSyntax` page.
|
||||
|
||||
Information discovered from systems: Facts
|
||||
``````````````````````````````````````````
|
||||
|
||||
There are other places where variables can come from, but these are a type of variable that are discovered, not set by the user.
|
||||
|
||||
Facts are information derived from speaking with your remote systems.
|
||||
|
||||
An example of this might be the ip address of the remote host, or what the operating system is.
|
||||
|
@ -73,7 +126,248 @@ To see what information is available, try the following::
|
|||
|
||||
ansible hostname -m setup
|
||||
|
||||
The results of this can be used to create dynamic groups of hosts that match particular critera, see the :doc:`modules` documentation on 'group_by' for details, as well as in generalized conditional statements as discussed in the `playbook_conditionals` chapter.
|
||||
This will return a ginormous amount of variable data, which may look like this, as taken from Ansible 1.4 on a Ubuntu 12.04 system::
|
||||
|
||||
"ansible_all_ipv4_addresses": [
|
||||
"REDACTED IP ADDRESS"
|
||||
],
|
||||
"ansible_all_ipv6_addresses": [
|
||||
"REDACTED IPV6 ADDRESS"
|
||||
],
|
||||
"ansible_architecture": "x86_64",
|
||||
"ansible_bios_date": "09/20/2012",
|
||||
"ansible_bios_version": "6.00",
|
||||
"ansible_cmdline": {
|
||||
"BOOT_IMAGE": "/boot/vmlinuz-3.5.0-23-generic",
|
||||
"quiet": true,
|
||||
"ro": true,
|
||||
"root": "UUID=4195bff4-e157-4e41-8701-e93f0aec9e22",
|
||||
"splash": true
|
||||
},
|
||||
"ansible_date_time": {
|
||||
"date": "2013-10-02",
|
||||
"day": "02",
|
||||
"epoch": "1380756810",
|
||||
"hour": "19",
|
||||
"iso8601": "2013-10-02T23:33:30Z",
|
||||
"iso8601_micro": "2013-10-02T23:33:30.036070Z",
|
||||
"minute": "33",
|
||||
"month": "10",
|
||||
"second": "30",
|
||||
"time": "19:33:30",
|
||||
"tz": "EDT",
|
||||
"year": "2013"
|
||||
},
|
||||
"ansible_default_ipv4": {
|
||||
"address": "REDACTED",
|
||||
"alias": "eth0",
|
||||
"gateway": "REDACTED",
|
||||
"interface": "eth0",
|
||||
"macaddress": "REDACTED",
|
||||
"mtu": 1500,
|
||||
"netmask": "255.255.255.0",
|
||||
"network": "REDACTED",
|
||||
"type": "ether"
|
||||
},
|
||||
"ansible_default_ipv6": {},
|
||||
"ansible_devices": {
|
||||
"fd0": {
|
||||
"holders": [],
|
||||
"host": "",
|
||||
"model": null,
|
||||
"partitions": {},
|
||||
"removable": "1",
|
||||
"rotational": "1",
|
||||
"scheduler_mode": "deadline",
|
||||
"sectors": "0",
|
||||
"sectorsize": "512",
|
||||
"size": "0.00 Bytes",
|
||||
"support_discard": "0",
|
||||
"vendor": null
|
||||
},
|
||||
"sda": {
|
||||
"holders": [],
|
||||
"host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)",
|
||||
"model": "VMware Virtual S",
|
||||
"partitions": {
|
||||
"sda1": {
|
||||
"sectors": "39843840",
|
||||
"sectorsize": 512,
|
||||
"size": "19.00 GB",
|
||||
"start": "2048"
|
||||
},
|
||||
"sda2": {
|
||||
"sectors": "2",
|
||||
"sectorsize": 512,
|
||||
"size": "1.00 KB",
|
||||
"start": "39847934"
|
||||
},
|
||||
"sda5": {
|
||||
"sectors": "2093056",
|
||||
"sectorsize": 512,
|
||||
"size": "1022.00 MB",
|
||||
"start": "39847936"
|
||||
}
|
||||
},
|
||||
"removable": "0",
|
||||
"rotational": "1",
|
||||
"scheduler_mode": "deadline",
|
||||
"sectors": "41943040",
|
||||
"sectorsize": "512",
|
||||
"size": "20.00 GB",
|
||||
"support_discard": "0",
|
||||
"vendor": "VMware,"
|
||||
},
|
||||
"sr0": {
|
||||
"holders": [],
|
||||
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
|
||||
"model": "VMware IDE CDR10",
|
||||
"partitions": {},
|
||||
"removable": "1",
|
||||
"rotational": "1",
|
||||
"scheduler_mode": "deadline",
|
||||
"sectors": "2097151",
|
||||
"sectorsize": "512",
|
||||
"size": "1024.00 MB",
|
||||
"support_discard": "0",
|
||||
"vendor": "NECVMWar"
|
||||
}
|
||||
},
|
||||
"ansible_distribution": "Ubuntu",
|
||||
"ansible_distribution_release": "precise",
|
||||
"ansible_distribution_version": "12.04",
|
||||
"ansible_domain": "",
|
||||
"ansible_env": {
|
||||
"COLORTERM": "gnome-terminal",
|
||||
"DISPLAY": ":0",
|
||||
"HOME": "/home/mdehaan",
|
||||
"LANG": "C",
|
||||
"LESSCLOSE": "/usr/bin/lesspipe %s %s",
|
||||
"LESSOPEN": "| /usr/bin/lesspipe %s",
|
||||
"LOGNAME": "root",
|
||||
"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:",
|
||||
"MAIL": "/var/mail/root",
|
||||
"OLDPWD": "/root/ansible/docsite",
|
||||
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"PWD": "/root/ansible",
|
||||
"SHELL": "/bin/bash",
|
||||
"SHLVL": "1",
|
||||
"SUDO_COMMAND": "/bin/bash",
|
||||
"SUDO_GID": "1000",
|
||||
"SUDO_UID": "1000",
|
||||
"SUDO_USER": "mdehaan",
|
||||
"TERM": "xterm",
|
||||
"USER": "root",
|
||||
"USERNAME": "root",
|
||||
"XAUTHORITY": "/home/mdehaan/.Xauthority",
|
||||
"_": "/usr/local/bin/ansible"
|
||||
},
|
||||
"ansible_eth0": {
|
||||
"active": true,
|
||||
"device": "eth0",
|
||||
"ipv4": {
|
||||
"address": "REDACTED",
|
||||
"netmask": "255.255.255.0",
|
||||
"network": "REDACTED"
|
||||
},
|
||||
"ipv6": [
|
||||
{
|
||||
"address": "REDACTED",
|
||||
"prefix": "64",
|
||||
"scope": "link"
|
||||
}
|
||||
],
|
||||
"macaddress": "REDACTED",
|
||||
"module": "e1000",
|
||||
"mtu": 1500,
|
||||
"type": "ether"
|
||||
},
|
||||
"ansible_form_factor": "Other",
|
||||
"ansible_fqdn": "ubuntu2",
|
||||
"ansible_hostname": "ubuntu2",
|
||||
"ansible_interfaces": [
|
||||
"lo",
|
||||
"eth0"
|
||||
],
|
||||
"ansible_kernel": "3.5.0-23-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": 16436,
|
||||
"type": "loopback"
|
||||
},
|
||||
"ansible_lsb": {
|
||||
"codename": "precise",
|
||||
"description": "Ubuntu 12.04.2 LTS",
|
||||
"id": "Ubuntu",
|
||||
"major_release": "12",
|
||||
"release": "12.04"
|
||||
},
|
||||
"ansible_machine": "x86_64",
|
||||
"ansible_memfree_mb": 74,
|
||||
"ansible_memtotal_mb": 991,
|
||||
"ansible_mounts": [
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"fstype": "ext4",
|
||||
"mount": "/",
|
||||
"options": "rw,errors=remount-ro",
|
||||
"size_available": 15032406016,
|
||||
"size_total": 20079898624
|
||||
}
|
||||
],
|
||||
"ansible_os_family": "Debian",
|
||||
"ansible_pkg_mgr": "apt",
|
||||
"ansible_processor": [
|
||||
"Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz"
|
||||
],
|
||||
"ansible_processor_cores": 1,
|
||||
"ansible_processor_count": 1,
|
||||
"ansible_processor_threads_per_core": 1,
|
||||
"ansible_processor_vcpus": 1,
|
||||
"ansible_product_name": "VMware Virtual Platform",
|
||||
"ansible_product_serial": "REDACTED",
|
||||
"ansible_product_uuid": "REDACTED",
|
||||
"ansible_product_version": "None",
|
||||
"ansible_python_version": "2.7.3",
|
||||
"ansible_selinux": false,
|
||||
"ansible_ssh_host_key_dsa_public": "REDACTED KEY VALUE"
|
||||
"ansible_ssh_host_key_ecdsa_public": "REDACTED KEY VALUE"
|
||||
"ansible_ssh_host_key_rsa_public": "REDACTED KEY VALUE"
|
||||
"ansible_swapfree_mb": 665,
|
||||
"ansible_swaptotal_mb": 1021,
|
||||
"ansible_system": "Linux",
|
||||
"ansible_system_vendor": "VMware, Inc.",
|
||||
"ansible_user_id": "root",
|
||||
"ansible_userspace_architecture": "x86_64",
|
||||
"ansible_userspace_bits": "64",
|
||||
"ansible_virtualization_role": "guest",
|
||||
"ansible_virtualization_type": "VMware"
|
||||
|
||||
In the above the model of the first harddrive may be referenced in a template or playbook as::
|
||||
|
||||
{{ ansible_devices.sda.model }}
|
||||
|
||||
Similarly, the hostname as the system reports it is::
|
||||
|
||||
{{ ansible_hostname }}
|
||||
|
||||
|
||||
Facts are frequently used in conditionals (see `playbook_conditionals`) and also in templates.
|
||||
|
||||
Facts can be also used to create dynamic groups of hosts that match particular critera, see the :doc:`modules` documentation on 'group_by' for details, as well as in generalized conditional statements as discussed in the `playbook_conditionals` chapter.
|
||||
|
||||
Turning Off Facts
|
||||
`````````````````
|
||||
|
@ -131,17 +425,39 @@ or variables defined elsewhere in the playbook.
|
|||
Registered Variables
|
||||
````````````````````
|
||||
|
||||
Another major use of variables is running a command and using the result of that command to save the result into a variable.
|
||||
|
||||
The value of a task being executed in ansible can be saved in a variable and used later. See some examples of this in the
|
||||
`playbooks_conditionals` chapter.
|
||||
|
||||
While it's mentioned elsewhere in that document too, here's a quick syntax example::
|
||||
|
||||
- hosts: web_servers
|
||||
|
||||
tasks:
|
||||
|
||||
- shell: /usr/bin/foo
|
||||
register: foo_result
|
||||
ignore_errors: True
|
||||
|
||||
- shell: /usr/bin/bar
|
||||
when: foo_result.rc == 5
|
||||
|
||||
|
||||
Accessing Complex Variable Data
|
||||
```````````````````````````````
|
||||
|
||||
We already talked about facts a little higher up in the documentation.
|
||||
|
||||
Some provided facts, like networking information, are made available as nested data structures. To access
|
||||
them a simple {{ foo }} is not sufficient, but it is still easy to do. Here's how we get an IP address::
|
||||
|
||||
{{ ansible_eth0["ipv4"]["address"] }}
|
||||
|
||||
OR alternatively::
|
||||
|
||||
{{ ansible_eth0.ipv4.address }}
|
||||
|
||||
Similarly, this is how we access the first element of an array::
|
||||
|
||||
{{ foo[0] }}
|
||||
|
@ -316,3 +632,127 @@ Ansible's approach to configuration -- separating variables from tasks, keeps yo
|
|||
from turning into arbitrary code with ugly nested ifs, conditionals, and so on - and results
|
||||
in more streamlined & auditable configuration rules -- especially because there are a
|
||||
minimum of decision points to track.
|
||||
|
||||
Variable Precedence: Where Should I Put A Variable?
|
||||
```````````````````````````````````````````````````
|
||||
|
||||
A lot of folks may ask about how variables override another. Ultimately it's Ansible's philosophy that it's better
|
||||
you know where to put a variable, and then you have to think about it a lot less.
|
||||
|
||||
Avoid defining the variable "x" in 47 places and then ask the question "which x gets used".
|
||||
Why? Because that's not Ansible's Zen philosophy of doing things.
|
||||
|
||||
There is only one Empire State Building. One Mona Lisa, etc. Figure out where to define a variable, and don't make
|
||||
it complicated.
|
||||
|
||||
However, let's go ahead and get precedence out of the way! It exists. It's a real thing, and you might have
|
||||
a use for it.
|
||||
|
||||
If multiple variables of the same name are defined in different places, they win in a certain order, which is::
|
||||
|
||||
* -e variables always win
|
||||
* then comes "most everything else"
|
||||
* then comes variables defined in inventory
|
||||
* then "role defaults", which are the most "defaulty" and lose in priority to everything.
|
||||
|
||||
That seems a little theoretical. Let's show some examples and where you would choose to put what based on the kind of
|
||||
control you might want over values.
|
||||
|
||||
First off, group variables are super powerful.
|
||||
|
||||
Site wide defaults should be defined as a 'group_vars/all' setting. Group variables are generally placed alongside
|
||||
your inventory file. They can also be returned by a dynamic inventroy script (see `intro_dynamic_inventory`) or defined
|
||||
in things like AnsibleWorks AWX from the UI or API::
|
||||
|
||||
---
|
||||
# file: /etc/ansible/group_vars/all
|
||||
# this is the site wide default
|
||||
ntp_server: default-time.example.com
|
||||
|
||||
Regional information might be defined in a 'group_vars/region' variable. If this group is a child of the 'all' group (which it is, because all groups are), it will override the group that is higher up and more general::
|
||||
|
||||
---
|
||||
# file: /etc/ansible/group_vars/boston
|
||||
ntp_server: boston-time.example.com
|
||||
|
||||
If for some crazy reason we wanted to tell just a specific host to use a specific NTP server, it would then override the group variable!::
|
||||
|
||||
---
|
||||
# file: /etc/ansible/host_vars/xyz.boston.example.com
|
||||
ntp-server: override.example.com
|
||||
|
||||
So that covers inventory and what you would normally set there. It's a great place for things that deal with geography or behavior. Since groups are frequently the entity that maps roles onto hosts, it is sometimes a shortcut to set variables on the group instead of defining them on a role. You could go either way.
|
||||
|
||||
Remember: Child groups override parent groups, and hosts always override their groups.
|
||||
|
||||
Next up: learning about role variable precedence.
|
||||
|
||||
We'll pretty much assume you are using roles at this point. You should be using roles for sure. Roles are great. You are using
|
||||
roles aren't you? Hint hint.
|
||||
|
||||
Ok, so if you are writing a redistributable role with reasonable defaults, put those in the 'roles/x/defaults/main.yml' file. This means
|
||||
the role will bring along a default value but ANYTHING in Ansible will override it. It's just a default. That's why it says "defaults" :)
|
||||
See `intro_roles` for more info about this::
|
||||
|
||||
----
|
||||
# file: roles/x/defaults/main.yml
|
||||
# if not overriden in inventory or as a parameter, this is the value that will be used
|
||||
http_port: 80
|
||||
|
||||
if you are writing a role and want to ensure the value in the role is absolutely used in that role, and is not going to be overriden
|
||||
by inventory, you should but it in roles/x/vars/main.yml like so, and inventory values cannot override it. -e however, still will::
|
||||
|
||||
----
|
||||
# file: roles/x/vars/main.yml
|
||||
# this will absolutely be used in this role
|
||||
http_port: 80
|
||||
|
||||
So the above is a great way to plug in constants about the role that are always true. If you are not sharing your role with others,
|
||||
app specific behaviors like ports is fine to put in here. But if you are sharing roles with others, putting variables in here might
|
||||
be bad. Nobody will be able to override them with inventory, but they still can by passing a parameter to the role.
|
||||
|
||||
Parameterized roles are useful.
|
||||
|
||||
If you are using a role and want to override a default, pass it as a parameter to the role like so::
|
||||
|
||||
roles:
|
||||
- { name: apache, http_port: 8080 }
|
||||
|
||||
This makes it clear to the playbook reader that you've made a concious choice to override some default in the role, or pass in some
|
||||
configuration that the role can't assume by itself. It also allows you to pass something site-specific that isn't really part of the
|
||||
role you are sharing with others.
|
||||
|
||||
This can often be used for things that might apply to some hosts multiple times,
|
||||
like so::
|
||||
|
||||
roles:
|
||||
- { role: app_user, name: Ian }
|
||||
- { role: app_user, name: Terry }
|
||||
- { role: app_user, name: Graham }
|
||||
- { role: app_user, name: John }
|
||||
|
||||
That's a bit arbitrary, but you can see how the same role was invoked multiple Times. In that example it's quite likely there was
|
||||
no default for 'name' supplied at all. Ansible can yell at you when variables aren't defined -- it's the default behavior in fact.
|
||||
|
||||
So that's a bit about roles.
|
||||
|
||||
There are a few bonus things that go on with roles.
|
||||
|
||||
Generally speaking, variables set in one role are available to others. This means if you have a "roles/common/vars/main.yml" you
|
||||
can set variables in there and make use of them in other roles and elsewhere in your playbook::
|
||||
|
||||
roles:
|
||||
- { role: common_settings }
|
||||
- { role: something, foo: 12 }
|
||||
- { role: something_else }
|
||||
|
||||
.. note:: There are some protections in place to avoid the need to namespace variables.
|
||||
In the above, variables defined in common_settings are most definitely available to 'app_user' and 'something_else' tasks, but if
|
||||
"something's" guaranteed to have foo set at 12, even if somewhere deep in common settings it set foo to 20.
|
||||
|
||||
So, that's precedence, explained in a more direct way. Don't worry about precedence, just think about if your role is defining a
|
||||
variable that is a default, or a "live" variable you definitely want to use. Inventory lies in precedence right in the middle, and
|
||||
if you want to forceably override something, use -e.
|
||||
|
||||
If you found that a little hard to understand, take a look at the "ansible-examples" repo on our github for a bit more about
|
||||
how all of these things can work together.
|
||||
|
|
Loading…
Reference in a new issue