Skip to main content
Your progress
0 of 4 lessons complete0%
T2 / M2.8 / L3 OF 4 / Engineer TIER / 9 min

Accept, revoke, apply to cloud

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.


TierEngineer
JTBD”Turn derived tags into attribution today, and into real cloud tags only where that is worth doing.”
PersonasPlatform Engineer · FinOps Lead
PrerequisitesM2.8.L1 · M2.8.L2
Time9 minutes
Bloom verbWork (Apply), Decide (Evaluate), Explain (Understand)

1. Concept

There are two separate decisions here, and keeping them separate is most of the skill.

Terminal window
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

Terminal window
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 per key, not per resource. Revoking returns a key to pending; it does not blocklist it, and it does not remove anything from the cloud.

What accepting actually changes

Terminal window
ACCEPTED TAGS:
✓ count toward cost attribution in 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 invoice

That 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.

Terminal window
THE APPLY PATH
1. You select accepted tags and choose Apply to cloud
2. An apply_tag remediation job is created per resource
3. For each resource, the job SKIPS the write if the tag
already matches the live cloud value
4. Successful writes land as real provider tags
5. The whole thing is audit-logged like any other mutation
The skip in step 3 holds on BOTH the web path and the MCP
path. There is no configuration that turns it off, because a
redundant write has no upside and consumes provider API quota.

When applying is worth it

Terminal window
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 tag
The provider's own cost Provider-side allocation tags
allocation report needs it need a real tag
You are exiting the gap for Making it real ends the
good and want IaC to own it derivation dependency
DO NOT APPLY WHEN BECAUSE
─────────────────────────────────────────────────────────────
You only need ZopNight reporting Accepting already did it
The policy is still being tuned You will be writing, then
rewriting, real cloud tags
The resource is IaC-managed Your next terraform apply
reverts it, and now you have
drift that looks like an
incident

The 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. Review by derived value.

Terminal window
GROUP 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 distinct
value 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:

Terminal window
STATE AT REVIEW
Pending 412 across 7 distinct values
Accepted 1,847
STEP 1: GROUP 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 4 clicks.
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 the 184 us-east-1 resources.
apply_tag jobs created: 184
skipped (already matched): 31
written: 153
failed: 0
The 31 skips are the invariant working. Those resources
already carried the tag; the job did not spend a 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)

Terminal window
1. Open Smart Tags → Pending. Group by derived value.
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. Accept one value group. Then open 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 value group 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:
jobs ____ skipped ____ 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.

Terminal window
BEFORE A ZopNight account with one cloud connected. Enough discovered resources for predictions to be worth reviewing, and a tag convention you already use.
ASK "Show me the pending tag suggestions for this account and accept the ones above 90% confidence."
CHECK a sample by hand before accepting in bulk. Confidence is a prediction, not a promise.

Tools behind it: list_smart_tags (read, Govern), accept_smart_tag (write, tier 1, metadata only), revoke_smart_tag (write, tier 1, metadata only). The full catalogue is at zop.dev/learn/mcp-tools.


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

An “Apply to cloud” run reports 184 jobs, 31 skipped, 153 written. The 31 skips mean:

A. 31 jobs failed and need retrying
B. 31 of the resources were deleted mid-run, so the provider rejected the tag write for all of them entirely
C. Those 31 resources already carried a live cloud tag matching the derived value, so the job skipped a redundant write
D. 31 resources lacked permission

Show answer

Correct: C. This 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: it means your existing cloud tagging already agreed with the policy. Failures are reported separately; a skip is a success that cost no provider API quota.

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 grouped by value, not 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.


Glossary terms touched

Apply to cloud · dimension_source · apply_tag job · Revoke


Start with the bill.

Foundations takes about five hours. The first lesson is nine minutes.

Open curriculum. No login. No paywall. 290 lessons across 7 courses, three publicly verifiable credentials. Read it on the train, take the exam on a Saturday, list the credential on your résumé Monday.

5h median time to finish Foundations
0 logins, paywalls, or marketing forms
open curriculum, public credential verifier
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·