Skip to main content

A tool for simplifying swarming of fixing AWS tags

Project description


A tool for simplifying multiple people fixing tags by proposing a tag a day for resources with those missing tags.

Build Status PyPI version


pip install aws-tag-a-day


# Generate configuration file
mkdir -p ~/.config/tagaday/
cat > ~/.config/tagaday/config.yml <<EOY
dynamodb-table-name: 'tag-proposals'
dynamodb-table-region: 'eu-west-2'
- rds
- ec2
- s3
- emr
- us-east-1
- us-west-1
- eu-west-1
- ap-southeast-1
- ap-northeast-1
- Project
- Owner
- Name
- Service
- Availability

# Create dynamodb table defined in the above config file.
# If the table exists already, the utility will not overwrite it.

# Start proposing tags


There are a lot of tools for handling batch tagging, but not many tools for aiding in filling in empty tags on a large scale.

The suggested workflow is:

  1. Create configuration file.
  2. Create a DynamoDB table by running tag-a-day-initialise. This is not a destructive operation, and existing tables will not be modified or removed. The utility will throw an error if the table already exists.
  3. Have 1 or more people start using tag-a-day.
  4. Reconcile any divergent or duplicate tags by running tag-a-day-reconcile, and discuss any duplicate tagging suggestions.
  5. Apply the tags to the resources.

NOTE: Steps 4 and 5 are not yet implemented by this utility.


Supported Services

Configuration File & CLI options

Configuration File Key Type CLI Option Type Description
regions: List --regions Comma separated string List of regions to audit resources in
services: List --services Comma separated string List of services to audit
required-tags: List --required-tags Comma separated string List of tags which must be present on all resources
dynamodb-table-name: String --dynamodb-table-name String Name of the DynamoDB table to propose tags to. If used in conjunction with tag-a-day-initialise, this will be the DynamoDB table to be created.
dynamodb-table-region: String --dynamodb-table-region String AWS Region in which to look for --dynamodb-table-name. If used in conjunction with tag-a-day-initialise this will be the region which the DynamoDB table will be created in.
--resource-ids Comma separated string List of resource ids, to filter only for specific resources to propose tags for.
--profile-path String File path pointing to a folder where tag profiles are located
--profile String File name (including .yaml/.yml suffix) point to a particular tagging profile in --profile-path


aws-tag-a-day is built on a plugin architecture, using entry_point in setuptools.

To add more TagHandlers, you can either add classes to this repo, or create a new python package with its own, and hook into the plugin architecture using the tag_a_day.tag_handlers entrypoint.

  1. Create a new class, inheriting from

    from import Service
    class CustomTagHandler(Service): pass
  2. Set a unique name for the Tag handler

    from import Service
    class CustomTagHandler(Service):
  3. Create two stub methods, resources and handler matching the signatures below:

    from import Service
    class VpcTagHandler(Service):
       def resources(self, session):
       def handler(self, resource, expected_tags, region, session, cache, proposals):
  4. Implement resources(...) to return an iterable. If using boto3 resources, this should look like:

      def resources(self, session):
        return session.resource('ec2').vpc.all()

    If using boto3 client, don't forget to implement pagination, and should look like:

      def resources(self, session):
        ec2 = session.client('ec2')
        paginator = ec2.get_paginator('describe_vpcs')
        for page in paginator.paginate():
          for vpc in page:
            yield vpc 
  5. Implement handle(...) to yield a payload describing the tag proposal (example is using boto3.resources):

      def handle(self, vpc, expected_tags, region, session, cache, proposals):
        # This boilerplate logic will handle checking the tags which have already been
        # evaluated for this user.
        evaluated_tags = self._progress.evaluated_tags(vpc.vpc_id)
        vpc_info, missing_tags = \
            self._build_tag_sets(expected_tags, evaluated_tags, vpc.tags)
        # Check if the user has proposed values for all the missing tags 
        if self._progress.has_finished(vpc.vpc_id, expected_tags):
            # Print a skip message
        if any(missing_tags):
          # Print information about this resource, which could be useful 
          # to provide context around tagging.
            ("VpcID", vpc.vpc_id),
          # Allow the user to skip auditing this resource       
          if self._user_skip():
          # Build our user prompt to ask for new tags
          tag_prompt = self._build_tag_prompt(missing_tags)
          for tag_key in missing_tags:
            # Yield a proposal for a new tag key/value pair for the given
            # resource id.
            yield {
              'resource_id': vpc.vpc_id,
              'tag_key': tag_key,
              'tag_value': tag_prompt(tag_key),
  6. Finally, add the entrypoint by extending

    from setuptools import setup
        'tag_a_day.tag_handlers': [
          'vpc = my_package.my_module:VPCTagHandler',

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for aws-tag-a-day, version 0.1.10
Filename, size File type Python version Upload date Hashes
Filename, size aws_tag_a_day-0.1.10-py3-none-any.whl (18.3 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size aws-tag-a-day-0.1.10.tar.gz (9.9 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page