gNMIc
Ansible

Ansible gNMIc

Please contact an instructor.

gNMIc is an open-source, feature-rich command-line interface (CLI) client and collector designed for managing network devices via the gNMI protocol (gRPC Network Management Interface). It supports all gNMI RPCs—Capabilities, Get, Set, and Subscribe—for configuration and streaming telemetry.


Step 1 - Revisit NX-API Sandbox

Return to your NX-API Sandbox on your Leaf1 using the IP address below or if you still have the session open from earlier in the lab:

    https://10.15.6.21

Login using your username and password:

  • Username: admin
  • Password: cisco.123

In the Sandbox, set the Method to RESTCONF (Yang) and the Message format to gnmi-json. Copy and paste the VLAN and VNI mapping below into the text field. Then, click Convert.


vlan 106
 vn-segment 10106

It is important to notice that the Sandbox is a great way to learn and work in to convert the cli you know today into JSON for gNMI configuration templates. As you will see in the subsequent steps below, you will be taking the converted output and using it within Ansible.




Step 2 - Install gNMIc Binary

Return to your Terminal window and issue:


cd /home/pod06/workspace/nxapilab
bash -c "$(curl -sL https://get-gnmic.openconfig.net)"

gnmic version output:

version : 0.43.0
 commit : 883b7f9a
   date : 2026-02-01T21:03:39Z
 gitURL : https://github.com/openconfig/gnmic
   docs : https://gnmic.openconfig.net

Step 3 - Create a New Ansible Role for gNMI

Within your existing ansible-nxos directory, create a new role for the gNMI tasks. First change to the 'roles' subdirectory and then create a new role.


cd /home/pod06/workspace/nxapilab/ansible-nxos/roles


ansible-galaxy init gnmi_vlans


Step 4 - Create NETCONF YANG Configuration Template

Using the output from the Sandbox, create a JSON configuration template file.

Copy the data structure below into a JSON file.


touch /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_vlans.json
cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_vlans.json
{
    "bd-items": {
        "bd-items": {
            "BD-list": [
                {
                    "accEncap": "vxlan-10106",
                    "fabEncap": "vlan-106"
                }
            ]
        }
    }
}
EOF



touch /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_nve.json
cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_nve.json
{
  "eps-items": {
    "epId-items": {
      "Ep-list": [
        {
          "epId": "1",
          "nws-items": {
            "vni-items": {
              "Nw-list": [
                {
                  "mcastGroup": "239.1.1.1",
                  "vni": "10106"
                }
              ]
            }
          }
        }
      ]
    }
  }
}
EOF



