override variable from outside role

16 views
Skip to first unread message

Matt Zagrabelny

unread,
Oct 4, 2023, 5:02:59 PM10/4/23
to ansible...@googlegroups.com
Greetings Ansible users!

I have a role "nftables" that is assigned to all nodes in my inventory. It has a variable 'forward_policy' that has a default value:

$ cat roles/nftables/defaults/main.yaml
forward_policy: drop

I'd like to have another role (applied only to my router system) that can override that variable:

$ cat roles/router/vars/main.yaml
forward_policy: accept

I don't know how to override the variable in the nftables role from within the router role. Does anyone have any suggestions?

Thanks for any help!

-m

PS. Here is are my current playbooks:

roles
├── nftables
│   ├── defaults
│   │   └── main.yaml
│   ├── files
│   │   └── etc
│   │       ├── nftables.conf
│   │       └── nftables.conf.d
│   │           └── 000-flush-ruleset.nft
│   ├── handlers
│   │   └── main.yaml
│   ├── tasks
│   │   └── main.yaml
│   └── templates
│       └── etc
│           └── nftables.conf.d
│               └── 050-default-chains.nft.j2
└── router
    ├── files
    │   └── etc
    │       └── nftables.conf.d
    │           └── 070-default-nat-table.nft
    ├── tasks
    │   ├── main.yaml
    │   └── nftables_nat_table.yaml
    └── vars
        └── main.yaml

17 directories, 10 files

And the contents:

───────┬────────────────────────────────────────────────────────────────────────
       │ File: hosts.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ ungrouped:
   2   │     hosts:
   3   │         zed:
   4   │
   5   │ router:
   6   │     hosts:
   7   │         zed:
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/defaults/main.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ forward_policy: drop
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/files/etc/nftables.conf
───────┼────────────────────────────────────────────────────────────────────────
   1   │ #!/usr/sbin/nft -f
   2   │
   3   │ include "/etc/nftables.conf.d/*.nft"
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/files/etc/nftables.conf.d/000-flush-ruleset.nft
───────┼────────────────────────────────────────────────────────────────────────
   1   │ flush ruleset
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/handlers/main.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ -
   2   │     name: restart nftables
   3   │     service:
   4   │         name:  nftables
   5   │         state: restarted
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/tasks/main.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ ---
   2   │ # This playbook contains plays to configure nftables.
   3   │
   4   │ -
   5   │     name: enable service nftables
   6   │     service:
   7   │         name:    nftables
   8   │         enabled: yes
   9   │
  10   │ -
  11   │     name: configure nftables.conf
  12   │     copy:
  13   │         src:  files/etc/nftables.conf
  14   │         dest: /etc/nftables.conf
  15   │     tags:
  16   │         - nftables
  17   │     notify: restart nftables
  18   │
  19   │ -
  20   │     name: configure nftables.conf.d
  21   │     copy:
  22   │         src:  files/etc/nftables.conf.d
  23   │         dest: /etc
  24   │     tags:
  25   │         - nftables
  26   │     notify: restart nftables
  27   │
  28   │ -
  29   │     name: configure nftables.conf.d/050-default-chains.nft
  30   │     template:
  31   │         src:  etc/nftables.conf.d/050-default-chains.nft.j2
  32   │         dest: /etc/nftables.conf.d/050-default-chains.nft
  33   │     tags:
  34   │         - nftables
  35   │     notify: restart nftables
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/nftables/templates/etc/nftables.conf.d/050-default-chains.nft.j2
───────┼────────────────────────────────────────────────────────────────────────
   1   │ table inet filter {
   2   │     chain input {
   3   │         type filter hook input \
   4   │         priority 0;
   5   │         policy accept;
   6   │     }
   7   │     chain forward {
   8   │         type filter hook forward \
   9   │         priority 0;
  10   │         policy {{ forward_policy }};
  11   │     }
  12   │     chain output {
  13   │         type filter hook output \
  14   │         priority 0;
  15   │         policy accept;
  16   │     }
  17   │ }
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/router/files/etc/nftables.conf.d/070-default-nat-table.nft
───────┼────────────────────────────────────────────────────────────────────────
   1   │ table inet nat {
   2   │     chain postrouting {
   3   │         type nat hook postrouting \
   4   │         priority srcnat;
   5   │     }
   6   │
   7   │     chain prerouting {
   8   │         type nat hook prerouting \
   9   │         priority dstnat;
  10   │     }
  11   │ }
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/router/tasks/main.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ ---
   2   │ # This playbook contains plays to configure the router.
   3   │
   4   │ -
   5   │     include_tasks: nftables_nat_table.yaml
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/router/tasks/nftables_nat_table.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ ---
   2   │ # This playbook contains plays to add nat table for nftables.
   3   │
   4   │ -
   5   │     name: configure nftables nat table
   6   │     copy:
   7   │         src:  files/etc/nftables.conf.d/070-default-nat-table.nft
   8   │         dest: /etc/nftables.conf.d/070-default-nat-table.nft
   9   │     tags:
  10   │         - router
  11   │     notify: restart nftables
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: roles/router/vars/main.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ forward_policy: accept
───────┴────────────────────────────────────────────────────────────────────────
───────┬────────────────────────────────────────────────────────────────────────
       │ File: site.yaml
