This solution tags AWS resources with the tags of principals automatically. A tag set is created by merging IAM tags and session tags, which is finally applied to all resources in the triggered CloudWatch event.
The following resources are currently supported.
Service | Resources |
---|---|
EC2 | Instance, Volume, Image, Snapshot, Security Group, NACL, Elastic IP, Elastic Network Interface, Launch Template |
VPC | VPC, Subnet, Internet Gateway, NAT Gateway, Transit Gateway, Customer Gateway, VPC Gateway, VPC Endpoint, RouteTable, VPC Peering Connection |
ELB | Application Load Balancer, Network Load Balancer, Target Group |
SSM | Document, Parameter, OpsItem, PatchBaseline, MaintenanceWindow |
DynamoDB | Table, GlobalTable, Backup |
RDS | DBInstance, DBInstanceReadReplica, DBSnapshot, DBClusterSnapshot, GlobalCluster |
Lambda | Function |
S3 | Bucket, Object |
ElastiCache | CreateCacheCluster, CreateSnapshot, CopySnaphot |
Athena | |
Glue | |
ECS | Service, TaskSet, Cluster |
EKS | NodeGroup, Cluster |
SNS | Topic |
SQS | Queue |
Secrets Manager | Secret |
Session tags are key-value pair attributes that you pass when you assume an IAM role or federate a user in AWS STS. You do this by making an AWS CLI or AWS API request through STS or through your identity provider (IdP). When you use AWS STS to request temporary security credentials, you generate a session. Sessions expire and have credentials, such as an access key pair and a session token. When you use the session credentials to make a subsequent request, the request context includes the aws:PrincipalTag context key. You can use the aws:PrincipalTag key in the Condition element of your policies to allow or deny access based on those tags.
When you use temporary credentials to make a request, your principal might include a set of tags. These tags come from the following sources:
-
Session tags – These tags were passed when you assumed the role or federated the user.
-
Incoming transitive session tags – These tags were inherited from a previous session in a role chain.
-
IAM tags – These tags were attached to the IAM role that you assumed.
However, there is no way to retrieve session-tags and transitive tag keys from the STS session using AWS API at the moment. That is why we need to fetch session tags from STS events and store in a database together with the principal (user/role ARN) information.
Tag factory consists of a lambda function, which processes the CloudWatch events initially and decides which tag handler to invoke using the event source field.
Each tag handler follows these steps in order:
-
Parse the event data and fetch all resource identifiers. For example, an EC2 event may contains various resources such as instances, volumes and security groups.
-
Fetch IAM principal ARN from the event.
-
Call AWS APIs to fetch IAM tags of the principal and add an Owner tag to specify the resource owner principal.
-
Fetch session tags from the database, if exists, for this session (principal ARN + session name).
-
Merge tags to create the final tag-set to apply; session tags overwrites IAM tags if there is a duplicate.
-
Apply the tag set to all the resources.
CloudWatch event rules are setup per service by CDK stacks.
Each rule triggers the lambda function, lambda/tag_handler/tag_handler.py, which then passes event to the Tag Factory for further processing as described above.
This solution is deployed by using AWS CDK. It has two independent components:
- aws-tags-stack: automated tagging feature, inherits tags from the principal who created it.
- aws-session-stack: (experimental) stores session tags in DynamoDb and applies them when tagging resources.
The session handler is also deployed to us-east-1 as it hosts the global STS endpoint. STS:AssumeRole* events are handled by this region and the tags are stored in your default region.
python3 -m venv .env`
$ source .env/bin/activate
If you are a Windows platform, you would activate the virtualenv like this:
% .env\Scripts\activate.bat
Once the virtualenv is activated, you can install the required dependencies.
$ pip install -r requirements.txt
At this point you can now synthesize the CloudFormation template for this code.
$ cdk synth
If the previous step is successful, you can deploy this stack to your default AWS account/region.
$ cdk deploy aws-session-stack aws-tags-stack us aws-session-stack-us [--profile <AWS-PROFILE>]
To add additional dependencies, for example other CDK libraries, just add
them to your setup.py
file and rerun the pip install -r requirements.txt
command.
cdk ls
list all stacks in the appcdk synth
emits the synthesized CloudFormation templatecdk diff
compare deployed stack with current statecdk docs
open CDK documentation