Lesson 5 of 6

Policy Automation

Objective

In this lesson you will use the SD-WAN Manager (vManage) REST APIs to programmatically create, validate, and activate a centralized policy for traffic steering and route-based control. Automating policy deployment is critical in large-scale networks where manual GUI work is error-prone and slow. In production, automated policies let you push consistent security, QoS, and application-aware routing across hundreds of edge devices in minutes.

Quick Recap

We use the same topology introduced in Lesson 1. No new physical devices are added in this lesson — we operate against the vManage server and the two edge routers that are already onboarded.

ASCII Topology (from Lesson 1):

                           +----------------------+
                           |      vManage         |
                           |  vmanage.lab.nhprep.com
                           |  IP: 10.1.1.10       |
                           +----------+-----------+
                                      |
                    Overlay Control Plane (TLS) / API
                                      |
        +-----------------------------+-----------------------------+
        |                                                           |
+---------------+                                           +----------------+
| SFO-EDGE      |                                           | NYC-EDGE       |
| Router name:  |                                           | Router name:   |
| sfo-edge      |                                           | nyc-edge       |
| Edge overlay  | 172.16.1.1/30 (Tunnel IP)                  | 172.16.1.2/30  |
| LAN: 192.168.10.0/24 (Gi0/1)                                | LAN: 192.168.20.0/24 (Gi0/1)
+---------------+                                           +----------------+

Device table

DeviceHostnameIP / FQDN
SD-WAN ManagervManagevmanage.lab.nhprep.com (10.1.1.10)
Edge RouterSFOsfo-edge (overlay 172.16.1.1, LAN 192.168.10.1)
Edge RouterNYCnyc-edge (overlay 172.16.1.2, LAN 192.168.20.1)

Note: API credentials used in examples: username admin, password Lab@123. Domain names use lab.nhprep.com.

Key Concepts

Before we automate policies, understand these core ideas:

  • Controller-centric policy model: vManage stores a single source of truth (policy objects) that are distributed to edges. When you create a policy via the API, you are changing that central store; vManage then computes device-specific configs and pushes them to each edge.

    Think of vManage as a policy manufacturing plant: you submit a master design (policy), and the plant fabricates device-ready blueprints and ships them.

  • Policy lifecycle: create → validate → activate: Programmatic workflows should follow these phases. Validation checks JSON schema and logical consistency; activation instructs vManage to push to devices. Skipping validation increases risk of runtime errors and partial deployments.

  • Idempotency & naming: If automation runs repeatedly, the same policy name should not create duplicates. Use unique names or use update semantics (PUT vs POST) so repeated runs produce the same result.

  • Control plane packet flow during activation: When you activate a policy, vManage computes changes and opens control channel sessions (TLS) to impacted edges to deliver device configs. Edges apply the config and may restart certain services locally (e.g., policy agent). Expect brief, localized path changes — design maintenance windows for high-risk policies.

Step-by-step configuration

Step 1: Obtain vManage authentication token

What we are doing: Authenticate to vManage REST API to get a session token. This token is required for subsequent API calls so vManage can authorize the automation.

# Use curl to authenticate and obtain a token
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"j_username":"admin","j_password":"Lab@123"}' \
  https://10.1.1.10:8443/j_security_check

What just happened: The POST sends the username/password to the vManage login endpoint. On success, vManage sets an HTTP session cookie (JSESSIONID) which your automation must include in further requests to authenticate. This step matters because vManage will reject API operations without a valid session.

Real-world note: In production, use API keys or OAuth where available and never store plaintext credentials in code repositories.

Verify:

# Verify by requesting the system status which requires authentication
curl -k -b cookie_jar.txt -c cookie_jar.txt https://10.1.1.10:8443/dataservice/system/status

{
  "currentTime": "2026-04-02T12:00:00Z",
  "status": "UP",
  "version": "20.12.1",
  "clusterStatus": "SINGLE",
  "uptime": "72 days 4 hours"
}

Explanation: A successful authenticated GET returns JSON showing vManage system status. If you instead see HTML login page content, authentication failed.

Step 2: Create a policy object (JSON) for traffic steering

What we are doing: Submit a policy definition JSON that describes traffic match conditions and routing actions (e.g., prefer MPLS for voice traffic). Policies are high-level intent that vManage translates into per-device configs.

