Network Automation Reference

How to Update Cisco Meraki MX Layer 3 Firewall Rules via API

Introduction

Managing a handful of branch firewalls through the dashboard is fine. But once your network scales to dozens, hundreds, or thousands of locations, manual configuration becomes a liability. Clicking through the Meraki Dashboard to update one Layer 3 outbound firewall rule across 50 sites isn’t just tedious — it invites configuration drift, human error, and a lot of wasted time.

API-driven automation changes that. With the Cisco Meraki REST API, you can programmatically query, modify, and push firewall policy across an entire global network in seconds.

Whether you’re cloning a “Golden Image” site for a new retail branch, dynamically blocking malicious IPs your SIEM flagged, or updating printer subnets after a VLAN migration, this is a skill worth having.

What is Meraki API Firewall Automation?

Meraki API firewall automation means talking to the Cisco Meraki cloud backend via HTTP requests to manage the Layer 3 security policy on your MX appliances.

Instead of logging into the dashboard and navigating to Security & SD-WAN > Firewall, you send a JSON payload to a specific Meraki API endpoint. For outbound Layer 3 rules, that’s /networks/{networkId}/appliance/firewall/l3FirewallRules in API v1.

Through GET (retrieve current rules) and PUT (overwrite them), you manage the entire ACL of an appliance programmatically.

Read Also: Meraki API Updating VLANs

Why It Matters in Modern Networks

In legacy environments firewall rules were mostly static. Today they aren’t — applications move between cloud providers, threat feeds update by the minute, and new branches get spun up fast with zero-touch provisioning.

Manual firewall updates create a bottleneck between security and business agility. Managing rules as code (Python or Terraform) means you can version-control them in Git, peer-review changes, test in staging, and deploy uniformly — so site B ends up with the exact same security posture as site A instead of drifting over time.

Key Concepts Explained

A few things worth understanding before you touch the firewall API:

  • RESTful Verbs: mostly GET (read) and PUT (update). Meraki uses PUT for firewall rules, which means you have to supply the entire list of rules in your request. Send just one rule and you’ll delete every other rule that existed.

  • Network ID: every site has a unique string identifier (e.g., N_1234567890123456). API calls target this specific ID.

  • JSON Payloads: Meraki’s API speaks JSON, which maps cleanly to Python dictionaries.

  • Outbound Layer 3 Rules: on a Meraki MX, standard L3 rules govern outbound traffic — traffic leaving a VLAN toward the WAN or another VPN subnet.

Step-by-Step Breakdown

Here’s the workflow I follow for a firewall update via the API:

  1. Authenticate: get your Meraki API key and include it in the X-Cisco-Meraki-API-Key header.

  2. Locate the Network ID: identify the site where the MX appliance lives.

  3. Fetch existing rules (GET): pull the current firewall policy so you don’t blindly overwrite it.

  4. Modify the payload: change the specific rule you need (e.g., a source CIDR block).

  5. Push the update (PUT): send the complete, updated rule list back.

  6. Verify: check for a 200 OK, and optionally confirm in the Dashboard.

    If the rule you pushed was meant to open external access to a service, our free Port Checker is a fast way to confirm the port is actually reachable from outside your network, not just accepted by the API.

Configuration / Code Examples

Postman is fine for quick testing, but Python is what I reach for in production. Here’s a script using the requests library to safely update a Layer 3 firewall rule.

Python Script: Updating a Layer 3 Firewall Rule

import requests
import json

# Define variables (Replace with your actual data)
API_KEY = "your_meraki_api_key_here"
NETWORK_ID = "L_1234567890123456"
BASE_URL = f"https://api.meraki.com/api/v1/networks/{NETWORK_ID}/appliance/firewall/l3FirewallRules"

# Setup HTTP Headers
headers = {
 "X-Cisco-Meraki-API-Key": API_KEY,
 "Content-Type": "application/json",
 "Accept": "application/json"
}

def update_firewall_rules():
 print(f"[*] Fetching existing firewall rules for network {NETWORK_ID}...")

 # STEP 1: GET existing rules to prevent overwriting everything
 try:
 response = requests.get(BASE_URL, headers=headers)
 response.raise_for_status() # Check for HTTP errors
 current_data = response.json()
 rules_list = current_data.get('rules', [])
 except requests.exceptions.RequestException as e:
 print(f"[!] Failed to fetch rules: {e}")
 return

 # STEP 2: Modify the specific rule locally
 rule_found = False
 new_source_cidr = "10.50.10.0/24" # Our new printer subnet

 for rule in rules_list:
 # We target a specific rule by its comment/description
 if rule.get('comment') == 'Allow Printers to Internal':
 print(f"[*] Found target rule. Updating source CIDR to {new_source_cidr}")
 rule['srcCidr'] = new_source_cidr
 rule_found = True
 break

 if not rule_found:
 print("[!] Target rule not found. Aborting update.")
 return

 # Prepare the final payload containing ALL rules
 payload = {"rules": rules_list}

 # STEP 3: PUT the updated rule list back to the API
 print("[*] Pushing updated rules to Meraki Cloud...")
 try:
 put_response = requests.put(BASE_URL, headers=headers, json=payload)
 put_response.raise_for_status()
 print("[+] Success! Firewall rules updated. Status Code: 200")
 except requests.exceptions.RequestException as e:
 print(f"[!] Failed to update rules: {e}")

