diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7c26749 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,63 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# Dockerfile +[{Dockerfile,Dockerfile.template.erb,Dockerfile.sample}] +indent_style = space +indent_size = 4 + +# Batch Files +[*.{cmd,bat}] +end_of_line = crlf + +# Bash Files +[*.sh] +end_of_line = lf + +# tsv use tab to separate fields +[*.tsv] +indent_style = tab + +# Applies to all Markdown files +[*.{md,mdx}] +trim_trailing_whitespace = false + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# Web Files +[*.{htm,html,js,jsm,ts,tsx,cjs,cts,ctsx,mjs,mts,mtsx,css,sass,scss,less,pcss,svg,vue}] +indent_size = 2 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 +max_line_length = 79 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab + +# Indentation override for all JS under lib directory +[lib/**.js] +indent_style = space +indent_size = 2 + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..31e2660 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,65 @@ +default_language_version: + python: python3.9 +repos: + # General + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: detect-aws-credentials + args: [--allow-missing-credentials] + - id: detect-private-key + - id: check-added-large-files + - id: check-merge-conflict + - id: check-ast + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-json + - id: check-yaml + - id: check-toml + - id: check-symlinks + - id: check-xml + - id: destroyed-symlinks + - id: end-of-file-fixer + - id: check-byte-order-marker + - id: mixed-line-ending + - id: name-tests-test + - id: requirements-txt-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + - repo: https://github.com/zricethezav/gitleaks + rev: v8.18.1 + hooks: + - id: gitleaks + + # Python + - repo: https://github.com/psf/black # Can choose between black or autopep8 + rev: 24.1.1 + hooks: + - id: black + args: [-t, py39] + - repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py39-plus] + - repo: https://github.com/asottile/add-trailing-comma + rev: v3.1.0 + hooks: + - id: add-trailing-comma + - repo: https://github.com/asottile/reorder_python_imports + rev: v3.1.0 + hooks: + - id: reorder-python-imports + + # Terraform + - repo: https://github.com/terraform-docs/terraform-docs + rev: v0.17.0 + hooks: + - id: terraform-docs-go + args: + ["markdown", "table", "--output-file", "README.md", "."] + - repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.86.0 + hooks: + - id: terraform_fmt + args: [--args=-diff] diff --git a/README.md b/README.md index a924c39..baf4ca0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AWS Magic Tagging Resources -Use the EventBridge to trigger a Lambda function to tag resources in AWS. +This script is designed to automatically tag AWS resources when certain events occur. It is intended to be used as an AWS Lambda function, triggered by AWS EventBridge. ## Prerequisites @@ -31,6 +31,8 @@ resource_tags = { - IAM Policy - Log Group - EventBridge Rule +- Resource Group +- CloudWatch Dashboard ## How to use this @@ -62,9 +64,15 @@ Deploy this terraform and verify the resource tags are created. `sh multi-region-destroy.sh` +## Functionality + +1. **Extracting Tag Information**: The `get_tag_information` function extracts tag information from the event, including the source IP address, event time, and user agent. It also calls the `taggers.get_event_time` and `taggers.get_identity_type` functions to get additional tag information. + +2. **Adding Tags**: The `lambda_handler` function is the entry point for the Lambda function. It first calls the `get_tag_information` function to get the tag information, then decides which type of AWS resource to add tags to based on the source of the event. For example, if the source of the event is "aws.ec2", it calls the `ec2_tagger.tagger` function to add tags to EC2 resources. + ### Support auto-tagging resources - + - EC2 - ELB - RDS @@ -72,13 +80,68 @@ Deploy this terraform and verify the resource tags are created. - Lambda - SNS - IAM + - AutoScaling ### Default tags - - - Owner - - SourceIP - - UserType - - EventTime - - UserName / RoleName + - Owner + - SourceIP + - UserType + - EventTime + - UserName / RoleName + + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.14 | +| [aws](#requirement\_aws) | 4.22.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 4.22.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [lambda](#module\_lambda) | terraform-aws-modules/lambda/aws | 3.3.1 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_dashboard.dashboard](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/cloudwatch_dashboard) | resource | +| [aws_cloudwatch_event_rule.event_rule](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/cloudwatch_event_rule) | resource | +| [aws_cloudwatch_event_target.event_rule](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/cloudwatch_event_target) | resource | +| [aws_iam_policy.lambda_tagging_policy](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/iam_policy) | resource | +| [aws_iam_role.lambda_function_role](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.lambda_basic_policy](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.lambda_tagging_policy](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/iam_role_policy_attachment) | resource | +| [aws_lambda_permission.event_rule](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/lambda_permission) | resource | +| [aws_resourcegroups_group.resource_group](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/resources/resourcegroups_group) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/data-sources/caller_identity) | data source | +| [aws_iam_role.lambda_function_role](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/data-sources/iam_role) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/4.22.0/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_region](#input\_aws\_region) | The AWS region to use | `string` | `"us-east-1"` | no | +| [enable\_cloudwatch\_dashboard](#input\_enable\_cloudwatch\_dashboard) | Enable the CloudWatch Dashboard | `bool` | `false` | no | +| [lambda\_function\_name](#input\_lambda\_function\_name) | The name of the Lambda function | `string` | `"AWSAutoTaggingFunction"` | no | +| [lambda\_function\_role\_name](#input\_lambda\_function\_role\_name) | The name of the Lambda function role | `string` | `"AWSAutoTaggingFunctionRole"` | no | +| [resource\_tags](#input\_resource\_tags) | Tags to apply to resources | `map(string)` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [completed\_region](#output\_completed\_region) | The region that the Lambda function was created | + diff --git a/cw_dashboard.tf b/cw_dashboard.tf index ab925e3..1b3f759 100644 --- a/cw_dashboard.tf +++ b/cw_dashboard.tf @@ -1,10 +1,11 @@ locals { dashboard_query = <<-EOT - SOURCE '/aws/lambda/${var.lambda_function_name}' + SOURCE '/aws/lambda/${var.lambda_function_name}' | fields @timestamp, @message | filter @message not like 'START RequestId' | filter @message not like 'REPORT RequestId' | filter @message not like 'END RequestId' + | filter @message not like 'INIT_START' | sort @timestamp desc | limit 100 EOT diff --git a/eventbridge.tf b/eventbridge.tf index c2f2094..c243c4b 100644 --- a/eventbridge.tf +++ b/eventbridge.tf @@ -35,6 +35,11 @@ locals { service = "IAM" source = ["aws.iam"] event_name = ["CreateRole", "CreatePolicy"] + }, + { + service = "AutoScaling" + source = ["aws.autoscaling"] + event_name = ["CreateAutoScalingGroup"] } ] } diff --git a/handler/main.py b/handler/main.py index 36af67a..08f9a18 100644 --- a/handler/main.py +++ b/handler/main.py @@ -1,10 +1,11 @@ +import resource_tagger.autoscaling_tagger as asg_tagger +import resource_tagger.cloudfront_tagger as cf_tagger import resource_tagger.ec2_tagger as ec2_tagger import resource_tagger.elb_tagger as elb_tagger +import resource_tagger.iam_tagger as iam_tagger +import resource_tagger.lambda_tagger as lambda_tagger import resource_tagger.rds_tagger as rds_tagger -import resource_tagger.cloudfront_tagger as cf_tagger import resource_tagger.sns_tagger as sns_tagger -import resource_tagger.lambda_tagger as lambda_tagger -import resource_tagger.iam_tagger as iam_tagger import resource_tagger.taggers as taggers @@ -33,7 +34,7 @@ def lambda_handler(event, context): elif event["source"] == "aws.rds": response = rds_tagger.tagger(event, tags) - + elif event["source"] == "aws.cloudfront": response = cf_tagger.tagger(event, tags) @@ -46,10 +47,13 @@ def lambda_handler(event, context): elif event["source"] == "aws.iam": response = iam_tagger.tagger(event, tags) + elif event["source"] == "aws.autoscaling": + response = asg_tagger.tagger(event, tags) + else: response = "[LOG] No support source found!" else: response = "[LOG] No tags found!" - + print(response) return response diff --git a/handler/resource_tagger/autoscaling_tagger.py b/handler/resource_tagger/autoscaling_tagger.py new file mode 100644 index 0000000..387bf17 --- /dev/null +++ b/handler/resource_tagger/autoscaling_tagger.py @@ -0,0 +1,36 @@ +import boto3 + +from .taggers import changing_tag_to_array + + +# Create tags for AWS resources +def add_tags_in_resource(tags, resource): + asg_converted_tags = [] + converted_tags = changing_tag_to_array(tags) + + try: + for tag in converted_tags: + tag["ResourceId"] = resource + tag["ResourceType"] = "auto-scaling-group" + tag["PropagateAtLaunch"] = True + asg_converted_tags.append(tag) + client = boto3.client("autoscaling") + response = client.create_or_update_tags(Tags=asg_converted_tags) + except Exception as e: + response = {"[LOG] Error: ": str(e)} + + return response, converted_tags + + +def tagger(event, tags): + request_parameters = event["detail"]["requestParameters"] + autoscaling_group_name = request_parameters["autoScalingGroupName"] + + if autoscaling_group_name is not None: + response, converted_tags = add_tags_in_resource(tags, autoscaling_group_name) + response["autoscaling_group_name"] = autoscaling_group_name + response["converted_tags"] = converted_tags + return response + + else: + return "[LOG] No resource id found!" diff --git a/handler/resource_tagger/cloudfront_tagger.py b/handler/resource_tagger/cloudfront_tagger.py index fd58307..99e17ea 100644 --- a/handler/resource_tagger/cloudfront_tagger.py +++ b/handler/resource_tagger/cloudfront_tagger.py @@ -1,42 +1,43 @@ import boto3 -from .taggers import get_resource_arn + from .taggers import changing_tag_to_array +from .taggers import get_resource_arn # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("cloudfront") response = client.tag_resource( Resource=resource, - Tags={ - "Items": add_tags - } + Tags={"Items": converted_tags}, ) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def add_comment_in_cloudfront(tags, resource, response=None): - distribution_id = resource.split('/')[1] - client = boto3.client("cloudfront") + distribution_id = resource.split("/")[1] + client = boto3.client("cloudfront") distribution_config = client.get_distribution_config(Id=distribution_id) if distribution_config["DistributionConfig"]["Comment"] == "": - distribution_config["DistributionConfig"]["Comment"] = "Created by " + tags["Owner"] + distribution_config["DistributionConfig"]["Comment"] = ( + "Created by " + tags["Owner"] + ) response = client.update_distribution( - Id = distribution_id, - DistributionConfig = distribution_config["DistributionConfig"], + Id=distribution_id, + DistributionConfig=distribution_config["DistributionConfig"], IfMatch=distribution_config["ETag"], ) else: response = "[LOG] Distribution already has a comment!" print(response) - return + return def tagger(event, tags, resource_arn=None): @@ -50,9 +51,9 @@ def tagger(event, tags, resource_arn=None): if resource_arn != None: add_comment_in_cloudfront(tags, resource_arn) - response, tags = add_tags_in_resource(tags, resource_arn) + response, converted_tags = add_tags_in_resource(tags, resource_arn) response["resource_arn"] = resource_arn - response["tags"] = tags + response["converted_tags"] = converted_tags return response else: diff --git a/handler/resource_tagger/ec2_tagger.py b/handler/resource_tagger/ec2_tagger.py index 09cbb16..e07dfd5 100644 --- a/handler/resource_tagger/ec2_tagger.py +++ b/handler/resource_tagger/ec2_tagger.py @@ -1,43 +1,85 @@ import boto3 -from .taggers import get_resource_id + from .taggers import changing_tag_to_array +from .taggers import get_resource_id + + +# Get EBS VolumeIds +def get_ebs_volume_ids(instance_id): + volume_ids = [] + client = boto3.client("ec2") + response = client.describe_instances(InstanceIds=[instance_id]) + for instance in response["Reservations"][0]["Instances"]: + for block_device in instance["BlockDeviceMappings"]: + volume_ids.append(block_device["Ebs"]["VolumeId"]) + return volume_ids + + +# Get AMI SnapshotIds +def get_ami_snapshot_id(ami_id): + snapshot_ids = [] + client = boto3.client("ec2") + response = client.describe_images(ImageIds=[ami_id]) + for ebs_mapping in response["Images"][0]["BlockDeviceMappings"]: + snapshot_ids.append(ebs_mapping["Ebs"]["SnapshotId"]) + return snapshot_ids # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("ec2") - response = client.create_tags( - Resources=[resource], - Tags=add_tags - ) + response = client.create_tags(Resources=[resource], Tags=converted_tags) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def tagger(event, tags, resource_id=None): + event_name = event["detail"]["eventName"] response_elements = event["detail"]["responseElements"] - if event["detail"]["eventName"] == "RunInstances": + if event_name == "RunInstances": resource_id = response_elements["instancesSet"]["items"][0]["instanceId"] - elif event["detail"]["eventName"] == "CreateManagedPrefixList": - resource_id = response_elements["CreateManagedPrefixListResponse"]["prefixList"]["prefixListId"] + elif event_name == "CreateManagedPrefixList": + resource_id = response_elements["CreateManagedPrefixListResponse"][ + "prefixList" + ]["prefixListId"] - elif event["detail"]["eventName"] == "CreateNatGateway": - resource_id = response_elements["CreateNatGatewayResponse"]["natGateway"]["natGatewayId"] + elif event_name == "CreateNatGateway": + resource_id = response_elements["CreateNatGatewayResponse"]["natGateway"][ + "natGatewayId" + ] else: resource_id = get_resource_id(response_elements) - if resource_id != None: - response, tags = add_tags_in_resource(tags, resource_id) + if event_name == "RunInstances" and resource_id is not None: + response, converted_tags = add_tags_in_resource(tags, resource_id) + volume_ids = get_ebs_volume_ids(resource_id) + for volume_id in volume_ids: + add_tags_in_resource(tags, volume_id) + response["resource_id"] = resource_id + response["converted_tags"] = converted_tags + return response + + elif event_name == "CreateImage" and resource_id is not None: + response, converted_tags = add_tags_in_resource(tags, resource_id) + snapshot_ids = get_ami_snapshot_id(resource_id) + for snapshot_id in snapshot_ids: + add_tags_in_resource(tags, snapshot_id) + response["resource_id"] = resource_id + response["converted_tags"] = converted_tags + return response + + elif resource_id is not None: + response, converted_tags = add_tags_in_resource(tags, resource_id) response["resource_id"] = resource_id - response["tags"] = tags + response["converted_tags"] = converted_tags return response else: diff --git a/handler/resource_tagger/elb_tagger.py b/handler/resource_tagger/elb_tagger.py index 0afa027..fcaed7a 100644 --- a/handler/resource_tagger/elb_tagger.py +++ b/handler/resource_tagger/elb_tagger.py @@ -1,22 +1,20 @@ import boto3 -from .taggers import get_resource_arn + from .taggers import changing_tag_to_array +from .taggers import get_resource_arn # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("elbv2") - response = client.add_tags( - ResourceArns=[resource], - Tags=add_tags - ) + response = client.add_tags(ResourceArns=[resource], Tags=converted_tags) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def tagger(event, tags, resource_arn=None): @@ -29,9 +27,9 @@ def tagger(event, tags, resource_arn=None): resource_arn = get_resource_arn(response_elements) if resource_arn != None: - response, tags = add_tags_in_resource(tags, resource_arn) + response, converted_tags = add_tags_in_resource(tags, resource_arn) response["resource_arn"] = resource_arn - response["tags"] = tags + response["converted_tags"] = converted_tags return response else: diff --git a/handler/resource_tagger/iam_tagger.py b/handler/resource_tagger/iam_tagger.py index 9e59705..1b97ade 100644 --- a/handler/resource_tagger/iam_tagger.py +++ b/handler/resource_tagger/iam_tagger.py @@ -1,35 +1,30 @@ import boto3 -from .taggers import get_resource_arn + from .taggers import changing_tag_to_array +from .taggers import get_resource_arn # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("iam") - response = client.tag_policy( - PolicyArn=resource, - Tags=add_tags - ) + response = client.tag_policy(PolicyArn=resource, Tags=converted_tags) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def add_tags_in_role(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("iam") - response = client.tag_role( - RoleName=resource, - Tags=add_tags - ) + response = client.tag_role(RoleName=resource, Tags=converted_tags) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def tagger(event, tags, response=None): @@ -37,16 +32,16 @@ def tagger(event, tags, response=None): if event["detail"]["eventName"] == "CreateRole": resource_name = response_elements["role"]["roleName"] - response, tags = add_tags_in_role(tags, resource_name) + response, converted_tags = add_tags_in_role(tags, resource_name) response["resource_name"] = resource_name - + elif event["detail"]["eventName"] == "CreatePolicy": resource_arn = get_resource_arn(response_elements) - response, tags = add_tags_in_resource(tags, resource_arn) + response, converted_tags = add_tags_in_resource(tags, resource_arn) response["resource_arn"] = resource_arn - + else: return "[LOG] No resource arn found!" - response["tags"] = tags + response["converted_tags"] = converted_tags return response diff --git a/handler/resource_tagger/rds_tagger.py b/handler/resource_tagger/rds_tagger.py index 1191214..365a7f6 100644 --- a/handler/resource_tagger/rds_tagger.py +++ b/handler/resource_tagger/rds_tagger.py @@ -1,22 +1,23 @@ import boto3 -from .taggers import get_resource_arn + from .taggers import changing_tag_to_array +from .taggers import get_resource_arn # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("rds") response = client.add_tags_to_resource( ResourceName=resource, - Tags=add_tags + Tags=converted_tags, ) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def tagger(event, tags, resource_arn=None): @@ -29,9 +30,9 @@ def tagger(event, tags, resource_arn=None): resource_arn = get_resource_arn(response_elements) if resource_arn != None: - response, tags = add_tags_in_resource(tags, resource_arn) + response, converted_tags = add_tags_in_resource(tags, resource_arn) response["resource_arn"] = resource_arn - response["tags"] = tags + response["converted_tags"] = converted_tags return response else: diff --git a/handler/resource_tagger/sns_tagger.py b/handler/resource_tagger/sns_tagger.py index 6b32abb..aa75a44 100644 --- a/handler/resource_tagger/sns_tagger.py +++ b/handler/resource_tagger/sns_tagger.py @@ -1,22 +1,20 @@ import boto3 -from .taggers import get_resource_arn + from .taggers import changing_tag_to_array +from .taggers import get_resource_arn # Create tags for AWS resources def add_tags_in_resource(tags, resource): - add_tags = changing_tag_to_array(tags) + converted_tags = changing_tag_to_array(tags) try: client = boto3.client("sns") - response = client.tag_resource( - ResourceArn=resource, - Tags=add_tags - ) + response = client.tag_resource(ResourceArn=resource, Tags=converted_tags) except Exception as e: response = {"[LOG] Error: ": str(e)} - return response, add_tags + return response, converted_tags def tagger(event, tags, resource_arn=None): @@ -29,9 +27,9 @@ def tagger(event, tags, resource_arn=None): resource_arn = get_resource_arn(response_elements) if resource_arn != None: - response, tags = add_tags_in_resource(tags, resource_arn) + response, converted_tags = add_tags_in_resource(tags, resource_arn) response["resource_arn"] = resource_arn - response["tags"] = tags + response["converted_tags"] = converted_tags return response else: diff --git a/handler/resource_tagger/taggers.py b/handler/resource_tagger/taggers.py index c0f51ff..dca73bd 100644 --- a/handler/resource_tagger/taggers.py +++ b/handler/resource_tagger/taggers.py @@ -1,5 +1,5 @@ -import re import datetime +import re def get_identity_type(event, tags): @@ -7,7 +7,9 @@ def get_identity_type(event, tags): if tags["UserType"] == "AssumedRole": tags["Owner"] = event["detail"]["userIdentity"]["principalId"].split(":")[1] - tags["RoleName"] = event["detail"]["userIdentity"]["sessionContext"]["sessionIssuer"]["userName"] + tags["RoleName"] = event["detail"]["userIdentity"]["sessionContext"][ + "sessionIssuer" + ]["userName"] elif tags["UserType"] == "IAMUser": tags["Owner"] = event["detail"]["userIdentity"]["userName"] @@ -23,9 +25,14 @@ def get_identity_type(event, tags): # Get resource event time and convert to UTC timezone def get_event_time(event, tags, utc_time=0): - event_time = datetime.datetime.strptime(event["detail"]["eventTime"], "%Y-%m-%dT%H:%M:%SZ") + event_time = datetime.datetime.strptime( + event["detail"]["eventTime"], + "%Y-%m-%dT%H:%M:%SZ", + ) event_time = event_time + datetime.timedelta(hours=utc_time) - event_time = event_time.replace(tzinfo=datetime.timezone(datetime.timedelta(hours=utc_time))) + event_time = event_time.replace( + tzinfo=datetime.timezone(datetime.timedelta(hours=utc_time)), + ) tags["EventTime"] = event_time.strftime("%Y-%m-%dT%H:%M:%S%z") return tags @@ -62,14 +69,20 @@ def response_elements_data_processing(response_elements, regular_expression): # Get resource id from event def get_resource_id(response_elements): regular_expression = "[a-z]*?-.*" - resource_id = response_elements_data_processing(response_elements, regular_expression) + resource_id = response_elements_data_processing( + response_elements, + regular_expression, + ) return resource_id # Get resource arn from event def get_resource_arn(response_elements): - regular_expression = "arn\:aws\:.*" - resource_arn = response_elements_data_processing(response_elements, regular_expression) + regular_expression = r"arn\:aws\:.*" + resource_arn = response_elements_data_processing( + response_elements, + regular_expression, + ) return resource_arn @@ -78,4 +91,4 @@ def changing_tag_to_array(tags): tags_array = [] for key, value in tags.items(): tags_array.append({"Key": key, "Value": value}) - return tags_array + return tags_array diff --git a/iam.tf b/iam.tf index e3fdbfc..b1e8dd8 100644 --- a/iam.tf +++ b/iam.tf @@ -25,7 +25,7 @@ resource "aws_iam_role" "lambda_function_role" { ) } -resource "aws_iam_role_policy_attachment" "lambda_basic_permission" { +resource "aws_iam_role_policy_attachment" "lambda_basic_policy" { count = terraform.workspace == "default" ? 1 : 0 role = aws_iam_role.lambda_function_role[count.index].name policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" @@ -51,6 +51,8 @@ resource "aws_iam_policy" "lambda_tagging_policy" { "Effect" : "Allow", "Action" : [ "ec2:*Tag*", + "ec2:DescribeImages", + "ec2:DescribeInstances", "elasticloadbalancing:*Tag*", "rds:*Tag*", "cloudfront:*Tag*", @@ -59,6 +61,7 @@ resource "aws_iam_policy" "lambda_tagging_policy" { "sns:*Tag*", "lambda:*Tag*", "iam:*Tag*", + "autoscaling:*Tag*", ], "Resource" : "*" } diff --git a/provider.tf b/provider.tf index b5e4633..424b1bc 100644 --- a/provider.tf +++ b/provider.tf @@ -17,5 +17,6 @@ provider "aws" { } output "completed_region" { - value = data.aws_region.current.name + value = data.aws_region.current.name + description = "The region that the Lambda function was created" } diff --git a/terraform.tfvars.template b/terraform.tfvars.template index 146f5c4..522b104 100644 --- a/terraform.tfvars.template +++ b/terraform.tfvars.template @@ -7,5 +7,5 @@ enable_cloudwatch_dashboard = false resource_tags = { terraform = "true" project = "aws-magic-tagging-resources" - version = "v1.6.0" + version = "v1.7.0" }