Declarative Networking: Automating NSX-T Fabric with Ansible
Why step-by-step imperative network scripts create orphaned API objects, and how declarative NSX-T Policy API models eliminate state drift.
βImperative scripts tell a network how to build something step by step. Declarative models specify what the final network topology must look like, letting the controller handle dependency graphs and state convergence.β
In late 2021, during my time as a Systems Integration Advisor at NTT Data, we were building an automated private cloud onboarding engine for enterprise tenants.
The legacy network team had started by writing custom Python scripts that issued individual REST API requests against the NSX Manager.
It was classic Imperative Automation:
Step 1: Create Tier-0 Router -> Step 2: Create Tier-1 Router -> Step 3: Create Logical Switch -> Step 4: Attach Router Interface -> Step 5: Apply Security Group.
On paper, the logic was straightforward. In production, it was a maintenance disaster.
The Imperative Orphan Trap
Imperative automation forces the programmer to handle every dependency failure, retry loop, and state check manually.
If Step 4 failed due to a transient API timeout or IP pool collision, the Python script terminated immediately.
It left half-created Tier-0 routers, unattached Tier-1 interfaces, and orphaned logical switches floating inside the NSX database.
# What happened when re-running the failed imperative Python script:
# Step 1: POST /api/v1/logical-routers (Create Tier-0 Router)
# Output: HTTP 409 Conflict - Object 'T0-Gateway-Prod' already exists!
Because the script wasnβt idempotent, running it a second time crashed at Step 1 because the object created during the previous failed run already existed.
Engineers were spending up to four hours after every failed deployment pass using Postman to manually track down and delete orphaned API objects before they could attempt another run.
We were spending more time cleaning up broken script state than delivering tenant environments.
The Solution: Declarative Policy Modeling with Ansible
We abandoned imperative Python scripts and refactored our automation pipelines around Declarative Policy Modeling using Ansible and the vmware.ansible_nsxt collection.
In a declarative architecture, you donβt write step-by-step instructions. You define a single YAML manifest describing the desired end-state topology.
The NSX-T Policy API receives the entire manifest, builds an internal dependency graph, and handles object creation, ordering, and error recovery automatically.
# # Declarative NSX-T Fabric Provisioning Playbook
- name: Provision Tenant Multi-Tier Network Topology
hosts: localhost
gather_facts: false
vars:
nsx_manager: '10.100.1.10'
tenant_name: 'Finance-Prod'
tasks:
- name: Ensure Tier-1 Gateway Exists
vmware.ansible_nsxt.nsxt_policy_tier1:
hostname: '{{ nsx_manager }}'
username: '{{ nsx_user }}'
password: '{{ nsx_password }}'
validate_certs: false
display_name: 'T1-{{ tenant_name }}'
tier0_id: 'T0-Gateway-Primary'
route_advertisement_types:
- 'TIER1_CONNECTED'
state: present
- name: Ensure Overlay Segment Exists
vmware.ansible_nsxt.nsxt_policy_segment:
hostname: '{{ nsx_manager }}'
username: '{{ nsx_user }}'
password: '{{ nsx_password }}'
validate_certs: false
display_name: 'Seg-{{ tenant_name }}-App'
tier1_id: 'T1-{{ tenant_name }}'
subnets:
- gateway_address: '10.200.10.1/24'
state: present
Why Declarative Convergence Wins
If the vmware.ansible_nsxt.nsxt_policy_segment task is interrupted mid-execution, re-running the playbook causes zero errors.
Ansible queries the Policy API endpoint, determines that T1-Finance-Prod already exists in the desired state, skips re-creating it, and proceeds directly to ensuring Seg-Finance-Prod-App is instantiated correctly.
# Executing the declarative Ansible playbook
ansible-playbook -i localhost, deploy_tenant_fabric.yml
# Output: PLAY RECAP ***********************************************************
# localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0
The Impact
- Zero Orphaned Objects: Eliminated 100% of partial API object pollution in the NSX database.
- True Idempotency: Enabled instant, safe playbook re-runs; network engineers could execute the pipeline ten times in a row with identical result states.
- Provisioning Speed: Reduced tenant network instantiation time from 45 minutes of manual step checks to 2 minutes of declarative execution.
Key Takeaway
Adopt Declarative APIs for Infrastructure Code.
Do not write imperative scripts that manually manage API dependency order and state checks. Use declarative models like Ansible and the NSX-T Policy API to specify the target topology, letting the underlying SDN controller manage dependency resolution and state convergence automatically.
Architecture and decisions: mine. Debugging sessions at odd hours: mine. AI assistance: structure, syntax, first draft. β Sachin
Sachin Kumar Sharma
Associate Director (Infrastructure & Cloud Architecture Strategy) | 20+ Yrs Exp
Architecting resilient multi-cloud enterprise landing zones, SDN overlay fabrics, DevSecFinOps automation pipelines, and autonomous Agentic AI platforms.
π‘ Related Engineering Articles
From CLI to Code: Standardizing Network Infrastructure Pipelines
Why manual SSH terminal sessions destroy network auditability, and how we shifted our operations team to a GitOps model using Ansible and GitLab CI.
Day-0 Firewall Rules: Automating Security Baseline Insertion
How we eliminated the manual ticket bottleneck by injecting security baselines directly into the provisioning pipeline of NSX-T logical segments.
The ovftool Silent Failure: Automating OVF Deployments at Scale Without Headless Timeout Crashes
Why headless ovftool CLI calls hang indefinitely in CI/CD pipelines, and how pre-flight answerfile schema validation eliminated silent deployment crashes.
π¬ Stay Updated on Tech Releases
Sign up to get notified when I publish new production war stories, agentic AI architecture blueprints, or open-source infrastructure tools.