Skip to content

First Steps

This section provides an easy to understand, simple example of deploying a network configuration to a new or existing Meraki organization. This helps to get familiar using Network as Code to manage Meraki cloud-managed networks. Because Terraform assumes full control of the lifecycle of the resources it creates, this example focuses on network and device configuration that won’t impact existing organizational settings.

The repository used in this example can be found at: https://github.com/netascode/nac-meraki-simple-example

This example assumes you have installed the following prerequisites.

  • Terraform 1.8.0 or later
  • Git
  • Your preferred text editor / Integrated Development Environment (IDE) (such as VisualStudio Code)
  • A Meraki Dashboard account with API access enabled
  • A Meraki API key (generated from Dashboard > Organization > Settings > Dashboard API access)

Start by cloning the repository to your local system:

Terminal window
git clone https://github.com/netascode/nac-meraki-simple-example.git
cd nac-meraki-simple-example

Open the folder in your preferred editor / IDE.

The working area should look like this:

nac-meraki-simple-example/
├── data/
│ ├── meraki.nac.yaml
│ ├── networks.nac.yaml
├── defaults/
│ └── defaults_overrides.nac.yaml
├── main.tf
├── terraform.tf
└── README.md

As explained in the introduction, the main.tf file contains the required providers, provider settings and points to the location of all *.yaml file definitions.

module "meraki" {
source = "netascode/nac-meraki/meraki"
version = "0.3.2"
yaml_directories = ["data", "defaults"]
write_model_file = "./merged_defaults.yaml"
}

Before proceeding, you need to configure your Meraki API credentials. The Terraform provider requires your API key and organization ID, you can provide them via environment variables:

Terminal window
export MERAKI_API_KEY="your-api-key-here"
export MERAKI_ORG_ID="your-org-id-here"

Let’s examine the initial configuration in data/networks.nac.yaml:

---
meraki:
domains:
- name: cisco.com # Replace with your domain
administrator:
name: admin@cisco.com # Replace with your admin email
organizations:
- name: Demo Organization
networks:
- name: Branch-Office-Demo
product_types:
- appliance
- switch
- wireless
time_zone: America/Los_Angeles
notes: Branch office demo network
tags:
- demo
- branch
wireless:
ssids:
- name: Corporate-WiFi
ssid_number: "0"
enabled: true
auth_mode: psk
psk: DemoPassword123
encryption_mode: wpa
wpa_encryption_mode: WPA2 only
use_vlan_tagging: true
default_vlan_id: 100

This configuration creates:

  • A network named “Branch-Office-Demo”
  • Support for appliance, switch, and wireless products
  • A single SSID with WPA2-PSK authentication

Step 3: Initialize and Apply the Configuration

Section titled “Step 3: Initialize and Apply the Configuration”

Initialize Terraform and apply the configuration:

Terminal window
# Initialize Terraform
terraform init
# Review the planned changes
terraform plan
# Apply the configuration
terraform apply

Terraform will show you the resources it plans to create. Type yes when prompted to confirm the changes.

After successful execution, you should see output similar to:

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

You can now verify the network was created by logging into your Meraki Dashboard and checking the networks section.

Let’s expand the configuration by adding switch port configuration and additional wireless settings. Update your data/networks.nac.yaml:

---
meraki:
domains:
- name: cisco.com # Replace with your domain
administrator:
name: admin@cisco.com # Replace with your admin email
organizations:
- name: Demo Organization
networks:
- name: Branch-Office-Demo
product_types:
- appliance
- switch
- wireless
time_zone: America/Los_Angeles
notes: Branch office demo network
tags:
- demo
- branch
wireless:
ssids:
- name: Corporate-WiFi
ssid_number: "0"
enabled: true
auth_mode: psk
psk: DemoPassword123
encryption_mode: wpa
wpa_encryption_mode: WPA2 only
use_vlan_tagging: true
default_vlan_id: 100
- name: Guest-WiFi
ssid_number: "1"
enabled: true
auth_mode: open
splash_page: Click-through splash page
appliance:
vlans:
- vlan_id: 100
name: Data VLAN
subnet: 10.1.100.0/24
appliance_ip: 10.1.100.1
dhcp_handling: Run a DHCP server
dhcp_lease_time: 1 day
- vlan_id: 200
name: Voice VLAN
subnet: 10.1.200.0/24
appliance_ip: 10.1.200.1
dhcp_handling: Run a DHCP server
dhcp_lease_time: 1 day