if __name__ == "__main__":
 update_firewall_rules()

 

Code Explanation:

  • Lines 16-24: I do a GET first to pull the current firewall state — this is the step that actually saves you from an accidental outage.

  • Lines 27-37: loop through the list of dictionaries, find the target rule by its comment field (e.g., “Allow Printers to Internal”), and update its srcCidr to the newly provisioned subnet.

  • Lines 42-49: bundle the modified list back into {"rules": [...]} and push it via PUT.

Real-World Use Cases

  1. Site Cloning & Branch Spin-ups: when you clone a template network, the firewall rules copy over exactly, but the internal IP subnets usually change. Use the API to parse the new site’s rules and update srcCidr to match the newly assigned local VLANs.

  2. Dynamic Threat Containment: hook your Meraki firewalls up to a SIEM. When it flags a malicious external IP, an API script can add a Deny rule to the top of the MX firewall across every site at once.

  3. Scheduled Maintenance Windows: a script opens a firewall port for database replication at 2 AM, and a cron job runs a second script to close it at 4 AM — so temporary access doesn’t get left open indefinitely.

Benefits

  • Speed: changes that take hours across 50 sites via the GUI take seconds via the API.

  • Consistency: scripts don’t make typos — an IP address pushed via API deploys exactly as written in your code.

  • Auditability: changes made via Python or CI/CD leave a clear, text-based log of what changed, when, and by whom.

Common Challenges

The biggest trap with the Meraki Firewall API is what PUT actually does. There’s no PATCH for appending a single rule to an ACL, so PUT is a full replacement. Send a payload with 1 rule when the firewall has 50, and Meraki deletes the 50 and replaces them with your 1.

Always GET first, modify the payload locally, and PUT the entire list back.

Best Practices

  • Idempotency: write scripts so running them twice gives the same result as running them once. Before adding a rule, check if it already exists.

  • Use staging networks: never test a new API script against production. Use a virtual MX or an empty network in your dashboard for validating payloads.

  • Use tags: group sites with Meraki network tags (e.g., tag:retail), then have your script pull networks matching that tag and apply updates to that group.

Security Considerations

Your Meraki API key has administrative access to your entire network — treat it like a master password.

  • Never hardcode keys: don’t put API keys directly in your Python code. Use environment variables (e.g., os.environ.get('MERAKI_API_KEY')).

  • Use a secrets vault: for production, use HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault to pass credentials at runtime.

  • Rotate keys: regularly revoke and regenerate API keys to limit the blast radius if one leaks.

Troubleshooting Tips

  • HTTP 400 Bad Request: your JSON payload is malformed. Check your data types — rules must be an array of objects (a list of dicts in Python), not a single dictionary.

  • HTTP 401 Unauthorized: your API key is invalid, missing from the headers, or lacks write privileges for that network.

  • HTTP 404 Not Found: the script is pointing to a Network ID that doesn’t exist. Double-check the URL string.

  • HTTP 429 Too Many Requests: you’ve hit the rate limit (typically 10 calls/sec per organization). Add time.sleep(0.5) inside your loops to pace requests.

The biggest risk in the script above is the one flagged earlier: PUT replaces the entire rule list, so a bug in your local modification logic can silently wipe rules you didn’t mean to touch. This is one place where Terraform’s declarative model is a genuine improvement, not just a trend — Cisco’s Terraform provider for Meraki diffs your desired rule list against what’s actually configured and only changes what’s different, instead of you manually GET-ing and re-PUT-ing the full list on every run. If you’re managing firewall rules across more than a handful of sites on an ongoing basis, it’s worth the setup cost.

Frequently Asked Questions

Q: What API endpoint is used to update Meraki MX Layer 3 firewall rules?

A: Send a PUT request to /networks/{networkId}/appliance/firewall/l3FirewallRules.

Q: Why did my Meraki API call delete all my other firewall rules?

A: Because updating firewall rules requires PUT, which overwrites the existing configuration. If your JSON payload doesn’t include the existing rules, the API assumes you want them gone. Always GET first, modify the list, and PUT the entire thing back.

Q: What format does the Meraki API require for firewall rules?

A: A JSON object with a "rules" key holding an array of rule objects (each with protocol, policy, destPort, destCidr, srcPort, and srcCidr).

Q: Does changing Meraki firewall rules via API cause downtime?

A: No. The change applies in the background exactly as it would if you clicked Save in the dashboard.

Q: Can I use the official Meraki Python SDK for firewall updates?

A: Yes — the meraki Python library abstracts the raw HTTP calls. dashboard.appliance.updateNetworkApplianceFirewallL3FirewallRules() does the same thing with cleaner code.

Have a question this didn’t cover? Get in touch and I’ll help you work through it.

Advertisement

Leave a Comment

Sign in with Google to comment โ€” verifies you're a real person. No WordPress account is created; nothing beyond your name and email is used.

โœ“ Signed in โ€” you can comment below.