Skip to main content

Naming Cheatsheet for best Pracices

· 16 min read
Derrick Futschik (Derrops)
Head of Engineering, Fortiro

Quick reference guide for naming AWS resources following the Derrops conventions. All examples assume account-segregated environments (preferred approach).

Core Format: {org}--{domain}--{service}--{key} (compound kebab-case with -- segment delimiters)


Template Variables Reference

Before using this cheatsheet, understand what each placeholder means:

VariableDefinitionExampleRequired?Notes
{region}AWS region codeap-southeast-2, us-east-1, eu-west-1✅ Only for globally unique services (S3, CloudFront, ACM, Route53)Omit if using account-per-region segregation
{env}Deployment environmentprod, dev, staging, uat✅ Only for globally unique services (S3) or DNSOmit if using account-per-environment segregation (recommended)
{org}Organization/top-level business unitacme, mycompany, client-name✅ Always requiredMost stable segment; rarely changes
{domain}Business capability / bounded domainpayments, identity, analytics, platform✅ Always requiredOwned independently; more stable than teams
{service}Deployable service unitcheckout-api, auth-service, webhook-worker✅ Always requiredThe primary identity; can be renamed/refactored
{key}Specific resource or config within servicetransactions, webhook-secret, primary, cache✅ Always requiredPurpose-specific identifier; changes frequently
{partition}Data partition grouping (logs, events only)2024/01/15/14, 2024-01-15❌ Optional; data storage onlyOnly for time-series or partitioned data in S3/Glue
{purpose}Functional purposealb, db, lambda, encryption-enabled✅ When needed for clarityQualifies the resource type
{type}Resource subtypeweb, worker, private, public, primary, replica✅ When distinguishing variantsMakes specific instances identifiable
{az}Availability zone1a, 1b, 1c✅ For multi-AZ resourcesEnsures subnets are distributed
{consumer}API consumer/clientmobile-client, partner-integrations, internal✅ For API keys and accessIdentifies who consumes the resource
{target}Target system for data sourcedynamodb, rds, lambda, s3✅ For integration pointsWhat the resource connects to
{num}Sequential number01, 02, 03❌ Optional; for instance namingZero-padded for sorting
{yyyy}/{mm}/{dd}/{hh}Date/time partitions2024/01/15/14✅ For time-series data onlyEach level is independently queryable
{file}Filenametransactions.json, logs.parquet✅ For object/file storageThe final artifact identifier
{version} or {tag}Semantic version or release tag1.2.3, latest, v2.0.0-beta✅ For images and artifactsIdentifies specific release
{registry}Container registry host123456789.dkr.ecr.ap-southeast-2.amazonaws.com, docker.io✅ For container imagesWhere the image is hosted

Summary Table - All Services

