See Variable precedence: Where should I put a variable?. You can see that the role's defaults represent the lowest precedence for variables and the extra variables, declared on the command-line, override everything. There are a plethora of options between these two options.
For testing, create the roles and the playbook below. For example
shell> tree roles/
roles/
├── certbot
│ ├── defaults
│ │ └── main.yml
│ └── tasks
│ └── main.yml
├── jenkins
│ ├── defaults
│ │ └── main.yml
│ └── tasks
│ └── main.yml
└── nginx
├── defaults
│ └── main.yml
└── tasks
└── main.yml
9 directories, 6 files
There are only two files in each role. The files are identical in all roles
shell> cat roles/certbot/defaults/main.yml
fqdn: "{{ fqdn_default|default('srv.example.com') }}"
shell> cat roles/certbot/tasks/main.yml
- debug:
var: fqdn
Then, the playbook below
shell> cat playbook.yml
- hosts: localhost
roles:
- certbot
- jenkins
- nginx
gives as expected
shell> ansible-playbook playbook.yml
PLAY [localhost] *********************************************************
TASK [certbot : debug] ***************************************************
ok: [localhost] =>
fqdn: srv.example.com
TASK [jenkins : debug] ***************************************************
ok: [localhost] =>
fqdn: srv.example.com
TASK [nginx : debug] *****************************************************
ok: [localhost] =>
fqdn: srv.example.com
In this example, the default values of fqdn in all roles are the same. Of course, you can declare different default values for each role if you want to.
You can declare the variable on the command-line
shell> ansible-playbook playbook.yml -e fqdn=www.example.com
PLAY [localhost] *********************************************************
TASK [certbot : debug] ***************************************************
ok: [localhost] =>
fqdn: www.example.com
TASK [jenkins : debug] ***************************************************
ok: [localhost] =>
fqdn: www.example.com
TASK [nginx : debug] *****************************************************
ok: [localhost] =>
fqdn: www.example.com
Moreover, in this example, you can also change the default value, e.g. in the group_vars
shell> cat group_vars/all.yml
fqdn_default: default.example.com
Then the playbook will use the value of fqdn_default
shell> ansible-playbook playbook.yml
PLAY [localhost] **********************************************************
TASK [certbot : debug] ****************************************************
ok: [localhost] =>
fqdn: default.example.com
TASK [jenkins : debug] ****************************************************
ok: [localhost] =>
fqdn: default.example.com
TASK [nginx : debug] ******************************************************
ok: [localhost] =>
fqdn: default.example.com
Use vars_prompts if you want to input the fqdn from the command line when the playbook is running
. e.g.
shell> cat playbook.yml
- hosts: localhost
vars_prompt:
- name: fqdn
prompt: What is the fqdn?
private: no
roles:
- certbot
- jenkins
- nginx
shell> ansible-playbook playbook.yml
What is the fqdn?: ww9.example.com
PLAY [localhost] ******************************************************
TASK [certbot : debug] ************************************************
ok: [localhost] =>
fqdn: ww9.example.com
TASK [jenkins : debug] *************************************************
ok: [localhost] =>
fqdn: ww9.example.com
TASK [nginx : debug] ***************************************************
ok: [localhost] =>
fqdn: ww9.example.com
Quoting from the Note: "Prompts for individual vars_prompt variables will be skipped for any variable that is already defined through the command line --extra-vars option,..."