AWS / Guide 3

Tagging and governance

A tag strategy finance can use, and tag policies, SCPs and AWS Config to enforce it.

Tags answer the questions that come up every month: who owns this, what does it belong to, and who pays for it. In AWS they matter even more than in Azure, because there are no resource groups: tags are the only way to group resources across services. Tag policies, service control policies and AWS Config make sure the answers are there.

A tag strategy that finance can use

Keep the set small and required. The same five tags as the Azure notes work well:

TagExampleWhy
Ownerjane@ravindran.inWho to ask before changing or deleting it
CostCenterCC-1042Who pays; used for showback and chargeback
EnvironmentProduction, Test, DevDifferent rules, schedules and priorities
ApplicationPayrollGroups resources across services
DataClassificationConfidentialDrives security controls

Rules worth writing down:

  • Tag keys and values are case-sensitive in AWS. CostCenter and costcenter are two different tags, and both will appear in cost reports. Pick one spelling and enforce it.
  • Add Name too. The console shows the Name tag as the resource's display name for EC2, EBS and VPC resources.
  • Tag at creation. Most services accept tags in the create call, and SCPs (below) can refuse creates without them. Tags added later miss the cost of the hours before.
  • Tags don't flow down automatically. An EC2 instance's tags aren't copied to its volumes unless you set it: use launch templates with tag specifications for instances, volumes and network interfaces, and CloudFormation stack-level tags, which propagate to supported resources.
  • Limits: 50 user tags per resource; keys up to 128 characters, values up to 256. The aws: prefix is reserved.
  • Don't put secrets or personal data in tags. Many people and tools can read them.

Enforce names and values with tag policies

A tag policy in AWS Organizations defines the exact spelling of each tag key and its allowed values. Attached to the root or an OU, it reports non-compliant tags, and can optionally block non-compliant tagging for the resource types you list.

{
  "tags": {
    "Environment": {
      "tag_key": { "@@assign": "Environment" },
      "tag_value": { "@@assign": [ "Production", "Test", "Dev" ] },
      "enforced_for": { "@@assign": [ "ec2:instance", "ec2:volume", "s3:bucket" ] }
    },
    "CostCenter": { "tag_key": { "@@assign": "CostCenter" } }
  }
}

Note what it doesn't do: a tag policy checks tags that are there, but can't require a tag to exist. For that, use an SCP or AWS Config.

Require tags at creation with an SCP

This SCP refuses to launch an EC2 instance or create a volume without a CostCenter tag. It works per API action and resource type, so add the services you care about most, and test it on the Sandbox OU first:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "RequireCostCenterOnCreate",
    "Effect": "Deny",
    "Action": [ "ec2:RunInstances", "ec2:CreateVolume" ],
    "Resource": [ "arn:aws:ec2:*:*:instance/*", "arn:aws:ec2:*:*:volume/*" ],
    "Condition": { "Null": { "aws:RequestTag/CostCenter": "true" } }
  }]
}

Check compliance with AWS Config

AWS Config records the configuration of every resource and evaluates rules against it. It's the AWS counterpart of Azure Policy's audit side, and several other guides rely on it. Turn it on in every account and region through Control Tower or an organisation-wide deployment, and send the data to the log archive account.

  • The managed rule required-tags reports resources missing up to six tags you name.
  • Conformance packs bundle rules: start with Operational Best Practices for CIS AWS Foundations Benchmark or the AWS Foundational Security Best Practices checks in Security Hub (Guide 6).
  • Remediation can run a Systems Manager Automation document to fix what a rule finds, automatically or on request.
  • Watch the cost. Config charges per configuration item recorded. Record globally-scoped resources (IAM) in one region only, and consider periodic rather than continuous recording for resource types that change constantly in non-production.
# Which Config rules are non-compliant in this account and region
Get-CFGComplianceByConfigRule -ComplianceType NON_COMPLIANT |
    Select-Object ConfigRuleName, @{n='Compliance';e={$_.Compliance.ComplianceType}}

# Resources failing the required-tags rule
Get-CFGComplianceDetailsByConfigRule -ConfigRuleName 'required-tags' -ComplianceType NON_COMPLIANT |
    ForEach-Object { $_.EvaluationResultIdentifier.EvaluationResultQualifier } |
    Select-Object ResourceType, ResourceId

For a direct list of what's missing which tags, across regions, run Get-AwsUntaggedResources.ps1.

Tags in cost reports

Tags don't appear in Cost Explorer or the Cost and Usage Report until you activate them as cost allocation tags in the management account (Billing and Cost Management > Cost allocation tags). Activation isn't retroactive, so do it on day one. Also:

  • Cost categories map accounts, tags and services to business units, and fill gaps (for example "everything in payroll-prod is Payroll, whether tagged or not").
  • Account-level tags and a one-workload-per-account layout mean most costs are allocated correctly even when a resource tag is missing.

Other guardrails worth setting early

  • Allowed regions: an SCP that denies actions outside your approved regions, with the documented exceptions for global services.
  • Allowed instance types: an SCP condition on ec2:InstanceType for non-production OUs, which stops accidental very large instances.
  • Protect the logging: deny cloudtrail:StopLogging, config:StopConfigurationRecorder and guardduty:DeleteDetector for everyone except a break-glass role.
  • Block public sharing: declarative policies for EBS snapshot and AMI block public access, and S3 Block Public Access at account level (Guide 5).

Examples to try

From aws.ravindran.in: S3 object tags, CloudFormation (stack tags propagate to resources), and CloudFormation drift detection.