ServiceFormatPatternDelimiterExample
S3 BucketGlobal + prefixap-southeast-2--prod--{org}--{domain}--{service}--{key}-ap-southeast-2--prod--acme--payments--checkout-api--backups
S3 Object KeysHierarchy{org}/{domain}/{service}/{key}/acme/payments/checkout-api/schema.sql
S3 Logs/EventsWith partition{org}/{domain}/{service}/{yyyy}/{mm}/{dd}/{hh}/{file}/acme/payments/checkout-api/2024/01/15/14/transactions-00001.json
CloudWatch LogsHierarchy/{org}/{domain}/{service}/{key}//acme/payments/checkout-api/application-logs
CloudWatch Metrics (Namespace)Hierarchy (org/domain only){org}/{domain}/acme/payments
CloudWatch Metric (Dimensions)Key-value pairsservice={service} (env via account, not dimension)N/Aservice=checkout-api, service=order-processor
CloudWatch Metric NamesFlat kebab{key}-{metric-type}-request-count, error-rate, latency-p99
ECS ClusterFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--cluster
ECS ServiceFlat kebab{org}--{domain}--{service}-- / -acme--payments--checkout-api
ECS Task DefinitionFlat kebab{org}--{domain}--{service}-- / -acme--payments--checkout-api
ECR RepositoryRegistry path{org}/{domain}/{service}/acme/payments/checkout-api
ECR Image TagSemantic{registry}/{org}/{domain}/{service}:{version}/ :123456789.dkr.ecr.ap-southeast-2.amazonaws.com/acme/payments/checkout-api:1.2.3
DynamoDB TableFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--transactions
DynamoDB GSIFlat kebab{key}--gsi-- / -transactions-by-user--gsi
RDS Instance IDFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--primary
RDS DB NameFlat snake{org}_{domain}_{service}_acme_payments_checkout_api
RDS Parameter GroupFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--params
RDS Subnet GroupFlat kebab{org}--{domain}--{service}--subnet-group-- / -acme--payments--checkout-api--subnet-group
EC2 InstanceFlat kebab{org}--{domain}--{service}--{type}-{num}-- / -acme--payments--checkout-api--web-01
EC2 Security GroupFlat kebab{org}--{domain}--{service}--{purpose}-- / -acme--payments--checkout-api--alb
EC2 VolumeFlat kebab{org}--{domain}--{service}--volume-{purpose}-- / -acme--payments--checkout-api--volume-data
EC2 Elastic IPFlat kebab{org}--{domain}--{service}--eip-- / -acme--payments--checkout-api--eip
Lambda FunctionFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--webhook-handler
Lambda LayerFlat kebab{org}--{domain}--{service}--{purpose}-- / -acme--shared-utilities--common-libs
Lambda AliasSimpleprod, dev, stagingN/Aprod
IAM RolePath + namePath: /{org}/{domain}/{service}/ Name: {service}--{purpose}-role/ -- -ARN: arn:aws:iam::123456789:role/acme/payments/checkout-api/checkout-api--lambda-role
IAM PolicyPath + namePath: /{org}/{domain}/{service}/ Name: {purpose}-policy/ -acme--payments--checkout-api--s3-access-policy
IAM UserFlat kebab{org}--{domain}--{service}--user-- / -acme--payments--checkout-api--service-user
Route53 Hosted ZoneSubdomainprod.acme.com (env from account).prod.acme.com
Route53 DNS RecordReverse hierarchy{service}.prod.acme.com.checkout-api.prod.acme.com
Route53 Private ZoneInternal DNS{service}.internal.prod.acme.com.checkout-api.internal.prod.acme.com
CloudFront DistributionFlat kebab{org}--{domain}--{service}--cdn-- / -acme--payments--checkout-api--cdn
CloudFront Alias (CNAME)DNS pattern{service}.prod.acme.com.checkout-api.prod.acme.com
ACM Certificate DomainDNS pattern{service}.prod.acme.com.checkout-api.prod.acme.com
ACM Wildcard CertDNS wildcard*.prod.acme.com.*.prod.acme.com
VPCFlat kebab{org}--{domain}--{service}--vpc-- / -acme--payments--checkout-api--vpc
SubnetFlat kebab{org}--{domain}--{service}--subnet-{type}-{az}-- / -acme--payments--checkout-api--subnet-private-1a
Route TableFlat kebab{org}--{domain}--{service}--rt-{type}-- / -acme--payments--checkout-api--rt-private
Network ACLFlat kebab{org}--{domain}--{service}--nacl-- / -acme--payments--checkout-api--nacl
ALB/NLBFlat kebab{org}--{domain}--{service}--alb-- / -acme--payments--checkout-api--alb
Target GroupFlat kebab{org}--{domain}--{service}--tg-{purpose}-- / -acme--payments--checkout-api--tg-api
SNS TopicFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--transactions
SQS QueueFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--events
SQS FIFO QueueFlat kebab{org}--{domain}--{service}--{key}.fifo-- / -acme--payments--checkout-api--events.fifo
SQS DLQFlat kebab{queue-name}--dlq-- / -acme--payments--checkout-api--events--dlq
Kinesis StreamFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--events
EventBridge BusFlat kebab{org}--{domain}--{service}--events-- / -acme--payments--checkout-api--events
EventBridge RuleFlat kebab{org}--{domain}--{service}--{key}-rule-- / -acme--payments--checkout-api--process-webhook-rule
Step FunctionsFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--order-processing
API Gateway REST APIFlat kebab{org}--{domain}--{service}--api-- / -acme--payments--checkout-api--api
API Gateway HTTP APIFlat kebab{org}--{domain}--{service}--http-api-- / -acme--payments--checkout-api--http-api
API Gateway StageSimpleprod, dev, stagingN/Aprod
API Gateway KeyFlat kebab{org}--{domain}--{service}--{consumer}-- / -acme--payments--checkout-api--mobile-client
AppSync APIFlat kebab{org}--{domain}--{service}--api-- / -acme--payments--checkout-api--api
AppSync Data SourceFlat kebab{org}--{domain}--{service}--{target}-- / -acme--payments--checkout-api--dynamodb
ElastiCache ClusterFlat kebab{org}--{domain}--{service}--cache-- / -acme--payments--checkout-api--cache
ElastiCache Replication GroupFlat kebab{org}--{domain}--{service}--replication-group-- / -acme--payments--checkout-api--replication-group
ElastiCache Parameter GroupFlat kebab{org}--{domain}--{service}--params-- / -acme--payments--checkout-api--params
OpenSearch DomainFlat kebab{org}--{domain}--{service}-- / -acme--payments--checkout-api
OpenSearch IndexHierarchy{org}/{domain}/{service}/{key}/{date}/acme/payments/checkout-api/transactions/2024-01-15
RDS ProxyFlat kebab{org}--{domain}--{service}--proxy-- / -acme--payments--checkout-api--proxy
AWS Backup PlanFlat kebab{org}--{domain}--{service}--backup-plan-- / -acme--payments--checkout-api--backup-plan
AWS Backup VaultFlat kebab{org}--{domain}--{service}--vault-- / -acme--payments--checkout-api--vault
Glue DatabaseFlat snake{org}_{domain}_{service}_acme_payments_checkout_api
Glue TableFlat snake{key}N/Atransactions
Glue JobFlat kebab{org}--{domain}--{service}--{key}-job-- / -acme--analytics--etl--transform-job
Glue CrawlerFlat kebab{org}--{domain}--{service}--{key}-crawler-- / -acme--analytics--data-crawlers
Athena WorkgroupFlat kebab{org}--{domain}--{service}--workgroup-- / -acme--analytics--etl--workgroup
Athena Results BucketS3 key paths3://bucket/{org}/{domain}/{service}//s3://acme-analytics-athena-results/acme/analytics/etl/
QuickSight DatasetFlat kebab{org}--{domain}--{service}--dataset-- / -acme--analytics--transactions--dataset
QuickSight AnalysisFlat kebab{org}--{domain}--{service}--{key}-analysis-- / -acme--analytics--revenue-dashboard--analysis
QuickSight DashboardFlat kebab{org}--{domain}--{service}--{key}-- / -acme--analytics--revenue-dashboard
Redshift ClusterFlat kebab{org}--{domain}--{service}--cluster-- / -acme--analytics--warehouse--cluster
Redshift DatabaseFlat snake{org}_{domain}_{service}_acme_analytics_warehouse
Redshift Subnet GroupFlat kebab{org}--{domain}--{service}--subnet-group-- / -acme--analytics--warehouse--subnet-group
MSK ClusterFlat kebab{org}--{domain}--{service}--cluster-- / -acme--events--streaming--cluster
Kafka TopicDotted path{org}.{domain}.{service}.{key}.acme.payments.checkout-api.transactions
AppConfig ApplicationFlat kebab{org}--{domain}--{service}-- / -acme--payments--checkout-api
AppConfig EnvironmentSimpleprod, dev, stagingN/Aprod
AppConfig ProfileFlat kebab{org}--{domain}--{service}--{key}-profile-- / -acme--payments--checkout-api--feature-flags-profile
Systems Manager DocumentFlat kebab{org}--{domain}--{service}--{key}-- / -acme--payments--checkout-api--runbook
Systems Manager Maintenance WindowFlat kebab{org}--{domain}--{service}--maintenance-- / -acme--payments--checkout-api--patching-window
Service Catalog PortfolioFlat kebab{org}--{domain}--portfolio-- / -acme--payments--portfolio
Service Catalog ProductFlat kebab{org}--{domain}--{service}--product-- / -acme--payments--checkout-api--product
X-Ray Sampling RuleFlat kebab{org}--{domain}--{service}--sampling-rule-- / -acme--payments--checkout-api--sampling-rule
Config RuleFlat kebab{org}--{domain}--{service}--{key}-rule-- / -acme--payments--checkout-api--encryption-enabled-rule
Config AggregatorFlat kebab{org}--{domain}--config-aggregator-- / -acme--payments--config-aggregator
Security Hub Custom InsightFlat kebab{org}--{domain}--{service}--{key}-insight-- / -acme--payments--checkout-api--critical-findings-insight
WAF Web ACLFlat kebab{org}--{domain}--{service}--waf-- / -acme--payments--checkout-api--waf
WAF IP SetFlat kebab{org}--{domain}--{service}--{purpose}-ipset-- / -acme--payments--checkout-api--blocked-ips
WAF Rule GroupFlat kebab{org}--{domain}--{service}--rules-- / -acme--payments--checkout-api--rate-limit-rules
CloudFormation StackFlat kebab{org}--{domain}--{service}--{key}-stack-- / -acme--payments--checkout-api--stack
SSM ParameterHierarchy/{org}/{domain}/{service}/{key}//acme/payments/checkout-api/stripe-webhook-secret
Secrets Manager SecretHierarchy{org}/{domain}/{service}/{key}/acme/payments/checkout-api/db-password
Auto Scaling GroupFlat kebab{org}--{domain}--{service}--asg-- / -acme--payments--checkout-api--asg
Launch TemplateFlat kebab{org}--{domain}--{service}--launch-template-- / -acme--payments--checkout-api--launch-template

