Say I want to put basic config variables in roles/*/vars/main.yml for use when the role’s tasks run, but also want to access them in a play that doesn’t include that role. A specific example of what I am talking about would be where I need to build a configuration file for an application that is configured in a subsequent play.
Say I have a postgres role where the database port is defined in roles/postgres/vars/main.yml. In the next play I want to configure my web-application’s settings file with the database port. I know I could:
put all vars in group_vars/all
include roles/postgres/vars/main.yml (or roles/postgres/defaults/main.yml?) in the vars_files section of the play building the configuration file
The first doesn’t seem ideal as pretty much all of my variables are needed in multiple plays therefore this file is getting really long. Plus it seems like it undermines the reusable nature of roles a bit.
The second seems fine, except that I’m going to end up including a lot of role-specific vars/main.yml (defaults/main.yml?) files on some plays. Plus I fear that I might be opening myself up to precedence problems. E.g. a variable is overridden in the previous play and isn’t reflected when including the role specific vars/defaults.
My question is, are these my only options? Is there a better way to go about managing role related variables that are needed outside of the role?
“Say I want to put basic config variables in roles/*/vars/main.yml for use when the role’s tasks run, but also want to access them in a play that doesn’t include that role”
Assuming you are already running 1.4, and you should be, since it’s released (just waiting on EPEL to roll over). you can do this from any task file:
include_vars: …/roles/foo/vars/main.yml
Though it seems like it might be better to just have the role depend on a common role, and set the variables there.
I’ve considered this. Is there a benefit to using include_vars over specifying the path in the vars_files list?
Though it seems like it might be better to just have the role depend on a common role, and set the variables there.
In my case I’m keeping “provisioning” and “deploy” as separate playbooks. So installing/configuring the base services (like postgres) happens before my app is configured with their settings. I don’t want to run all of the install/configure steps on those services every time I go to deploy.
The only reason I wouldn’t use vars_files is because vars_files is a keyword at play level, so you can’t make it part of the role.
If it’s a common file of variables though, the cleanest way is to just include the file as a role, and those variables will be made available to other roles.
The only reason I wouldn’t use vars_files is because vars_files is a keyword at play level, so you can’t make it part of the role.
Oh, yeah, of course. I see.
If it’s a common file of variables though, the cleanest way is to just include the file as a role, and those variables will be made available to other roles.
Another way of doing this is to use the dictionary ability of yaml, instead of adding them in the role, add them to group_vars/all.yaml in a dictornary:
Say I want to put basic config variables in roles/*/vars/main.yml for use when
the role’s tasks run, but also want to access them in a play that doesn’t
include that role. A specific example of what I am talking about would be
where I need to build a configuration file for an application that is
configured in a subsequent play.
Another way of doing this is to use the dictionary ability of yaml, instead of
adding them in the role, add them to group_vars/all.yaml in a dictornary:
mysoftware:
license_key: 12345
version: 2.0
Yes, but this doesn’t seem ideal. Especially with the release of galaxy. IMO if we are using galaxy as a means to share code. The roles we share should include vars that can (defaults/main.yml) and cannot (vars/main.yml) be overridden.
IMO, if the memcached role defines a port or path, that port should be available to the entire system.
I have a similar need to re-use variables related to a role without running the tasks associated with that role. At this point, I’m putting them all in group_vars/all, but it’s getting a bit challenging to manage. With the include_vars approach, would we lose the ability to override them in group_vars and host_vars?
Before settling on group_vars/all, my previous approach was to not have a main.yml and to include a tasks file from the role explicitly in my playbook, although with this approach I lost the ability to see which role was currently being executed and it felt kind of clunky (so I abandoned it).
I think a really slick interface to address this workflow would be to allow specifying specific task files for a role in the roles declaration. Something like:
roles:
some_role:some_tasks
In that example, some_tasks would be referring to roles/some_role/tasks/some_tasks.yml. This would accommodate re-using role variables by simply not having a tasks/main.yml and explictly specifying the task list in the playbooks that need them. With that setup, my random auxillary playbooks would all have “roles: [my_app]”, while my main deployment playbook would have “roles: [my_app:deploy]”.