Moving some role deps stuff around a small amount.

This commit is contained in:
Michael DeHaan 2013-08-16 22:05:26 -04:00
parent 42648e2f0a
commit 15e2ccd2d9
2 changed files with 42 additions and 68 deletions

View file

@ -488,7 +488,7 @@ This designates the following behaviors, for each role 'x':
- If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play
- If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play
- If roles/x/vars/main.yml exists, variables listed therein will be added to the play
- If roles/x/meta/main.yml exists, any role dependencies listed therein will be added to the list of roles
- If roles/x/meta/main.yml exists, any role dependencies listed therein will be added to the list of roles (1.3 and later)
- Any copy tasks can reference files in roles/x/files/ without having to path them relatively or absolutely
- Any script tasks can reference scripts in roles/x/files/ without having to path them relatively or absolutely
- Any template tasks can reference files in roles/x/templates/ without having to path them relatively or absolutely
@ -555,34 +555,27 @@ Role Dependencies
.. versionadded: 1.3
Role dependencies allow you to include other roles within your role, so that you no longer
have to specify them at the top level. As noted above, role dependencies are stored in the
`meta/main.yml` file contained within the role directory. This file should contain the following::
Role dependencies allow you to automatically pull in other roles when using a role. Role dependencies are stored in the
`meta/main.yml` file contained within the role directory. This file should contain
a list of roles and parameters to insert before the specified role, such as the following in an example
`roles/myapp/meta/main.yml`::
---
dependencies:
- { role: foo, x: 1 }
- { role: bar, y: 2 }
- { role: baz, z: 3 }
- { role: common, some_parameter: 3 }
- { role: apache, port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 }
Role dependencies can also be specified as a full path::
Role dependencies can also be specified as a full path, just like top level roles::
---
dependencies:
- { role: '/path/to/common/roles/foo', x: 1 }
Roles dependencies are always executed before the role that includes them. For example, given the following
list of dependant roles::
Roles dependencies are always executed before the role that includes them, and are recursive.
- car
- wheel
- tire
- brake
The roles would be executed in the order: tire -> brake -> wheel -> car.
Role dependencies may be included more than once. Continuing the above example, the car role could
add dependencies as follows::
Role dependencies may be included more than once. Continuing the above example, the 'car' role could
add 'wheel' dependencies as follows::
---
dependencies:
@ -591,57 +584,19 @@ add dependencies as follows::
- { role: wheel, n: 3 }
- { role: wheel, n: 4 }
Which would result in the following dependency tree::
If the wheel role required tire and brake in turn, this would result in the following execution order::
- car
- wheel (n=1)
- tire (n=1)
- brake (n=1)
- wheel (n=2)
- tire (n=2)
- brake (n=2)
- wheel (n=3)
- tire (n=3)
- brake (n=3)
- wheel (n=4)
- tire (n=4)
- brake (n=4)
And the order of execution would be tire(n=1) -> brake(n=1) -> wheel(n=1) -> tire(n=2) -> brake(n=2) -> wheel(n=2) -> ... -> car.
tire(n=1)
brake(n=1)
wheel(n=1)
tire(n=2)
brake(n=2)
wheel(n=2)
...
car
.. note::
Variable inheritance and scope are detailed below.
Role Variable Scope and Precedence
``````````````````````````````````
There are two rules governing variable scope when it comes to roles and dependencies.
1. Variables listed in vars/ files are loaded into the role and also into the global list of variables.
This means that if two roles define the same variable name, the last one to be included will be the
one that sets the variable at the global level. These variables also override whatever may be set in group
or host vars files, since inventory variables have the lowest priority.
This allows roles to share variables with other roles that it doesn't know about, and means variables from
parent roles will override any that are set at a lower level. Given the car/wheel example above, if the
`tire` role sets `x: 1` in its vars/main.yml while the `wheel` roles sets `x: 2`, both roles will see
`x: 2` (as will the brake role). This allows parent roles to override variables defined in dependant classes,
for instance if you wanted to override the http_port setting in a web server role.
If you wish to avoid this behavior, make sure the variables in your roles have unique names instead of something
generic like `port`.
2. Variables given when including/depending a role override variables in vars/main.yml
This means that if you include a role (or add it to a list of dependencies) while setting a variable,
that variable value will be the one that role (and any dependant roles) will see.
For example, given the car/wheel example again, if the car adds the wheel role as a dependency as follows::
- { role: wheel, x: 100 }
Then the wheel, tire, and brake roles will all see `x: 100` no matter what is set in the vars files for each role.
Variable inheritance and scope are detailed in the Advanced Playbook section.
Executing A Playbook
````````````````````

View file

@ -1023,6 +1023,25 @@ that is going to be used. You won't be fooled by some variable from inventory s
So, in short, if you want something easy to remember: facts beat playbook definitions, and
playbook definitions beat inventory variables.
There's a little bit more if you are using roles -- roles fit in the "playbook definitions" category of scale. They are
trumped by facts, and still trump inventory variables. However, there's a bit of extra magic.
Variables passed as parameters to the role are accesible only within that role (and dependencies of that role). You can
almost think of them like programming functions or macros.
Variables loaded via the 'vars/' directory of a role are made available to all roles and tasks, which in older versions of Ansible
could be confusing in the case of a reused variable name. In Ansible 1.3 and later, however, vars/ directories are guaranteed to be scoped to the current role, just like roles parameters. They are still available globally though, so if you want to set a variable like "ntp_server" in a common role, other roles can still make use of it. Thus they are just like "vars_files" construct that they emulate, but they have a bit more of a "Do What I Mean" semantic to them. They are smarter.
If there are role dependencies involved, dependent roles can set variables visible to the roles that require them, but
the requiring role is allowed to override those variables. For instance if a role "myapp" requires "apache", and
the value of "apache_port" in "apache" is 80, "myapp" could choose to set it to 8080. Thus you may think of this somewhat
like an inheritance system if you're a developer -- though it's not exactly -- and we don't require folks to think in programming terms to know how things work.
If you want, you can choose to prefix variable names with the name of your role and be extra sure of where
data sources are coming from, but this is optional. However it can be a nice thing to do in your templates as you immediately
know where the variable was defined.
Ultimately, the variable system may seem complex -- but it's really not. It's mostly a "Do What I Mean" kind of system, though knowing the details may help you if you get stuck or are trying to do something advanced. Feel free to experiment!
Check Mode ("Dry Run") --check
```````````````````````````````