⚠️ Critical: Native Hierarchy Detection

Many services support their own native hierarchical constructs. Always check if a service has native hierarchy support BEFORE applying -- segment delimiters. Using native hierarchies enables:

  • Prefix filtering and querying
  • Permission scoping via path-based policies
  • Better operational organization
  • Automatic drill-down capabilities in console

Example: CloudWatch metrics require careful structure:

  • Namespace uses / for org/domain ONLY (e.g., acme/payments) ← USE THIS FOR HIERARCHY
  • Dimensions include service={service} (e.g., service=checkout-api); env via account boundary ← USE THIS FOR CROSS-SERVICE QUERIES
  • Metric names use - for words only (e.g., request-count, error-rate) ← Use this for specifics

Why? This enables meaningful queries like "all services in payments domain with high CPU" by filtering the service dimension, not namespaces. Each account's metrics are naturally isolated, maintaining permission boundaries while maximizing query utility!


Delimiter Decision Matrix

Use CaseDefault DelimiterNotesWhen to OverrideServices
Segment separator (org↔domain↔service↔key)-- (double hyphen)Separates major naming segments; most readableALWAYS check for native hierarchy firstAll flat resource names
Word within segment- (hyphen)Words/parts within a single segmentNever—always use - for wordsAll resource names
Path hierarchy (native)/ (slash)Native hierarchical support—use instead of --Use / instead of -- when availableS3 keys, SSM Parameters, Secrets, IAM paths, ECR, CloudWatch Logs, CloudWatch Metrics namespaces
DNS hierarchy (native). (dot)Native DNS subdomain separation—use instead of --Use . instead of -- when availableRoute53, DNS records, CloudFront aliases, Kafka topics
Image tag/version (native): (colon)Native registry delimiter for versioningUse : after image nameECR, Docker registries
Database internal names_ (underscore)DB-friendly; only for internal schema names, NOT identifiersUse _ instead of - for DB/schema names onlyRDS database names, Glue databases

