Firmware management in Meraki enables you to control the firmware version running on network devices. Through NAC, you can schedule upgrades and downgrades for specific product types within a network and configure the automatic upgrade window.
Meraki firmware operations are non-declarative by nature. Unlike other NAC resources, NAC does not continuously reconcile firmware state — it pushes the intent (a scheduled upgrade or downgrade) and does not verify the outcome. Use nac-test to operationally validate that the intended firmware version is running after the scheduled window.
Schedule Intent vs Configuration Intent:
Most NAC resources declare a desired ongoing state — Terraform enforces them continuously and corrects drift. Firmware is different: it declares an intent to act at a point in time. Once the schedule is created, the intent is considered delivered — NAC does not track whether the upgrade completes. A finished schedule is not a steady-state goal — it does not mean “keep this device on version X forever.” The YAML represents what should happen next, not what should always be. Once a schedule is pushed, NAC does not track it further. If the schedule is still pending, any YAML changes will be pushed as an update. If the schedule has already executed, update to_version, local_time, or both to push a new schedule — see the note below on past-date behaviour.
Re-declaring After a Completed Schedule:
Once a scheduled upgrade or downgrade executes, that product’s YAML entry reflects a completed action. To schedule a new upgrade, update local_time and to_version. The provider always sends toVersion.id, time, and predownload together whenever any one of them changes, so:
Updating only local_time schedules a new upgrade to the same version at a new time — useful when a device was manually downgraded outside NAC and you want to re-apply the same version.
Updating only to_version schedules an upgrade to the new version using the existing local_time. If that time is already in the past, the upgrade will be triggered within approximately 5 minutes of apply.
Changes to one product do not affect the schedules of other products.
Intent Must Be Forward-Looking:
The declared to_version must differ from the version currently running on the network — specifying the current firmware version causes an API error. For local_time, always specify a future timestamp, or omit it entirely to trigger the upgrade within approximately 5 minutes of apply.
Upgrade vs Downgrade — Per-Product Mutual Exclusivity:
The upgrade and downgrade blocks can coexist in the same firmware definition. However, a single product type can only appear in one of them — never both. For example, wireless can be in downgrade while switch and appliance are in upgrade, but wireless cannot appear in both blocks simultaneously.
Dedicated Workspace:
It is recommended to manage firmware upgrades and downgrades in a dedicated Terraform workspace. Because firmware is a schedule intent rather than a configuration intent, it behaves differently from other NAC resources: Meraki may apply automatic upgrades, or operators may manually change firmware versions outside of NAC. Either event can cause the Terraform state to diverge from what the API reports, which produces plan-time errors and can stall a CI/CD pipeline. Isolating firmware operations in a dedicated workspace means these failures are contained and do not block unrelated configuration changes from being applied.
Omitting the local_time field triggers an immediate upgrade (scheduled approximately 5 minutes from the time of apply). This is useful in two scenarios:
Network initialization: standardize newly claimed devices to a known-good firmware version before the network goes into production.
Forced immediate upgrade: push a version change to existing devices without waiting for a maintenance window.
The example below targets three product types — switch, wireless, and appliance — pinning each to a stable release.
The example below schedules an upgrade to higher firmware versions across switch, wireless, and appliance at 10 PM on a specific date. The automatic_upgrade_window defines the recurring window Meraki uses for automatic (Meraki-initiated) upgrades; the local_time on each product controls when this specific scheduled upgrade runs.
local_time is specified as a local time without a timezone designator (e.g. "2026-09-15T22:00:00"). The API requires a trailing Z in this field, but despite the format it does not mean UTC — the time is interpreted in the network’s configured timezone. NAC appends the Z automatically.
The pre_download flag on wireless instructs access points to download the firmware image in advance so that the actual upgrade completes faster during the maintenance window.
The participate_in_next_beta_release flag opts the product into Meraki’s next beta release program. It is independent of next_upgrade and can be set with or without a scheduled upgrade.
meraki:
domains:
- name: !envdomain
administrator:
name: !envorg_admin
organizations:
- name: !envorg
networks:
- name: !envnetwork_name
product_types:
- appliance
- switch
- wireless
firmware:
automatic_upgrade_window:
day_of_week: "sunday"
hour_of_day: "4:00"
upgrade:
products:
switch:
participate_in_next_beta_release: true
next_upgrade:
local_time: "2026-09-15T22:00:00"
to_version: "MS 18.1.7.1"
wireless:
next_upgrade:
local_time: "2026-09-15T22:00:00"
to_version: "MR 32.2.3"
pre_download: true
appliance:
next_upgrade:
local_time: "2026-09-15T22:00:00"
to_version: "MX 26.1.3"
Example 3: Mixed Upgrade and Downgrade Across Products
upgrade and downgrade can coexist in the same firmware block — the constraint is per product, not per block. A product type can appear in upgrade or downgrade, but never in both at the same time.
The example below upgrades switch and appliance while simultaneously scheduling a downgrade for wireless. wireless appears only in downgrade and is absent from upgrade. If wireless were added to upgrade as well, validation would fail.
A downgrade requires a reasons list with at least one entry — the category must be one of: performance, stability, broke old features, testing, unifying networks versions, other.
meraki:
domains:
- name: !envdomain
administrator:
name: !envorg_admin
organizations:
- name: !envorg
networks:
- name: !envnetwork_name
product_types:
- appliance
- switch
- wireless
firmware:
automatic_upgrade_window:
day_of_week: "sunday"
hour_of_day: "4:00"
upgrade:
products:
switch:
next_upgrade:
local_time: "2026-08-01T22:00:00"
to_version: "MS 18.1.7.1"
appliance:
next_upgrade:
local_time: "2026-08-01T22:00:00"
to_version: "MX 26.1.3"
downgrade:
products:
wireless:
next_downgrade:
local_time: "2026-08-01T22:00:00"
to_version: "MR 31.1.8"
reasons:
- category: "stability"
comment: "MR 32.x introduced intermittent client association failures in high-density environments"