Skip to main content

ADR-008: Tag Governance — Enterprise + FOCUS 1.2+ Co-existence Strategy

  • Status: Proposed
  • Date: 2026-02-27
  • Deciders: HITL/Manager, Product Owner, Cloud Architect
  • Supersedes: ADR-XVAL-005 (advisory finding — Owner/Repository gap)

What​

Maintain two parallel tagging systems on all Terraform-managed AWS resources:

  1. Enterprise tags (PascalCase) — organizational taxonomy feeding CMDB, ServiceNow, and AWS Cost Explorer
  2. FOCUS 1.2+ tags (snake_case prefixed x_) — cross-cloud FinOps allocation per FOCUS specification

Add the two missing APRA-mandated Enterprise tags (Owner and Repository) to projects/sso/versions.tf default_tags.

Why​

Tag System Comparison​

AttributeEnterprise TagsFOCUS 1.2+ Tags
Key formatPascalCase (CostCenter)snake_case with prefix (x_cost_center)
Consumed byAWS Cost Explorer, ServiceNow CMDB, CloudTrail, APRA auditorsFinOps dashboards, cross-cloud cost tooling, FOCUS-compliant exporters
GranularityOrganizational (repo-level Project)Workload-level (x_project = "sso")
OverlapCostCenter = "platform"x_cost_center = "platform" (same value, different system)
Intentional divergenceProject = "terraform-aws" (repo identity)x_project = "sso" (workload identity)
Required byAPRA CPS 234, enterprise CMDB contractFOCUS 1.2+ specification

Why Project != x_project (correct by design)​

Project = "terraform-aws" identifies the IaC repository (all modules in this repo share it). x_project = "sso" identifies the billable workload (FOCUS SubProduct concept). These serve different consumers: enterprise CMDB tracks the repository unit; FinOps dashboards track workload spend. Aligning them to the same value would corrupt FOCUS cost attribution.

Why CostCenter and x_cost_center co-exist​

This is a transition architecture. Enterprise tags predate FOCUS adoption. Removing CostCenter would break CMDB integrations. Adding x_cost_center enables FOCUS tooling without migration. When the organization completes FOCUS migration, CostCenter may be deprecated (future ADR).

Why Owner and Repository are required​

APRA CPS 234 Para 15 requires asset inventory with accountability. The ADLC template (ADR-XVAL-005) identified these as missing from projects/sso/versions.tf. They are not enforced by CKV_APRA_001 (which only checks data_classification on aws_ssoadmin_permission_set), but they ARE required by the organizational APRA tagging template and CMDB contract.

Who​

  • HITL/Manager: Approves tag governance policy
  • Cloud Architect: Designs co-existence strategy (this ADR)
  • Infrastructure Engineer: Applies Owner + Repository tags to versions.tf

When​

ActionOwnerSprint
ADR-008 proposedCloud ArchitectSprint 2
versions.tf updated with Owner + RepositoryInfrastructure EngineerSprint 2
ADR-008 accepted by HITLHITLSprint 2
FOCUS migration assessment (future)Product OwnerSprint 5+

Where​

  • Primary change: projects/sso/versions.tf provider "aws" { default_tags {} }
  • Secondary: modules/sso/ resources inherit via default_tags + merge() pattern
  • Checkov: .checkov/custom_checks/check_apra_cps234.py (CKV_APRA_001) and check_focus_tags.py (CKV_CUSTOM_FOCUS_001)

How​

Target Tag Block (versions.tf)​

provider "aws" {
region = "ap-southeast-2"

default_tags {
tags = {
# ── Enterprise Tags (PascalCase) ─────────────────────────────────────
# Consumed by: AWS Cost Explorer, ServiceNow CMDB, APRA CPS 234 audits
# Scope: repository-level (all modules in terraform-aws share these)
Project = "terraform-aws" # IaC repository identity (NOT workload)
Environment = "sandbox"
CostCenter = "platform" # Organizational cost centre (CMDB)
Owner = "platform@oceansoft.io" # APRA Para 15: accountable individual/team
Repository = "https://github.com/nnthanh101/terraform-aws" # APRA asset registry
Compliance = "APRA-CPS234"
ManagedBy = "terraform"

# ── APRA CPS 234 Additional ──────────────────────────────────────────
# Para 15: Data classification required on all information assets
data_classification = "internal"

# ── FOCUS 1.2+ Tags (snake_case, x_ prefix) ──────────────────────────
# Consumed by: FinOps dashboards, cross-cloud cost exporters
# Scope: workload-level (intentionally different granularity from Enterprise)
# NOTE: x_cost_center intentionally mirrors CostCenter during FOCUS transition
# NOTE: x_project != Project by design (workload != repository)
x_cost_center = "platform" # FOCUS BillingAccountId allocation
x_environment = "sandbox" # FOCUS EnvironmentName
x_project = "sso" # FOCUS SubProductName (workload, not repo)
x_service_name = "sso" # FOCUS ServiceName
}
}
}

Checkov Compliance​

CheckIDEnforcesSatisfied by
APRA data classificationCKV_APRA_001data_classification on aws_ssoadmin_permission_setdata_classification = "internal" in default_tags -> merges to all resources
APRA least privilegeCKV_APRA_002No AdministratorAccessNo change from this ADR
APRA session durationCKV_APRA_003Session <= 8hNo change from this ADR
FOCUS 1.2+ tagsCKV_CUSTOM_FOCUS_0014 x_ tags on taggable resourcesAll 4 x_ tags present in default_tags

Owner and Repository have no current checkov enforcement. Documented here for APRA Para 15 accountability traceability. A future CKV_APRA_004 check may enforce them.

Consequences​

Benefits​

  1. No breaking changes to existing CMDB integrations (Enterprise tags retained)
  2. FOCUS 1.2+ tooling can ingest correctly-scoped workload tags immediately
  3. x_project correctly identifies workload spend independent of repository structure
  4. APRA Para 15 accountability gap closed (Owner, Repository added)
  5. Inline comments make the co-existence rationale durable in the codebase

Tradeoffs​

  1. 11-tag block is verbose — mitigated by inline comments grouping the two systems
  2. CostCenter and x_cost_center carry identical values during transition — acceptable duplication

Risks​

RiskProbabilityImpactMitigation
Future engineer removes x_cost_center assuming it duplicates CostCenterMediumMediumInline comments + this ADR explain the necessity
FOCUS spec updates require additional x_ tagsLowLowADR review cycle at each FOCUS spec minor version
APRA auditor requires CKV_APRA_004 for Owner/RepositoryLowMediumTags are already present; adding a check is non-breaking

Alternatives Considered​

  1. Single merged tag set (normalize to FOCUS only): Rejected — breaks existing CMDB contract; CMDB expects PascalCase keys
  2. Remove FOCUS tags from default_tags, apply per-resource: Rejected — increases maintenance surface; default_tags is the right DRY pattern
  3. Rename x_project to match Project: Rejected — corrupts FOCUS SubProduct/workload attribution

Coordination Evidence​

  • Product Owner log: tmp/terraform-aws/coordination-logs/product-owner-2026-02-27.json
  • Cloud Architect log: tmp/terraform-aws/coordination-logs/cloud-architect-2026-02-27-adr-cost-tags.json