Inconsistencies in Amazon's Tag Handling in AWS

Pulling together some material from a PR I started related to terraform.

The other day I was working on some issue or other with terraform and decided that it should do validation of the AWS tags attached to the resources which support them. The patch to support this is "tiny".

After submitting the PR I then got the following bit of feedback on the request.

I'm afraid that the validation rules aren't that simple however, because we use this generic tagsSchema() in multiple resources whose tags impose different limitations.

For example

all of EC2 - RDS - R53 -

And for some reason I just couldn't accept this. It really bothered me that AWS would have an inconsistency like this. And in something that I consider pretty fundamental to the AWS ecosystem. (Though don't get me started on the fact that not all resources are taggable...) So I decided to do some research starting with EC2, RDS and R53.

The tagging standards being different everywhere bothered me... so I decided to do some research instead. I think there's some more to do here (do the same analysis on all of the tagable resource types) but figured I'd share the results I have since I'm waiting for some efs resources to initialize.

From the specifications:

Service Key Length Value Length Validation
route53 128 256 Not specified
ec2 127 255 letters, spaces, and numbers representable in UTF-8, plus the following special characters: + - = . _ : / @
rds 128 256 the string may contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-'

Those all looked suspiciously similar to me... so similar that I was skeptical that the restrictions are actually different. So I went and tested them experimentally. :-)

Take rds... their documentation kind of says they support the same set of restrictions as ec2... the only difference is the @ and : symbols seems to be missing:

Restricted chars from specifications:

Service + - = . _ : / @
ec2 X X X X X X X X
rds X X X X X X
route53 ? ? ? ? ? ? ? ?

But testing rds experimentally it supports having both : and @ in the tags... And actually the fact that it allows : makes sense since amazon uses aws: and rds: as prefixes that they specifically mention you can't use as a user... though apparently that's just a recommendation... the console UI let me set those as well.

I tested route53 as well and it seems to support the same restricted set as the other two services.

Restricted chars from experimentation (differences highlighted in bold):

Service + - = . _ : / @
ec2 X X X X X X X X
rds X X X X X X X X
route53 X X X X X X X X

For the length restrictions I compared the actuals to the documented values.

Service Key Len Spec Key Len Actual Val Len Spec Val Len Actual
route53 128 128 256 256
rds 128 128 256 255
ec2 127 127 255 255

So on the length side... we find that the docs actually have a mistake in them and the max length for the rds value is actually 255 not 256.

Later on I went and followed up the inital experimentation by working through the taggable resources that I've used before from this Top 30 Amazon services list. That resulted in the following tables.

Supported Characters

Service + - = . _ : / @
efs X X X X X X X X
s3 X X X X X X X X
redshift X X X X X X X X
elasticache X X X X X X X X
acm X X X X X X X X
kinesis X X X X X X X X
vpc X X X X X X X X


Service Key Len Spec Key Len Actual Val Len Spec Val Len Actual
efs ? 128 ? 256
s3 128 128 256 256
redshift 128 128 256 256
elasticache 128 128 256 256
acm 127 128 255 256
kinesis 128 128 255 256
vpc ? 127 ? 255

These sorts of inconsistencies in AWS have always bothered me and I confirmed with some colleagues who work there that a lot of this is related to the microservice/team model that Amazon uses for AWS' development.

One of the terraform folks suggest that I should throw this up somewhere more permanently... so here it is. :-)