# POST the policy JSON to create a centralized policy
curl -k -X POST \
  -H "Content-Type: application/json" \
  -b cookie_jar.txt \
  https://10.1.1.10:8443/dataservice/template/policy \
  -d '{
        "policyName": "Prefer-MPLS-For-Voice",
        "description": "Steer UDP/5060 and UDP/10000-20000 over MPLS when available",
        "sequence": [
          {
            "match": {
              "protocol": "udp",
              "destinationPort": "5060,10000-20000"
            },
            "action": {
              "preferredPath": "mpls",
              "preference": 50
            }
          },
          {
            "match": {
              "any": true
            },
            "action": {
              "preferredPath": "default",
              "preference": 100
            }
          }
        ]
      }'

What just happened: The POST creates a policy object named Prefer-MPLS-For-Voice in vManage. The JSON defines a sequence: traffic matching UDP SIP/RTP ranges prefers the MPLS transport (lower preference value = higher priority), other traffic follows the default. This high-level policy does not yet change device configuration until activated.

Real-world note: Use human-readable policy names and include descriptions for auditability; automation should tag policies with change IDs.

Verify:

# GET the newly created policy and show full JSON
curl -k -b cookie_jar.txt https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice

{
  "policyName": "Prefer-MPLS-For-Voice",
  "description": "Steer UDP/5060 and UDP/10000-20000 over MPLS when available",
  "sequence": [
    {
      "match": {
        "protocol": "udp",
        "destinationPort": "5060,10000-20000"
      },
      "action": {
        "preferredPath": "mpls",
        "preference": 50
      }
    },
    {
      "match": {
        "any": true
      },
      "action": {
        "preferredPath": "default",
        "preference": 100
      }
    }
  ],
  "status": "CREATED",
  "createdBy": "admin",
  "createdOn": "2026-04-02T12:05:00Z"
}

Explanation: The GET returns the full stored policy JSON. Status remains "CREATED" until validation/activation.

Step 3: Validate the policy (schema and simulation)

What we are doing: Ask vManage to validate the JSON policy for schema correctness and run a dry-run simulation to ensure the policy compiles against the current device topology. Validation helps catch errors before impacting live devices.

# POST to validate the policy; vManage responds with validation results
curl -k -X POST \
  -H "Content-Type: application/json" \
  -b cookie_jar.txt \
  https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/validate

What just happened: vManage checks the policy structure, field names, and semantics. It also simulates which devices and flows would be affected. Validation prevents syntactic mistakes (e.g., missing fields) and logical errors (e.g., unknown transport name).

Real-world note: Always script validation as part of CI/CD pipelines so human approval occurs only for pre-validated changes.

Verify:

# Expected validation output (complete JSON)
{
  "policyName": "Prefer-MPLS-For-Voice",
  "valid": true,
  "messages": [
    {
      "level": "INFO",
      "text": "Policy validated successfully against current topology."
    }
  ],
  "simulation": {
    "affectedDevices": [
      {
        "deviceId": "sfo-edge",
        "deviceName": "sfo-edge",
        "matchedSequences": [1]
      },
      {
        "deviceId": "nyc-edge",
        "deviceName": "nyc-edge",
        "matchedSequences": [1]
      }
    ]
  }
}

Explanation: A "valid": true response with simulation results shows which devices would be impacted. If valid is false, parse messages for errors.

Step 4: Activate the policy to target devices

What we are doing: Activate (push) the validated policy to selected devices (SFO and NYC edges). Activation tells vManage to compute device-specific configs and transmit them to the edges over the control channel.

# POST to activate and target the two devices by deviceName
curl -k -X POST \
  -H "Content-Type: application/json" \
  -b cookie_jar.txt \
  https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/activate \
  -d '{
        "targetDevices": ["sfo-edge", "nyc-edge"],
        "activationDescription": "Automated activation: Prefer MPLS for voice traffic - ChangeID 20260402-01"
      }'

What just happened: The activation endpoint instructs vManage to render the policy to device-level configuration and deliver it to the selected edges. vManage coordinates the control-plane connection to each edge and monitors the push. On each edge, the policy agent applies the new forwarding preference for matched traffic.