Global vs Regional Scope

Resource TypeScopeIncludes region?Includes env?Example
S3 BucketsGlobally unique✅ Yes (ap-southeast-2)✅ Yes (prod)ap-southeast-2--prod--acme--payments--checkout-api--backups
Route53 Hosted ZonesGlobal DNS❌ No✅ Via account (prod.acme.com)prod.acme.com
CloudFront DistributionsGlobal CDN❌ No✅ Via DNS (prod)checkout-api.prod.acme.com
ACM CertificatesGlobal DNS❌ No✅ Via DNS (prod)checkout-api.prod.acme.com
IAM RolesGlobal (within account)❌ No❌ No (via account)/acme/payments/checkout-api/checkout-api-role
All Regional ServicesRegional❌ No (via account)❌ No (via account)acme-payments-checkout-api

Native Hierarchy Support

PRIORITY: Always use native hierarchies when available. They provide operational benefits flat names cannot.

ServiceNative SupportDelimiterExampleBenefit
S3 Object Keys✅ YES/acme/payments/checkout-api/schema.sqlPrefix filtering, drill-down in console
SSM Parameter Store✅ YES//acme/payments/checkout-api/stripe-keyGetParametersByPath queries, IAM scoping
Secrets Manager✅ YES/acme/payments/checkout-api/db-passwordPrefix filtering, organized in console
IAM Paths✅ YES//acme/payments/checkout-api/Path-based IAM policies, permission scoping
ECR Repositories✅ YES/acme/payments/checkout-apiNamespace organization in console
CloudWatch Logs✅ YES//acme/payments/checkout-api/logsLog group filtering and organization
CloudWatch Metrics (Namespace)✅ YES/ (org/domain only)acme/paymentsNamespace filtering; service as dimension enables cross-service queries
OpenSearch Indices✅ YES/acme/payments/checkout-api/transactions/2024-01-15Index pattern matching, time-series organization
Route53 DNS✅ YES.checkout-api.payments.acme.comDNS delegation, zone scoping
Kafka Topics✅ YES.acme.payments.checkout-api.eventsTopic organization, consumer group scoping
DynamoDB Tables❌ NO-Use {org}--{domain}--{service}--{key}No hierarchy support; use -- delimiters
RDS Instances❌ NO-Use {org}--{domain}--{service}--{key}No hierarchy support; use -- delimiters
Lambda Functions❌ NO-Use {org}--{domain}--{service}--{key}No hierarchy support; use -- delimiters
ECS/EC2 Resources❌ NO-Use {org}--{domain}--{service}--{key}No hierarchy support; use -- delimiters

