# Global default variables for multiple Ansible roles

**URL:** <https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284>\
**Category:** Get Help\
**Created:** [October 14, 2024, 7:58pm UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284 "2024-10-14T19:58:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bajo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bajo/32/5152_2.png) [@bajo](https://forum.ansible.com/u/bajo)\
**Post date:** [October 14, 2024, 7:58pm UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284/1 "2024-10-14T19:58:47Z")

</div>

I am trying to determine the best approach to define global default variables for my Ansible project. I have a project that consists of multiple playbooks, multiple roles. I also have some custom modules, etc…

Sample structure:

```auto
.
├── ansible.cfg
├── group_vars
│ └── all.yaml
├── inventory
├── playbooks
└── roles
    ├── role1
    └── role2

```

Let’s say both my roles use git and require the git repository name to perform a job. So, my question is, where should I define the git repository name?

Based on Ansible best practices, role variables should use role name as a prefix (`role1_git_repositoy_name`). If I do this, I have to have the git repository defined in two places (defaults in each role).

On the other hand, I can define the Git repository name in the `group_vars/all.yaml` like this:

```auto
# group_vars/all.yaml
git_repo_name: "my-github-org/my-repo"'

```

If I use this approach, I am not sure what would be the best way to consume this variable in my role.

1. Should I simply use `git_repo_name` variable in my roles?
2. Should I re-define my variable when calling a role:

```auto
- ansible.builtin.include_role:
    name: role1
  vars:
    role1_git_repo_name: "{{ git_repo_name }}"

```

1. Should I re-define my variable in defaults for a role:

```auto
# roles/role1/defaults/main.yaml
role1_git_repo_name: "{{ git_repo_name }}"

```

Any suggestions on how to proceed or what the best practices are?

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [October 14, 2024, 11:34pm UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284/2 "2024-10-14T23:34:02Z")

</div>

Hi @bajo and welcome.

There is no right answer here. It’s a personal preference. If you had some additional criteria, maybe you could lean toward some definitive answer.

Looking at the provided examples, the first one is the most clean. Just a single var defined in `group_vars` or `host_vars`. You can also put a single assert task at the beginning of the role to test if `git_repo_name` is defined and has proper value.

The second one is just plain ugly.

The third one, my favorite, is a nice alternative but it unnecessarily grows the number of variables (more resources consumed), with essentially the same value, in case you want to globally force the value. On the other hand, this is a must have if you want to have the ability to override variable per role i.e. you don’t want to have it forced globally. Fallback to default value is also possible.

---

<div class="post-metadata">

**Author:** ![jiholland](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jiholland/32/11273_2.png) [@jiholland](https://forum.ansible.com/u/jiholland)\
**Post date:** [October 15, 2024, 8:18am UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284/3 "2024-10-15T08:18:42Z")

</div>

Ideally, the variable files in your inventory should be named after the role they are steering:

```yaml
$ tree inventory/
inventory/
└── group_vars
    └── example
        ├── role1.yml
        └── role2.yml

$ cat inventory/group_vars/example/role1.yml
---
role1_git_repo_name: "my-github-org/my-repo"

$ cat inventory/group_vars/example/role2.yml
---
role2_git_repo_name: "my-github-org/my-repo"

```

If you have a truly global variable used by all your roles that you only want to define once in your inventory, then this is the way to go:

> [@bajo](#):
>
> 1. Should I re-define my variable in defaults for a role:
> 
> ```auto
> # roles/role1/defaults/main.yaml
> role1_git_repo_name: "{{ git_repo_name }}"
> 
> ```

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [October 15, 2024, 1:20pm UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284/4 "2024-10-15T13:20:14Z")

</div>

We have a “`defaults`” git project where we keep a few (very few) things global to all our projects. This includes an inventory, the `ansible-lint` configuration our ci/cd jobs use, and a `group_vars/all/_ansible-defaults.yml` file. That file contains variables that projects may need but are beyond the scope of any single project: load balancer SNAT pools, Jenkins user id/group names, proxy strings, etc.

Whenever any of those files changes, the “`defaults`” project’s Jenkins pipeline pushes changes to the appropriate places. In the case of `group_vars/all/_ansible-defaults.yml`, it goes through all our git projects looking for an existing `group_vars/all/_ansible-defaults.yml` file and updates/commits/pushes the new version of that file in the main branch.

By making `group_vars/all` a directory rather than a file, projects can still have their own `group_vars/all/this.yml`, `group_vars/all/that.yml`, `group_vars/all/the_other_thing.yml`, etc. files without fighting with the `defaults` project for the space in the `all` group\_vars namespace.

---

<div class="post-metadata">

**Author:** ![SANG](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sang/32/11247_2.png) [@SANG](https://forum.ansible.com/u/SANG)\
**Post date:** [September 24, 2026, 11:13am UTC](https://forum.ansible.com/t/global-default-variables-for-multiple-ansible-roles/10284/5 "2026-09-24T11:13:30Z")

</div>

I think neither 1 nor 3 is right, and for the same reason.

A role is a reusable unit, often authored by someone else. It has no business reading a bare, unnamespaced variable out of the project’s global namespace. `git_repo_name` is generic enough that any role may claim it — so the day role1 and role2 no longer share a repo, or the day you change `git_repo_name` assuming a single consumer, you cannot know what you just broke. The dependency lives inside the roles, where grepping your project finds nothing. Option 3 doesn’t fix this: it moves the same reference into `defaults`, keeps the coupling, and hides it one layer deeper — where lazy evaluation makes it fail late, far from the cause.

Prefer 2: each role consumes only its own prefixed interface (`roleX_git_repo_name`), and the project wires it up — `group_vars/<group>/roleX.yml`. Dependencies become visible and greppable, and splitting the two roles later is a one-line edit instead of a role rewrite. Sharing a value should be a choice the project makes at the call site or in a common group, not a constraint the role assumes — and never through role defaults, whose precedence is too low to hold that decision.

So yes: manage this dependency in the Ansible project, not inside the roles.
