Outcome
By the end of this lesson, you will be able to work the pending and accepted queues, decide when to write a derived tag back to the cloud provider, and explain what the apply job does and what it deliberately skips.
| Prerequisites | M2.8.L1 · M2.8.L2 |
| Time | 9 minutes |
1. Concept
There are two separate decisions here, and keeping them separate is most of the skill.
DECISION 1: ACCEPT "Should this derived value count toward cost attribution inside ZopNight?" Cheap. Reversible. Writes nothing to your cloud.
DECISION 2: APPLY TO CLOUD "Should this value also become a real tag on the real resource in AWS / GCP / Azure?" A cloud write. Reversible only by another cloud write.Most teams should do a lot of the first and very little of the second.
The two-state model
derived │ ├── value == live cloud tag ──> ACCEPTED (automatic) │ └── otherwise ──────────────────> PENDING │ accept ───┤ ▼ ACCEPTED │ revoke ───┤ ▼ PENDING
pending = derived − accepted. There is no reject state.Accept and revoke operate on a resource and the keys you name; the page lets you select many resources and accept or revoke in bulk. Revoking returns a key to pending; it does not blocklist it, and it does not remove anything from the cloud.
What accepting actually changes
ACCEPTED TAGS: ✓ count toward cost attribution in Costs → Reports → Tags ✓ carry dimension_source = "auto" (cloud tags carry "cloud"), so a report can tell you which is which ✓ move spend out of the Unattributed bucket ✗ do NOT appear in your cloud console ✗ do NOT affect your cloud provider's own cost allocation tags or your invoiceThat last pair is why accepting is cheap: attribution improves inside ZopNight, and nothing outside ZopNight changes. It is also why dimension_source matters. A tag showing as auto is one ZopNight derived; a tag showing as cloud came from the resource. When a report is challenged, that column is how you answer “where did this number come from.”
Apply to cloud
Applying writes the accepted value onto the real resource as a real tag, executed as an apply_tag remediation job. It is on demand, never automatic.
THE APPLY PATH 1. You select accepted tags and choose Apply to cloud 2. ZopNight drops any tag whose value already matches the live cloud value. A resource left with nothing to write gets no job at all 3. An apply_tag remediation job is created per remaining resource 4. Successful writes land as real provider tags 5. The whole thing is audit-logged like any other mutation
The skip in step 2 holds on BOTH the web path and the MCPpath. There is no configuration that turns it off, because aredundant write has no upside and consumes provider API quota.When applying is worth it
APPLY WHEN BECAUSE─────────────────────────────────────────────────────────────Another tool reads the tag Your cloud-native budget, an SCP, a Tag Policy, or a third-party tool cannot see a ZopNight virtual tagThe provider's own cost Provider-side allocation tagsallocation report needs it need a real tagYou are exiting the gap for Making it real ends thegood and want IaC to own it derivation dependency
DO NOT APPLY WHEN BECAUSE─────────────────────────────────────────────────────────────You only need ZopNight reporting Accepting already did itThe policy is still being tuned You will be writing, then rewriting, real cloud tagsThe resource is IaC-managed Your next terraform apply reverts it, and now you have drift that looks like an incidentThe IaC row is the one that bites. A resource under Terraform with default_tags will have your applied tag removed on the next apply, silently, and the resource will reappear as pending. If you want the tag to persist on an IaC-managed resource, the change belongs in the IaC, not in an apply job.
Working the queue efficiently
Do not review pending resource by resource. Decide by derived value, then select every resource carrying that value and accept in bulk. The page lists resources, not values, so tally the values first.
TALLY BY VALUE, THEN DECIDE ONCE:
team = payments 184 resources -> accept team = platform 96 resources -> accept team = analytics 72 resources -> accept team = i-0a3f9c2b1d 1 resource -> leave pending team = eksctl 41 resources -> leave pending
Five decisions, 394 resources. One decision per distinctvalue is the whole review.If a value needs per-resource judgement, that is a signal the policy axis is wrong, not that you need to work harder. Go back to L2 and change the policy.
2. Demo
A quarterly Smart Tags review, and the one apply that was justified:
STATE AT REVIEW Pending 472 across 7 distinct values Accepted 1,847
STEP 1: TALLY THE PENDING QUEUE BY VALUE cost-allocation = aws-us-east-1 184 -> accept cost-allocation = aws-eu-west-1 96 -> accept cost-allocation = gcp-europe-west1 72 -> accept cost-allocation = aws-ap-south-1 60 -> leave (wrong axis for the analytics estate) team = eksctl 41 -> leave (junk) team = i-0a3f... 1 -> leave (junk) workload-class = ec2-compute 18 -> accept
Accepted: 370 resources, in four bulk accepts. Unattributed: 31% -> 9%. Nothing written to any cloud account.
STEP 2: DID ANYTHING NEED TO BE REAL? One case: the finance team's AWS cost-allocation report is built provider-side, off real AWS tags, and cannot see a ZopNight virtual tag.
Applied cost-allocation to all 215 accepted us-east-1 resources: the 184 just accepted, plus 31 auto-accepted earlier because their cloud tag already matched. skipped before dispatch (already matched): 31 apply_tag jobs created: 184 written: 184 failed: 0
The 31 skips are the invariant working. Those resources already carried the tag, so ZopNight created no job and spent no write on them.
STEP 3: WHAT WAS NOT APPLIED, AND WHY The gcp-europe-west1 group is entirely Terraform-managed. Applying would have been reverted on the next plan. Raised a PR against the module's default labels instead.Step 3 is the mature move. The apply button was available and would have appeared to work.
3. Hands-on (6 min)
1. Open Smart Tags → Pending Review. Tally the derived values. How many DISTINCT values are pending? ______ How many RESOURCES? ______ The ratio is your review cost. If distinct values is above about 20, fix the policy, not the queue.
2. Select the chips for one derived value across resources (there is no group-by-value view; filter by provider and select in bulk) and click Accept. Then open Costs → Reports → Tags and confirm the Unattributed figure moved. Before ____% After ____%
3. Find one accepted tag and check its Source badge. Does it read `auto` or `cloud`? _________ Explain in one line why that distinction matters when someone challenges a chargeback number: ______________________________________________
4. For one derived value you have NOT applied, answer: - does any tool outside ZopNight read this tag? Y / N - is the resource set IaC-managed? Y / N Apply only if the first is Y and the second is N.
5. If you apply anything, record the skip count: skipped ____ jobs ____ written ____ A high skip count is good news about your existing tagging, not a failure.Do it through MCP. The same task you just did in the console, asked in one sentence.
BEFORE A ZopNight account with one cloud connected. Enough discovered resources for derived tags to be worth reviewing, and a tag convention you already use.ASK "Show me the pending tag values for this account, and which policy derived each one."CHECK a sample by hand before accepting in bulk. A derived value is only ever as good as the rule behind it.Tools behind it: list_smart_tags (read, Govern), accept_smart_tag (write, tier 1, metadata only), revoke_smart_tag (write, tier 1, metadata only), apply_smart_tags (write, tier 2, writes the tags to the cloud). Connection details are in the MCP integration docs.
4. Knowledge check
Q1
You accept a derived team tag on 370 resources. What changed in your AWS account?
A. Nothing
B. 370 resources now carry a new AWS tag
C. The tags are queued for a nightly sync
D. Only the AWS resources are tagged; GCP and Azure are not
Show answer
Correct: A. Accepting makes the value count toward cost attribution inside ZopNight and marks it dimension_source = auto; it writes nothing to any cloud provider. Writing to the cloud is a separate, explicit “Apply to cloud” action that runs as an apply_tag remediation job. This separation is what makes accepting cheap and reversible. Revoking an accepted tag returns it to pending and, likewise, touches nothing in the cloud.
Q2
You apply an accepted tag to 215 resources. 31 of them already carry a live cloud tag with exactly that value. What happens to those 31?
A. Their jobs fail and need retrying
B. The provider rejects the duplicate write on each one
C. ZopNight skips them before dispatch; no job is created
D. They are reported as lacking permission
Show answer
Correct: C. The skip happens in ZopNight before any job is dispatched, so only the 184 resources that need a write get an apply_tag job. It is the same matching rule that auto-accepts a derived tag at derivation, and it holds on both the web and MCP apply paths. A high skip count is good news: your existing cloud tagging already agreed with the policy.
Q3
A group of 72 pending resources is entirely managed by Terraform with default_tags. Applying the derived tag to the cloud would:
A. Work permanently, since ZopNight writes the tag directly to the cloud provider’s own tag store directly
B. Fail immediately with a permission error
C. Trigger a drift alert in Terraform that blocks the apply
D. Succeed now and be silently reverted on the next terraform apply, after which the resources reappear as pending
Show answer
Correct: D. The durable fix is a PR against the IaC module’s default tags; the apply button is available here and is the wrong tool. This is the trap worth remembering: the operation appears to work. Nothing warns you that the resource is IaC-managed, so the check has to be yours, and the reappearing pending entries are the only signal you will get.
5. Apply
Work the Smart Tags pending queue by deciding per derived value (select its chips across resources and accept them together) rather than resource by resource, and treat accepting as the default. Reserve Apply to cloud for the cases where something outside ZopNight genuinely needs to read the tag, and check for IaC management first.
Related lessons
- L2: Writing a tagging policy
- L4: Reconciliation and drift (next)
- T4.M4.5.L3: Tag attribution
- T3.M3.6.L1: Tag enforcement in Terraform / CDK / Pulumi