Common Pitfalls & Solutions

PitfallProblemWhy It MattersSolution
Using _ in S3 bucket namesS3 rejects underscoresS3 bucket naming constraintUse - (hyphens) everywhere
Inconsistent names across environmentsCannot query resources across envsBreaks filtering in CloudWatch, Config, Security HubUse identical logical names in all accounts
Including {env} when account-segregatedRedundant naming; violates consistency principleNames become longer, harder to read; breaks queriesOmit {env} if managing via account boundaries
Randomly suffixed namesNames become unpredictableMakes automation fragile; breaks IaCUse account/region namespace for uniqueness
Changing {org} or {domain}Breaks all downstream references and policiesAll IAM policies, CloudWatch filters, and automation failKeep these segments stable; only change {service}
Not using native delimitersLoses prefix querying capabilityCannot use S3 prefix filtering, SSM GetParametersByPathUse / for hierarchical systems, . for DNS
DNS names don't mirror resourcesRouting confusion; cross-team coordination failureApplications cannot find correct endpointsDNS = reversed hierarchy (service.domain.org.com)
Resource name > service character limitTruncation breaks conventionNames get auto-truncated; cannot predict final nameTest limits early; use shorter domain/service names
Mixed kebab and snake caseTools cannot parse consistentlyScripts fail; team confusion; automation breaksUse kebab-case (-) for all naming except DB internals
Forgetting tagging for cost allocationCannot allocate costs accuratelyWrong cost attribution; misleading cost reportsTag every resource with CostCenter, Owner, Service

Quick Reference by Layer

Infrastructure Layer

VPC: acme--payments--checkout-api--vpc
Subnet: acme--payments--checkout-api--subnet-private-1a
Security Group: acme--payments--checkout-api--alb

Compute Layer

ECS Cluster: acme--payments--checkout-api--cluster
ECS Service: acme--payments--checkout-api
EC2 Instance: acme--payments--checkout-api--web-01
Lambda: acme--payments--checkout-api--webhook-handler

Data Layer

DynamoDB: acme--payments--checkout-api--transactions
RDS Instance: acme--payments--checkout-api--primary
RDS Database: acme_payments_checkout_api
ElastiCache: acme--payments--checkout-api--cache
S3 Bucket: ap-southeast-2--prod--acme--payments--checkout-api--data