───────┼────────────────────────────────────────────────────────────────────────
   1   │ ---
   2   │ -
   3   │     name:  apply common configuration to all nodes
   4   │     hosts: all
   5   │     roles:
   6   │         - nftables
   7   │
   8   │ -
   9   │     name:  apply router configurations
  10   │     hosts: router
  11   │     roles:
  12   │         - router
───────┴────────────────────────────────────────────────────────────────────────

Vladimir Botka

unread,
Oct 4, 2023, 6:38:57 PM10/4/23
to 'Matt Zagrabelny' via Ansible Project
> $ cat roles/nftables/defaults/main.yaml
> forward_policy: drop
>
> $ cat roles/router/vars/main.yaml
> forward_policy: accept
>
> I don't know how to override the variable in the nftables role from within
> the router role.

Is it possible to minimize the example?

shell> tree .
.
├── hosts
├── pb.yml
└── roles
├── nftables
│   ├── defaults
│   │   └── main.yml
│   └── tasks
│   └── main.yml
└── router
├── tasks
│   └── main.yml
└── vars
└── main.yml

shell> cat roles/nftables/defaults/main.yml
forward_policy: drop
shell> cat roles/nftables/tasks/main.yml
- debug:
var: forward_policy

shell> cat roles/router/vars/main.yml
forward_policy: accept
shell> cat roles/router/tasks/main.yml
- debug:
var: forward_policy

shell> cat hosts
[router]
zed
shell> cat pb.yml
- hosts: all
roles:
- nftables

- hosts: router
roles:
- router

Running the playbook gives

shell> ansible-playbook pb.yml

PLAY [all] *****************************

TASK [nftables : debug] ****************
ok: [zed] =>
forward_policy: drop

PLAY [router] **************************

TASK [router : debug] ******************
ok: [zed] =>
forward_policy: accept

Does this reproduce your problem? If yes what do you expect?


--
Vladimir Botka

Matt Zagrabelny

unread,
Oct 4, 2023, 9:45:53 PM10/4/23
to ansible...@googlegroups.com
Hi Vladimir,

I would like forward_policy to be "accept" for the nftables role - since I want the "router" role to affect how a j2 template gets set in the "nftables" role.
 

PLAY [router] **************************

TASK [router : debug] ******************
ok: [zed] =>
  forward_policy: accept

So, I'd like to be able to modify a variable in one role from a different role.

Or perhaps have a global variable that can bet set to a default value in the role "nftables", but overridden in the role "router".
 
Thanks for the help!

-m

Vladimir Botka

unread,
Oct 5, 2023, 2:11:28 AM10/5/23
to 'Matt Zagrabelny' via Ansible Project
On Wed, 4 Oct 2023 20:45:23 -0500
"'Matt Zagrabelny' via Ansible Project"
<ansible...@googlegroups.com> wrote:

> > PLAY [all] *****************************
> >
> > TASK [nftables : debug] ****************
> > ok: [zed] =>
> > forward_policy: drop