Real-world note: Activating policies can trigger local route or forwarding changes. For critical services schedule maintenance windows and test on a small device set first.

Verify:

# Query activation status for the policy
curl -k -b cookie_jar.txt https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/status

{
  "policyName": "Prefer-MPLS-For-Voice",
  "status": "ACTIVATED",
  "activatedOn": "2026-04-02T12:10:00Z",
  "devices": [
    {
      "deviceName": "sfo-edge",
      "deviceId": "sfo-edge",
      "applyStatus": "SUCCESS",
      "applyMessage": "Policy applied and active"
    },
    {
      "deviceName": "nyc-edge",
      "deviceId": "nyc-edge",
      "applyStatus": "SUCCESS",
      "applyMessage": "Policy applied and active"
    }
  ]
}

Explanation: The status shows the policy is ACTIVATED and each targeted device reported SUCCESS. If any device shows FAILURE, inspect per-device logs and retry or rollback.

Step 5: Monitor and roll back if needed

What we are doing: Monitor traffic flows and, if necessary, deactivate the policy to roll back changes. Automated workflows should include a health-check and an automated rollback path when certain thresholds are exceeded.

# Deactivate (rollback) the policy if needed
curl -k -X POST \
  -H "Content-Type: application/json" \
  -b cookie_jar.txt \
  https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/deactivate \
  -d '{
        "targetDevices": ["sfo-edge", "nyc-edge"],
        "deactivationDescription": "Automated rollback due to voice quality threshold breach"
      }'

What just happened: The deactivate call instructs vManage to remove the policy's effect from the targeted devices. vManage re-renders device configs without the policy and pushes the updated configs to edges. This is a controlled rollback rather than a device-level manual change, preserving the central policy state.

Real-world note: Build automated telemetry checks (e.g., MOS, packet loss) that trigger this step when SLA thresholds are violated.

Verify:

# Confirm deactivation status
curl -k -b cookie_jar.txt https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/status

{
  "policyName": "Prefer-MPLS-For-Voice",
  "status": "DEACTIVATED",
  "deactivatedOn": "2026-04-02T12:25:00Z",
  "devices": [
    {
      "deviceName": "sfo-edge",
      "deviceId": "sfo-edge",
      "applyStatus": "SUCCESS",
      "applyMessage": "Policy removed"
    },
    {
      "deviceName": "nyc-edge",
      "deviceId": "nyc-edge",
      "applyStatus": "SUCCESS",
      "applyMessage": "Policy removed"
    }
  ]
}

Explanation: Deactivation returns device-level results. Keep audit logs of activation/deactivation timestamps and reasons.

Verification Checklist

  • Check 1: Policy created — Verify with GET policy endpoint to see the JSON and "status": "CREATED".
    • Command: GET https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice
  • Check 2: Policy validated — Verify valid: true and simulation affectedDevices list.
    • Command: POST https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/validate
  • Check 3: Policy activated and applied — Verify status: ACTIVATED and per-device applyStatus: SUCCESS.
    • Command: GET https://10.1.1.10:8443/dataservice/template/policy/Prefer-MPLS-For-Voice/status

Common Mistakes

SymptomCauseFix
API returns HTML login page instead of JSONNot authenticated / session cookie missingAuthenticate first, store cookies, reuse cookie jar for subsequent calls
Validation fails with schema errorJSON field names or structure incorrectCompare to vManage API schema; fix field names and required elements; use JSON linting
Activation shows FAILURE on some devicesDevice connectivity or certificate issueCheck device control connections, re-onboard device or re-establish TLS; confirm device is in vManage inventory
Re-running automation creates duplicate policiesUsed POST without idempotency or unique namesUse unique policy names or use PUT/update semantics; check existing policies before create

Key Takeaways

  • Use the vManage API workflow: authenticate → create policy → validate → activate. Validation prevents many runtime errors.
  • Centralized policies are translated per-device; activation pushes device-specific configs over the control channel — expect localized, short-lived changes during application.
  • Automate idempotently: name policies clearly and implement update semantics so reruns do not create duplicates.
  • Always include monitoring and automated rollback in your deployment pipeline to minimize user impact when policy changes cause unintended behavior.

Tip: In production, integrate these API steps into CI/CD tooling and require human approval before activating high-impact policies. This balances automation speed with operational safety.