Skip to content

Understanding Branch as Code Data Model

The starting point and core component of Branch as Code is the data model. In this section, we explore how to build an example data model using Branch as Code. The data model represents the configuration of a Unified Branch for Meraki Dashboard.
The example repository intentionally uses a simplified configuration to keep this learning lab lightweight and free of hardware requirements.

In Network as Code, the data model is a structured YAML document that describes the intended network configuration. This data model is consumed by the automation engine — in the case of Branch as Code, Terraform. Terraform reads the YAML content, extracts the parameters, and passes them to Meraki-specific modules and resources.

This is why we validate the data model first: to ensure that the automation engine receives complete and correct information before deployment.

Example: YAML → Terraform Resource

Data Model (YAML):

..
organizations:
- name: Unified Branch Learning Org
networks:
- name: Unified Branch 1
syslog_servers:
- host: 1.2.3.4
port: 514
roles:
- Switch event log
- Air Marshal events
- Flows
- URLs
- Wireless event log
- Appliance event log

Terraform Interpretation:

# module.meraki.meraki_network_syslog_servers.networks_syslog_servers["Unified Branch Learning Org/Unified Branch 1"] will be created
+ resource "meraki_network_syslog_servers" "networks_syslog_servers" {
+ id = (known after apply)
+ network_id = (known after apply)
+ servers = [
+ {
+ host = "3.4.5.6"
+ port = 514
+ roles = [
+ "Air Marshal events",
+ "Appliance event log",
+ "Flows",
+ "Switch event log",
+ "URLs",
+ "Wireless event log",
]
},
]
}

When using Infrastructure as Code, the data model represents the declaration of intent. The operator describes what the network should look like — not how to configure it. Terraform and Netascode modules translate this intent into the actual Meraki configuration. In IaC practices, the data model serves as the source of truth.

Each field in the data model must follow the constraints defined in the Meraki schema:

  • Type (string, number, enum…)
  • Allowed values
  • Value range
  • Mandatory / optional
  • Default values

Branch as Code uses the native Meraki schema. The complete requirements are documented in the Network as Code Meraki Data Model Overview

Example: Syslog Port:

NameTypeConstraintMandatoryDefault Value
portIntegerInteger 0–65535Yes

If the port value is missing in the above referenced syslog configuration, rendering will fail because it is mandatory.

Example: Admin Configuration

organizations_admin:
email: admin@example.com
name: Branch Admin
NameTypeConstraintMandatoryDefault
organizations_admin.emailStringLength 1–127No
organizations_admin.nameStringLength 1–127No

Here, both fields are optional and simply need to follow length constraints.

Branch as Code uses a template-driven architecture. Templates allow you to abstract large portions of configuration logic into reusable building blocks. These are Network as Code templates, not Meraki configuration templates. They are CVD-aligned and designed to work with the Network as Code Meraki Terraform modules.

Templates offer:

  • Consistency across deployments
  • Separation of logic and input
  • Alignment with Cisco Validated Designs (CVDs)
  • Modularity (appliance, switching, wireless, WAN, etc.)
  • Extensibility when customizing your environment

In the example repository, templates are intentionally minimized to avoid requiring hardware. Templates are stored in template-*.yaml files.

Note: Currently, only network-level templates are supported.

Example: Network Management Template

meraki:
template:
networks:
- name: nw_management
settings:
local_status_page_enabled: true
remote_status_page: true
secure_port: false
local_status_page_authentication:
username: ${local_page_username}
password: !env secret_password
named_vlans: true
snmp:
access: users
users:
- username: ${snmp_username}
passphrase: !env secret_password
syslog_servers:
- host: ${syslog_server}
port: ${syslog_port}
roles:
- Switch event log
- Air Marshal events
- Flows
- URLs
- Wireless event log
- Appliance event log

In this template we can notice some key concepts:

  1. Environment Variables for Secrets

Sensitive values (passwords, tokens) are provided via !env: !env secret_password. These come from the .env file configured earlier, which is excluded from version control. In production, secrets should be supplied through a CI/CD pipeline secret manager.

  1. Input Variables

The following values must be provided in the variables file:

  • snmp_username
  • syslog_server
  • syslog_port

Users provide these values as input. We review this in the next step.

In summary, templates abstract the configuration, and users specify only the parameters they need to change. The underlying logic (described by the templates) remains aligned with CVDs.

Deployments become consistent, repeatable, and lower risk because applying templates reduces manual configuration error.

Templates are regular YAML files that you can adjust. For example, consider the following modifications:

  • SNMP is not used → remove it
  • Syslog is always 1.2.3.4:514 → hardcode values
  • Named VLANs not desired → disable it

Modify template

Then our configuration becomes:

meraki:
template:
networks:
- name: nw_management
settings:
local_status_page_enabled: true
remote_status_page: true
secure_port: false
local_status_page_authentication:
username: ${local_page_username}
password: !env secret_password
named_vlans: false
syslog_servers:
- host: 1.2.3.4
port: 514
roles:
- Switch event log
- Air Marshal events
- Flows
- URLs
- Wireless event log
- Appliance event log

As part of Unified Branch as Code, the supplied templates are tested and verified in the lab. Any modification requires additional testing before deployment.

The lab includes an example variables file pods_variables.nac.yaml

This file contains all parameters the user needs to adjust, such as:

  • IP addressing
  • Hostnames
  • Network names
  • Template assignments
  • Local usernames

It is important to note that every required variable referenced in templates must be provided.

For example, if a template uses ${syslog_server}, this key must exist in the variable file.

Variables for multiple branches can be added in sequence in the same file.

5 Branches

In this sample, five different branches are configured. All use the same templates, with different variables provided per branch. With this approach, configuration can be replicated across hundreds of branches with the appropriate settings.

This approach also supports per-branch overrides. If one branch requires special configuration, you can override values or apply a dedicated template only to that branch.

For the lab, modifications are optional, but in production you must adjust values to match your environment.

Rendering combines templates and variables (everything in the data/ folder) into one merged YAML file.

Templates + Variables → Full Configuration (merged YAML)

The variable file also defines which templates apply to each network:

- name: Unified Branch 1
templates: [nw_setup, nw_management, switch, wireless, app_settings, app_vlans, app_fw, app_content, app_static_routes, group_policies]

If you do not want to configure wireless for a specific branch, you can remove the associated wireless template.

Rendering Templates

In Branch as Code v2.0, rendering is performed from the repository root using the main module in main.tf.

This is configured in the root main.tf:

module "meraki" {
source = "github.com/netascode/terraform-meraki-nac-meraki?ref=v0.9.0"
yaml_directories = ["data"]
write_model_file = "merged_configuration.nac.yaml"
}

This module will:

  • Load templates and variables from /data folder
  • Deep-merge them
  • Generate merged_configuration.nac.yaml