touch /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_evpn.json
cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_evpn.json
{
    "evpn-items": {
        "adminSt": "enabled",
        "bdevi-items": {
            "BDEvi-list": [
                {
                    "encap": "vxlan-10106",
                    "rd": "rd:unknown:0:0",
                    "rttp-items": {
                        "RttP-list": [
                            {
                                "type": "export",
                                "ent-items": {
                                    "RttEntry-list": [
                                        {
                                            "rtt": "route-target:unknown:0:0"
                                        }
                                    ]
                                }
                            },
                            {
                                "type": "import",
                                "ent-items": {
                                    "RttEntry-list": [
                                        {
                                            "rtt": "route-target:unknown:0:0"
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}
EOF



touch /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_vrf.json
cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_vrf.json
{
    "bgp-items": {
      "inst-items": {
        "asn": "65001",
        "dom-items": {
          "Dom-list": [
            {
              "name": "gNMIVRF",
              "rtrId": "10.0.0.101",
              "rtrIdAuto": "disabled",
              "af-items": {
                "DomAf-list": [
                  {
                    "advertL2vpnEvpn": "enabled",
                    "maxEcmp": "2",
                    "type": "ipv4-ucast"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "inst-items": {
      "Inst-list": [
        {
          "descr": "gNMI VRF",
          "encap": "vxlan-50001",
          "l3vni": "false",
          "name": "gNMIVRF",
          "dom-items": {
            "Dom-list": [
              {
                "name": "gNMIVRF",
                "rd": "rd:unknown:0:0",
                "af-items": {
                  "DomAf-list": [
                    {
                      "type": "ipv4-ucast",
                      "ctrl-items": {
                        "AfCtrl-list": [
                          {
                            "type": "l2vpn-evpn",
                            "rttp-items": {
                              "RttP-list": [
                                {
                                  "type": "export",
                                  "ent-items": {
                                    "RttEntry-list": [
                                      {
                                        "rtt": "route-target:unknown:0:0"
                                      }
                                    ]
                                  }
                                },
                                {
                                  "type": "import",
                                  "ent-items": {
                                    "RttEntry-list": [
                                      {
                                        "rtt": "route-target:unknown:0:0"
                                      }
                                    ]
                                  }
                                }
                              ]
                            }
                          },
                          {
                            "type": "ipv4-ucast",
                            "rttp-items": {
                              "RttP-list": [
                                {
                                  "type": "export",
                                  "ent-items": {
                                    "RttEntry-list": [
                                      {
                                        "rtt": "route-target:unknown:0:0"
                                      }
                                    ]
                                  }
                                },
                                {
                                  "type": "import",
                                  "ent-items": {
                                    "RttEntry-list": [
                                      {
                                        "rtt": "route-target:unknown:0:0"
                                      }
                                    ]
                                  }
                                }
                              ]
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
EOF



touch /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_anycast_gw.json
cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/gnmi_vlans/files/gnmi_anycast_gw.json
{
    "ipv4-items": {
      "inst-items": {
        "dom-items": {
          "Dom-list": [
            {
              "name": "gNMIVRF",
              "if-items": {
                "If-list": [
                  {
                    "id": "vlan106",
                    "addr-items": {
                      "Addr-list": [
                        {
                          "addr": "192.168.106.1/24",
                          "pref": "0",
                          "tag": "12345",
                          "type": "primary"
                        }
                      ]
                    }
                  },
                  {
                    "forward": "enabled",
                    "id": "vlan501"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "icmpv4-items": {
      "inst-items": {
        "dom-items": {
          "Dom-list": [
            {
              "name": "gNMIVRF",
              "if-items": {
                "If-list": [
                  {
                    "ctrl": "port-unreachable",
                    "id": "vlan106"
                  },
                  {
                    "ctrl": "port-unreachable",
                    "id": "vlan501"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "hmm-items": {
      "fwdinst-items": {
        "if-items": {
          "FwdIf-list": [
            {
              "id": "vlan106",
              "mode": "anycastGW"
            }
          ]
        }
      }
    },
    "intf-items": {
      "svi-items": {
        "If-list": [
          {
            "adminSt": "up",
            "descr": "Configured by gNMIc",
            "id": "vlan106",
            "rtvrfMbr-items": {
              "tDn": "/System/inst-items/Inst-list[name='gNMIVRF']"
            }
          },
          {
            "adminSt": "up",
            "descr": "Configured by gNMIc",
            "id": "vlan501",
            "rtvrfMbr-items": {
              "tDn": "/System/inst-items/Inst-list[name='gNMIVRF']"
            }
          }
        ]
      }
    }
  }
EOF


Step 5 - Create Ansible gNMIc Tasks

Create the Ansible tasks using the netconf_config and netconf_get modules. The netconf_config module will be used to send the rpc from the XML template created in the step above and apply it to the running config. The netconf_get module will be used to display that the configuration was applied correctly using a filter to just return the VLANs and associated VNI mappings.

Copy the playbook YAML file.


cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/roles/nc_vlan_vni/tasks/main.yml

- name: Merge VLAN Config
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify set --update-path /System/ --update-file {{ role_path ~ '/files/gnmi_vlans.json' }}
  delegate_to: localhost

- name: Merge NVE Config
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify set --update-path /System/ --update-file {{ role_path ~ '/files/gnmi_nve.json' }}
  delegate_to: localhost

- name: Merge EVPN Config
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify set --update-path /System/ --update-file {{ role_path ~ '/files/gnmi_evpn.json' }}
  delegate_to: localhost

- name: Merge VRF Config
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify set --update-path /System/ --update-file {{ role_path ~ '/files/gnmi_vrf.json' }}
  delegate_to: localhost

- name: Merge Anycast GW Config
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify set --update-path /System/ --update-file {{ role_path ~ '/files/gnmi_anycast_gw.json' }}
  delegate_to: localhost

- name: Get NVE VNIs
  ansible.builtin.shell: |
    gnmic -a {{ ansible_host }}:50051 -u {{ ansible_user }} -p {{ ansible_password }} --skip-verify get --path "/System/eps-items/epId-items" --format "json"
  delegate_to: localhost
  register: vni_check

- name: Debug Output
  ansible.builtin.debug:
    var: vni_check.stdout | ansible.builtin.from_json

EOF


Step 6 - Create a New Hosts File

Create a new host file with a group heading called gnmi-inventory that includes your leaf switches IP addresses.

Copy the gnmi-inventory file.


cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/gnmi-inventory
---
# hosts file for gNMIc Ansible playbook

nxos:
  vars:
    ansible_connection: ansible.netcommon.grpc
    ansible_user: admin
    ansible_password: cisco.123
    ansible_port: 50051
    # ansible_grpc_connection_type: cisco.nxos.nxos
    # ansible_network_os: cisco.nxos.nxos
  children:
    leafs:
      hosts:
        staging-leaf1:
            ansible_host: 10.15.6.21
        staging-leaf2:
            ansible_host: 10.15.6.22

EOF


Step 7 - Create a Main gNMIc Playbook

Create a new main playbook that associates the leaf host grouping and the gnmi_vlans role.

Copy the main playbook YAML file.


cat <<EOF >> /home/pod06/workspace/nxapilab/ansible-nxos/gnmi.yml

---
# main playbook

- hosts: leafs
  gather_facts: false

  roles:
    - role: gnmi_vlans

EOF



Step 8 - Execute the Ansible Playbook

Execute the Ansible playbook:


cd /home/pod06/workspace/nxapilab/ansible-nxos
ansible-playbook -i gnmi-inventory gnmi.yml

Alternatively, you can add -vvv for verbose debugging output for each task that is executed.