Tags


https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html
https://docs.aws.amazon.com/tag-editor/latest/userguide/best-practices-and-strats.html
https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html
https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html
https://github.com/hashicorp/terraform-provider-aws/blob/main/website/docs/index.html.markdown

1. Important Points#

AWS tag 的真实用途是资源检索、成本分摊、责任归属、自动化和 ABAC。Name 只适合 human readable,不能替代 tags。

tag design principles:
    use consistent tag keys and allowed values
    do not put secret / customer PII / ticket detail in tags
    use tags for filter, cost allocation, ownership, automation, and audit
    use AWS Organizations tag policies when tags must be enforced at org scale
    use IAM condition keys / ABAC only after tag governance is stable

Tag key style:

AWS org-scale recommendation:
    use lowercase hyphen keys with organization prefix
    example:
        acme:project
        acme:environment
        acme:managed-by

common small-team style:
    use PascalCase keys
    example:
        Project
        Environment
        ManagedBy

Pick one style and keep it consistent. This repository already uses Project / Environment / ManagedBy in several Terraform examples, so the examples below use PascalCase. If your AWS Organization has a formal tag policy, prefer the organization standard.

2. Tag Levels#

Minimum tags:

Tag Example Why
Project order product / workload boundary
Environment prod dev / uat / prod separation
ManagedBy terraform ownership by automation

Recommended operational tags:

Tag Example Why
Region ap-east-1 cost/CMDB/audit filters across regions
Stack ecs Terraform root module or platform layer
Service api service ownership and alarm/dashboard grouping
Owner platform accountable owner
Team platform team routing

Cost and governance tags:

Tag Example Why
CostCenter cc-1234 cost allocation reports
Criticality high incident priority / backup / DR policy
DataClass internal data handling policy
Compliance pci compliance scope

3. Region And Stack#

Region and Stack are useful, but not mandatory.

Region is useful when:
    cost reports need tag-based regional filtering
    CMDB / inventory tools ingest tags but not AWS region metadata
    multi-region incident review needs resource context quickly

Region can be skipped when:
    account and tooling already make region obvious
    adding it creates noisy duplication without reporting value
Stack is useful when:
    one environment has multiple Terraform root modules
    examples:
        monitoring
        sns
        vpc
        ecs
        rds

    resource owner needs to know which Terraform state manages it
    cost allocation needs platform layer split, for example network vs database vs alerting

Stack can be skipped when:
    one root module manages only one obvious stack
    Terraform state / naming / repository layout already answers ownership clearly

Practical default:

small baseline:
    Project
    Environment
    ManagedBy

good default:
    Project
    Environment
    Region
    Stack
    ManagedBy

organization / production:
    Project
    Environment
    Region
    Stack
    Service
    Owner
    Team
    CostCenter
    Criticality
    ManagedBy

4. Terraform Pattern#

Put stable common tags in provider.default_tags. Put resource-specific tags on resources or modules.

locals {
  project     = "order"
  environment = "prod"
  region      = "ap-east-1"
  stack       = "ecs"
  service     = "api"

  common_tags = {
    Project     = local.project
    Environment = local.environment
    Region      = local.region
    Stack       = local.stack
    Service     = local.service
    ManagedBy   = "terraform"
    Owner       = "alice.chen@example.com"
    Team        = "checkout-platform"
    CostCenter  = "fin-ops-042"
    Criticality = "high"
  }
}

provider "aws" {
  region = local.region

  default_tags {
    tags = local.common_tags
  }
}

Resource-specific tags:

resource "aws_subnet" "private_app" {
  for_each = local.private_app_subnets

  vpc_id            = aws_vpc.main.id
  cidr_block        = each.value.cidr
  availability_zone = each.value.az

  tags = {
    Name        = "${local.project}-${local.environment}-private-app-${each.key}-subnet"
    NetworkTier = "private"
    SubnetRole  = "private-app"
    RouteScope  = "nat"
  }
}

resource "aws_cloudwatch_metric_alarm" "lambda_errors" {
  alarm_name = "${local.project}-${local.environment}-${local.service}-lambda-errors-high"

  tags = {
    Name              = "${local.project}-${local.environment}-${local.service}-lambda-errors-high"
    Severity          = "p1"
    AlarmSignal       = "errors-high"
    MetricNamespace   = "AWS/Lambda"
    RunbookUrl        = "https://docs.example.com/runbooks/lambda-errors"
    DashboardUrl      = "https://console.aws.amazon.com/cloudwatch/"
  }
}

5. Resource-Specific Tags#

Use these only where they add real filter value.

Resource Area Extra Tags Example Values
VPC / subnet NetworkTier, SubnetRole, RouteScope private, private-app, nat
ALB / target group Exposure, Protocol, Service public, https, api
ECS / Lambda Runtime, Service, Criticality nodejs22, api, high
RDS / cache DataClass, BackupPolicy, Criticality confidential, daily-35d, high
SQS / SNS MessageClass, Producer, Consumer event, api, worker
CloudWatch alarm Severity, AlarmSignal, RunbookUrl, DashboardUrl p1, 5xx-high, URL
IAM AccessScope, PrincipalType deploy, ci

Do not tag everything with every possible key. A tag should answer one of these questions:

who owns it?
what project/service/env is it for?
which Terraform stack manages it?
how is cost allocated?
how should automation select it?
how should incident response route it?

6. Cost / ABAC / Tag Policy#

Cost allocation:

activate cost allocation tags in Billing
CostCenter / Project / Environment / Service are common report dimensions
tags only help cost reports after activation and ingestion delay

ABAC:

use tags in IAM conditions only after tag quality is enforced
examples:
    allow operations only when aws:ResourceTag/Environment = prod
    allow creation only when aws:RequestTag/Project is present

risk:
    inconsistent tags can become inconsistent access control

Tag policies:

use AWS Organizations tag policies to standardize keys and allowed values
tag policies help detect/enforce casing and values
they do not replace IAM permissions

7. Checklist#

baseline:
    Project
    Environment
    ManagedBy

recommended:
    Region
    Stack
    Service
    Owner / Team

when needed:
    CostCenter
    Criticality
    DataClass
    Compliance
    RunbookUrl / DashboardUrl for alarms

avoid:
    secrets or customer PII in tags
    mixing Project and project as different keys
    changing tag key names after cost reports and IAM policies depend on them
    relying on Name for Terraform data filters when a structured tag exists