How an edge node gets a whole site - network, storage, apps - without anyone naming that node anywhere.
A deployment is a saved recipe for a site: the network to create, the storage to create, the apps to run. It lives inside a project.
It never names an edge node. Instead, nodes qualify for it. That is the whole idea: you add a site by tagging hardware, not by editing a deployment project.
Watch out: the project holding a deployment must be of type
TAG_TYPE_DEPLOYMENT - not the ordinary project type. This is the most
common setup mistake, and the error message points at the deployment rather
than the project.
Two things must line up, and a third wires the app to its network. Each is a pair that must be equal on both sides - nothing matches by name.
The edge node has to be moved into the deployment's project. A node belongs to exactly one project at a time, so this is a move, not an addition. Nothing below is even evaluated until this is true.
| On the node | On the deployment | |
|---|---|---|
deployment_tag = cisco-policy-demo | must equal | deployment_tag = cisco-policy-demo |
A project can hold more than one recipe. This says which one this node gets.
| On the node - tags | On each policy - target condition | |
|---|---|---|
demo = policy-demo | must equal | demo = policy-demo |
One deployment can carry policies for several kinds of site. Each node receives only the ones whose condition its tags satisfy.
| On the network policy - tags | On the app's NIC - netinsttag | |
|---|---|---|
demo = policy-demo-ni | must equal | demo = policy-demo-ni |
The network does not exist until a node qualifies, so the app cannot refer to it by name. It finds it by tag instead.
Target condition. A filter written on the policy, not on the node. It says: “only apply me to nodes whose tags include this exact key and value.” The policy states what it is looking for, the node carries the labels, and the controller does the matching. A policy with no target condition applies to every node that reaches the deployment.
netinsttag. The same idea one level down, and about networks instead of nodes. It is written on the app's network interface and says: “plug me into whichever network instance carries this tag.”
Why not just name the network? Because it does not exist yet. The network is created by a policy at the moment a node qualifies, and it is created separately for every node. There is no name to refer to when you are writing the config, so a label is the only stable handle.
That is the pattern behind both: an object describes what it is looking for, and the controller finds the match when the node shows up. Nothing is wired by name.
Tip: matches 2 and 3 both use the key demo with different values, which
makes them look related when they are not. Renaming the network tag key to
something like net makes it read unambiguously - demo= always means
nodes, net= always means networks.
Only matches 1 and 2 are set on the node.
deployment_tag = cisco-policy-demodemo = policy-demoThat is the entire action. No Terraform run, no touching the node. Within a minute or two the controller creates the network instance and the app instance, and the app comes up.
Instances are named from the project, the app and the device, so two nodes under one deployment never collide:
cisco-policy-demo.nginx.TF-CISCO-UCS-130C-M8-32
To drain a node, clear its deployment tag. To reset between runs, set it again.
A deployment cannot be edited in place. Terraform will report a successful apply and the controller will keep the old policies. Nothing warns you; the plan even goes clean afterwards.
Any change to a deployment needs a destroy and recreate - and the delete is refused while a node is still attached, so unbind first:
1. clear the node's deployment_tag, apply 2. terraform apply -replace='...zedcloud_deployment.demo' 3. set the deployment_tag back, apply
If you edited a deployment and nothing changed on the node, this is almost always why.
Every one of these fails silently. There is no error to read, so work down the list.
TAG_TYPE_DEPLOYMENT?deployment_tag match the deployment's, exactly?
A node reading ADMIN_STATE_REGISTERED is normal - working nodes read that
too. It does not mean the node is inactive.
Testing a published port from the node itself always fails, because traffic originating on the host skips the rule that redirects it. Test from another machine.
Verified end to end on a Cisco UCS edge node: network instance, volume and nginx all created by policy, reachable on the node's published port.
Terraform reference: cisco-ot-ign-demo-policy-based/ - see
README-full.md for API queries and the full history.