> I would like forward_policy to be "accept" for the nftables role ...
> I want the "router" role to affect ... "nftables" role.

Create task that will "instantiate" the variable *forward_policy*

shell> cat roles/router/tasks/instantiate_vars.yml
- set_fact:
forward_policy: "{{ forward_policy }}"
when: forward_policy is defined

and run it in the first play *pre_tasks*

shell> cat pb.yml
- hosts: all
pre_tasks:
- include_role:
name: router
tasks_from: instantiate_vars
run_once: true
roles:
- nftables

- hosts: router
roles:
- router


--
Vladimir Botka

Matt Zagrabelny

unread,
Oct 6, 2023, 2:07:46 PM10/6/23
to ansible...@googlegroups.com
Hi Vladamir,

Thanks for all your help. Unfortunately the variables (and how and where they are being set) just aren't working the way I am expecting. I'll punt for now and just set the variable in the hosts.yaml file.

Very appreciative of your time and energy.

Cheers,

-m

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/20231005081108.4be4f4cc%40gmail.com.

Vladimir Botka

unread,
Oct 6, 2023, 3:03:37 PM10/6/23
to 'Matt Zagrabelny' via Ansible Project
There are many other options on how to override defaults.
The solution might be simple if you provide the detail. See
https://en.wikipedia.org/wiki/Minimal_reproducible_example

--
Vladimir Botka

Kosala Atapattu

unread,
Oct 8, 2023, 6:37:20 AM10/8/23
to ansible...@googlegroups.com

Vladimir Botka

unread,
Oct 8, 2023, 7:20:25 AM10/8/23
to Kosala Atapattu, ansible...@googlegroups.com
On Sun, 8 Oct 2023 23:36:47 +1300
Kosala Atapattu <kosala....@gmail.com> wrote:

> I did not fully understand the problem, but might worth having a look at
> variable precedence

The problem is as follows: You have two roles and want to override
defaults in the first role by the variables from the second role.

The precedence of variables is a substantial part of the solution. It
is not sufficient though. There might be more solutions depending on
the use-case's details. An option might be creating the below task in
the second role

shell> cat roles/role2/tasks/instantiate_vars.yml
- set_fact:
var1_common: "{{ var1_common }}"
when: var1_common is defined

and "instantiate" the variable(s) before you run the first role. This
way *set_fact* (precedence 19.) overrides the roles' defaults
(precedence 2.)

shell> cat pb.yml
- hosts: all
pre_tasks:
- include_role:
name: role2
tasks_from: instantiate_vars
run_once: true
roles:
- role1

Notes:

* You don't have to include or import *instantiate_vars.yml* in role2.
* You can "instantiate* more variables.
* You have to keep in mind the limitation of this solution. Only
precedence 20.-22. are left to override such "instantiated"
variables.

--
Vladimir Botka

Kosala Atapattu

unread,
Oct 8, 2023, 4:19:05 PM10/8/23
to Vladimir Botka, ansible...@googlegroups.com
Have you considered the following?

- hosts: all
  roles:
    - name: nftables
      forward_policy: drop
    - name: router
      forward_policy: allow

Or is there anything in the nftables logic which would define the forward_policy for the router role? Note, within a playbook, the variable scope is global. There is no such thing as a role scope for variables, you can override the same variable, role level or even at task level.

You can use set_fact to alter the variable for the scope of the playbook as much as you want. But older version (pre 2.10) I had issues with roles three layers down, but not in the later versions.

Cheers,
Kosala



Vladimir Botka

unread,
Oct 9, 2023, 8:00:30 AM10/9/23
to Kosala Atapattu, ansible...@googlegroups.com
On Mon, 9 Oct 2023 09:18:36 +1300
Kosala Atapattu <kosala....@gmail.com> wrote:

> Have you considered the following?
>
> - hosts: all
> roles:
> - name: nftables
> forward_policy: drop
> - name: router
> forward_policy: allow

This is not a solution to the problem:

You have two roles and want to override defaults in the first role
by the variables from the second role.

--
Vladimir Botka
Reply all
Reply to author
Forward
0 new messages