Messaging Layer

SNS Topic: acme--payments--checkout-api--transactions
SQS Queue: acme--payments--checkout-api--events
SQS DLQ: acme--payments--checkout-api--events--dlq
Kinesis Stream: acme--payments--checkout-api--events

Integration Layer

API Gateway: acme--payments--checkout-api--api
Step Functions: acme--payments--checkout-api--order-processing
EventBridge Rule: acme--payments--checkout-api--process-webhook-rule

Observability Layer

CloudWatch Logs: /acme/payments/checkout-api/application-logs
CloudWatch Metrics:
Namespace: acme/payments (org/domain only)
Dimensions: service=checkout-api (env via account boundary)
Metric Name: request-count, error-rate, latency-p99
Example Query: "All high-CPU services in payments" → Query namespace acme/payments, filter by service dimension
Permission Boundary: Account segregation; no env dimension needed
X-Ray Rule: acme--payments--checkout-api--sampling-rule
Config Rule: acme--payments--checkout-api--encryption-enabled-rule

Security Layer

IAM Role: /acme/payments/checkout-api/checkout-api--lambda-role
IAM Policy: acme--payments--checkout-api--s3-access-policy
WAF Web ACL: acme--payments--checkout-api--waf
ACM Certificate: checkout-api.prod.acme.com

DNS Layer

Hosted Zone: prod.acme.com
DNS Record: checkout-api.prod.acme.com
Route53 Private Zone: checkout-api.internal.prod.acme.com
CloudFront Alias: checkout-api.prod.acme.com

Storage/Config Layer

S3 Object Key: acme/payments/checkout-api/schema.sql
SSM Parameter: /acme/payments/checkout-api/stripe-webhook-secret
Secrets Manager: acme/payments/checkout-api/db-password

Tagging Strategy

Apply these tags to all resources for cost allocation and resource management:

Tag KeyValueExamplePurpose
orgOrganizationacmeTop-level ownership
domainBusiness domainpaymentsCapability boundary
serviceService namecheckout-apiDeployment unit
environmentDeployment stageprodOptional if account-segregated
ownerTeam/personpayments-teamResponsibility tracking
cost-centerCost allocationpayments-teamBilling attribution
backup-requiredbooleantrueBackup policy enforcement
terraformbooleantrueIaC management indicator

Implementation Checklist

  • Define segments: org, domain, service values
  • Account strategy: 1 per environment? (Recommended: yes)
  • Test naming: Create 1-2 sample resources in non-prod
  • Document exceptions: Route53 reverse hierarchy, DNS patterns
  • Create IAM policies: Use path prefixes for least privilege
  • Enable AWS Config: Enforce naming patterns automatically
  • Set up tagging: Apply tags to non-nameable resources
  • Create runbooks: How to find resources by naming convention
  • Train team: Share cheatsheet and examples
  • Monitor drift: Regular audits for non-compliant names

Format Comparison Examples

Use CasePrefix HierarchyDNS ReverseFlat KebabResult
Same service across systems/acme/payments/checkout-apicheckout-api.payments.acme.comacme-payments-checkout-api✅ All represent same logical resource
Different purposes/acme/payments/checkout-api/ordersN/Aacme-payments-checkout-api-orders✅ Additional scope via suffix
Env segregated/acme/prod/payments/checkout-apicheckout-api.prod.acme.com❌ Not used (handled via account)✅ Account provides namespace
With partition (logs)acme/payments/checkout-api/2024/01/15/logsN/AN/A✅ Hierarchical querying in S3

One-Liner Reference

Need to name a resource? Apply this logic in order:

  1. Does it support native hierarchy? → Use it (/ for paths, . for DNS)
  2. Is it globally unique (S3, ACM, CloudFront)? → Add ap-southeast-2--prod-- prefix (literal region and env values)
  3. Is it DNS-based? → Use reverse hierarchy: {service}.prod.acme.com (env in domain via account)
  4. Otherwise → Use format: {org}-{domain}-{service}-{key} with - delimiters, -- between segments
  5. Tag everything else that doesn't support naming