0

Situation

It's nice to set group_vars in ansible. This context every server has two dualport NICs (Mellanox). The network configuration is done via group_vars for netplan. While network:bond0:interfaces works like a charm network:ethernets: did not:

## group_vars/my-server-group
Mellanox_1: enp3s0
Mellanox_2: enp5s0
bond0_interfaces:
  - "{{ Mellanox_1 }}"
  - "{{ Mellanox_1 }}d1"
  - "{{ Mellanox_2 }}"
  - "{{ Mellanox_2 }}d1"
interface_no_dhcp:
  dhcp4: no
interface_array: [ '{{ Mellanox_1 }}', '{{ Mellanox_1 }}d1', '{{ Mellanox_2 }}', '{{ Mellanox_2 }}d1' ] 
# ^^^ works, but is useless
interface_array: { '{{ Mellanox_1 }}', '{{ Mellanox_1 }}d1', '{{ Mellanox_2 }}', '{{ Mellanox_2 }}d1' } 
# ^^^ doesn't work
netplan_config_file: /etc/netplan/netplan_ansible.yaml
netplan_configuration:
  network:
    ethernets:
      "{{ interface_array }}"
    bonds:
      bond0:
        interfaces: "{{ bond0_interfaces }}"
        parameters:
          mode:                 802.3ad

The result is:

## /etc/netplan/netplan.yaml (excerpt)
netplan_configuration:
  network:
    ethernets:
      "{{ Mellanox_1 }}":       <-- instead of 'enp3s0:'
      "{{ Mellanox_1 }}d1":
      "{{ Mellanox_2 }}":
      "{{ Mellanox_2 }}d1":

Also the following does not work and leads to an error: recursive loop detected in template string:

## group_vars/my-server-group
ethernet_interfaces: |
"{% for interface in bond0_interfaces %}"
"{{ ethernet_interfaces|combine({interface: interface_no_dhcp}) }}"
"{% endfor %}"

the problem:

With an array -- like with bond0_interfaces -- it works as expected with an dictionary it fails. As far as I know I need a dictionary instead of an array in order to follow netplan configuration guideline (described here). At the end it should be like:

the goal

## /etc/netplan/netplan.yaml (excerpt)
network:
  ethernets:
    enp3s0:
      dhcp4: no
    enp3s0d1:
      dhcp4: no
    enp5s0:
      dhcp4: no
    enp5s0d1:
      dhcp4: no
  bonds:
    bond0:
      interfaces: 
      - enp3s0
      - enp3s0d1
      - enp5s0
      - enp5s0d1
      parameters:
        mode:                 802.3ad

Does anyone have a solution?

in this thread user holdenweb says:

'Dynamic variable names are almost always a terrible idea'

In this context it makes absolutely sense ;-)

I also checked:

1 Answers1

0

I have a solution. May I suggest to use my Ansible role linux_postinstall? The task netplan does what you need. The trick is to filter item.conf in the template

{{ item.conf | from_yaml | to_nice_json }}

Below is the test play which creates ethernets and bonds in /scratch. I haven't tested netplan with these config files. YMMV. The example works also with group_vars.

> cat netplan.yml

- hosts: localhost
  become: yes
  become_method: sudo
  become_user: root
  vars:
    Mellanox_1: enp3s0
    Mellanox_2: enp5s0
    lp_netplan_root: "/scratch"
    lp_netplan: True
    lp_netplan_renderer: "networkd"
    lp_netplan_conf:
      - file: "91-ethernet.yaml"
        category: "ethernets"
        conf: |
          {{ Mellanox_1 }}:
            dhcp4: no
          {{ Mellanox_1 }}d1:
            dhcp4: no
          {{ Mellanox_2 }}:
            dhcp4: no
          {{ Mellanox_2 }}d1:
            dhcp4: no
      - file: "92-bonds.yaml"
        category: "bonds"
        conf: |
          bond0:
            interfaces:
            - "{{ Mellanox_1 }}"
            - "{{ Mellanox_1 }}d1"
            - "{{ Mellanox_2 }}"
            - "{{ Mellanox_2 }}d1"
            parameters:
              mode: 802.3ad
  roles:
    - vbotka.linux_postinstall

> ansible-playbook netplan.yml -t lp_netplan

> cat /scratch/91-ethernet.yaml

# Ansible managed
network:
  version: 2
  renderer: networkd
  ethernets:
    {
    "enp3s0": {
        "dhcp4": false
    }, 
    "enp3s0d1": {
        "dhcp4": false
    }, 
    "enp5s0": {
        "dhcp4": false
    }, 
    "enp5s0d1": {
        "dhcp4": false
    }
}

> cat /scratch/92-bonds.yaml

# Ansible managed
network:
  version: 2
  renderer: networkd
  bonds:
    {
    "bond0": {
        "interfaces": [
            "enp3s0", 
            "enp3s0d1", 
            "enp5s0", 
            "enp5s0d1"
        ], 
        "parameters": {
            "mode": "802.3ad"
        }
    }
}
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63