Apply the updated configuration:

Terminal window
terraform apply

This will add:

  • A guest WiFi network with captive portal
  • RF profile for wireless optimization
  • Switch power settings
  • VLAN configuration on the security appliance

The defaults.nac.yaml file allows you to set organization-wide defaults. Let’s create some default wireless and switch settings: This file can be named anything you wish, as long as you ensure defaults: is at the root of the yaml structure and the remaining structure matches the data model path. In this example our defaults file is called defaults_overrides.nac.yaml and resides in a folder called default. This directory can also be called anything and also if preferred reside in the same data folder as your other configurations.

---
defaults:
meraki:
domains:
organizations:
networks:
wireless:
ssids:
enabled: true
ip_assignment_mode: Bridge mode
use_vlan_tagging: false
switch:
settings:
vlan: 999
use_combined_power: true
uplink_client_sampling: true
mac_blocklist: false

It is important to remember that defaults are only applied in the yaml configuration files contain the full data model path so that the resource can be intitated.

For example:

Site-01.yaml:

---
meraki:
domains:
organizations:
networks:
wireless:
ssids:
enabled: false
ip_assignment_mode: DHCP mode
use_vlan_tagging: false
switch:
settings:
vlan: 1
use_combined_power: false
uplink_client_sampling: false
mac_blocklist: true

When you apply this configuration, these defaults will be applied to all networks unless explicitly overridden in the specific network configuration.

The example above demonstrates overwriting the value. Equally if we left no value for vlan in the switch settings, it would inherit the default value of 999.

Please note that we currently do not support list of dictionaries as a default value. Due to the design of the module we only support field defaults. For advanced use cases such as default firewall rules, we recommend you utilise the template feature of the module.

There maybe some scenarios where you may wish to utilise a list of dictionaires as default values. In these cases it is recommended to raise an issue on our module github repository.

As your configuration grows, you can organize it across multiple files:

It is recommended to split the management and execution of terraform into multiple main.tf files using multiple directories. This is useful if you want to manage specific regions or important areas. This is extremely useful when it comes to managing large terraform state files and keeping operations and pipelines to shorter execution times. This not only speeds up operations but also makes it much easier to troubleshoot and limit blast radius for any potential destructive changes.

For example:

emea/
├── main.tf
├── data/
│ ├── meraki.nac.yaml
│ ├── networks_branch.nac.yaml
│ ├── networks_campus.nac.yaml
│ ├── devices.nac.yaml
├── defaults/
│ └── defaults_overrides.nac.yaml
apac/
├── main.tf
├── data/
│ ├── meraki.nac.yaml
│ ├── networks_branch.nac.yaml
│ ├── networks_campus.nac.yaml
│ ├── devices.nac.yaml
├── defaults/
│ └── defaults_overrides.nac.yaml
lab/
├── main.tf
├── data/
│ ├── meraki.nac.yaml
│ ├── networks_branch.nac.yaml
│ ├── networks_campus.nac.yaml
│ ├── devices.nac.yaml
├── defaults/
│ └── defaults_overrides.nac.yaml

To remove resources, you can either:

  1. Remove the configuration from your YAML files and run terraform apply
  2. Use terraform destroy to remove all managed resources

For example, to remove the Guest-WiFi SSID, simply delete its configuration block from the YAML file and run:

Terminal window
terraform apply

Terraform will detect the removed configuration and delete the SSID from your Meraki network.

It is important to remember that although this is removed from Terraform management, not all API operations lead to deletion of that resource. Some of the provider operations will perform a delete on operation for non singleton resources. For singletons the provider typically leaves the object in place within dashboard. There are specific scenarios where we override this behavior to ensure that the resource is deleted from the dashboard. For example traffic shaping or firewall resources.

If you feel there is an additional singleton resource that requires this behavior, please open an issue on our GitHub repository.

This simple example demonstrates the core concepts of managing Meraki networks with Network as Code. You can extend this approach to:

  • Manage multiple organizations and networks
  • Configure advanced wireless features like splash pages and access control
  • Set up switch port configurations and VLAN assignments
  • Configure security appliance firewall rules and VPN settings
  • Implement device-specific configurations and templates

For more advanced scenarios, explore the comprehensive examples in the Data Model documentation and consider setting up CI/CD pipelines for automated deployments.