This tool lists various AWS resources across specified regions, validates their tags against a defined policy, optionally suggests fixes using AI, and allows applying those suggestions.
- Go: Ensure you have Go installed (version 1.18 or later recommended).
- AWS Credentials: Configure your AWS credentials. The tool uses the standard AWS SDK credential chain (environment variables
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN, shared credential file~/.aws/credentials, or IAM role attached to the execution environment). - AI API (Optional): If using AI recommendations (
-ai-modelflag), you need access to a compatible AI API endpoint and an API token.
Navigate to the project's root directory and run:
go build -o aws-tag-analyzer ./cmd/main.goThis will create an executable named aws-tag-analyzer (or aws-tag-analyzer.exe on Windows).
You can optionally create a .env file in the same directory as the executable to store configuration. Environment variables always take precedence over the .env file.
# Optional: Default AWS region if not specified via -region flag
AWS_REGION=eu-west-1
# Optional: AWS Credentials (Alternatively use standard AWS credential chain)
# AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
# AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
# AWS_SESSION_TOKEN=YOUR_SESSION_TOKEN # If using temporary credentials
# Required for AI Recommendations (-ai-model flag)
AI_API_URL=https://your-ai-api.example.com/v1/chat/completions
AI_API_TOKEN=YOUR_AI_API_BEARER_TOKENThe tool has two main commands: analyze and apply.
Lists resources, validates tags, and optionally generates AI recommendations.
./aws-tag-analyzer [analyze] [flags](Note: analyze is the default command if none is specified)
Flags:
-log-level: Set log level (trace, debug, info, warn, error, fatal, panic). Default:info. Logs are written to stderr.-region: Comma-separated list of AWS regions to scan (e.g.,us-east-1,eu-west-1). OverridesAWS_REGIONfrom config/env. Required ifAWS_REGIONis not set and-input-jsonis not used.-policy: Path to the tag policy JSON file (required for validation).-lowercase: Convert resource kind, name, region, and all tag keys/values to lowercase in the output.-ai-model: Enable AI recommendations using the specified model name (e.g.,'deepseek-r1:1.5b'). If this flag is provided with a non-empty value, AI recommendations are enabled. RequiresAI_API_URLandAI_API_TOKENenvironment variables to be set. If omitted or empty, AI recommendations are disabled.-ai-timeout: Timeout for AI API requests (e.g.,30s,1m). Default:20s. Only relevant if-ai-modelis specified.-input-json: Path to a JSON file containing pre-fetched resource data (output from a previousanalyzerun). Skips AWS fetching and uses the file data instead.- If
-policyis also provided, the tags in the JSON file will be re-validated against the specified policy, overwriting anyissuespresent in the input file. - If
-policyis omitted, any existingissuesarrays in the input JSON file will be cleared before potentially adding new AI recommendations (if-ai-modelis used). Useful for generating AI recommendations without re-running validation.
- If
Examples:
-
Analyze resources in
eu-west-1and validate againstpolicy.json(no AI):./aws-tag-analyzer -region eu-west-1 -policy ./policy.json > resources.json -
Analyze resources, validate, and get AI recommendations using a specific model:
./aws-tag-analyzer -region eu-west-1,eu-west-2 -policy ./policy.json -ai-model "deepseek-r1:1.5b" > resources_with_ai.json
-
Re-run validation and AI on previously fetched data using a new policy:
./aws-tag-analyzer -input-json ./resources.json -policy ./new_policy.json -ai-model "qwen2.5-coder:32b" > resources_revalidated.json
-
Add AI recommendations to previously fetched data without re-validating:
# Note: Omitting -policy here clears existing issues from resources.json first ./aws-tag-analyzer -input-json ./resources.json -ai-model "qwen2.5-coder:32b" > resources_with_ai_only.json
Reads a JSON output file (generated by the analyze command with recommendations) and interactively prompts the user to apply the suggested tag changes to the actual AWS resources.
./aws-tag-analyzer apply -input <input_json_file> [flags]Flags:
-input: Path to the JSON file containing resources and recommendations (required).-kind: Comma-separated list of resource kinds to apply changes to (e.g.,ec2,s3,vpc). If omitted, applies to all kinds in the input file.-log-level: Set log level. Default:info.
Example:
# Apply all recommendations from the file
./aws-tag-analyzer apply -input ./resources_with_ai.json
# Apply only recommendations for EC2 instances and S3 buckets
./aws-tag-analyzer apply -input ./resources_with_ai.json -kind ec2,s3The command will iterate through each resource and issue with a recommendation in the input file (respecting the -kind filter if provided). For each recommendation, it will display:
- The resource Kind, Identifier (ID/ARN), and Region.
- The resource's "Name" tag, if present.
- All existing tags on the resource.
- The specific tag validation issue found.
- The current value of the tag targeted by the recommendation (or indicate if it's missing).
- The suggested change(s) from the AI model(s).
If multiple AI models provided recommendations for the same issue, you will be asked to choose which one to apply by entering its number, or 'e' to select one to edit.
Finally, it will ask for confirmation (y/N/e[dit]).
y: Applies the suggested (or chosen) change.N(or any other key except 'y' or 'e'): Skips the change for this issue.e: Prompts you to enter a new value for the tag before applying the change.
If confirmed ('y' or after editing with 'e'), it will attempt to apply the tag change using the AWS SDK.
Warning: The apply command makes real changes to your AWS resources. Use with caution and ensure your credentials have the necessary permissions (e.g., ec2:CreateTags, elasticloadbalancing:AddTags, ecs:TagResource, s3:PutBucketTagging, s3:GetBucketTagging).
The policy file defines the tagging rules. It's a JSON array of rule objects.
[
{
"key": "environment", // Tag key (case-sensitive unless -lowercase is used)
"mandatory": true, // Is this tag required?
"value": ["production", "staging", "dev", "test", "uat", "core"], // Optional: List of allowed values
"status": "active" // Rule status ("active" or "inactive")
},
{
"key": "owner",
"mandatory": true,
"status": "active" // No value restriction means any value is allowed if present
},
{
"key": "system",
"mandatory": false, // Optional tag (considered "desirable" if no value restriction)
"status": "active"
},
{
"key": "project-code",
"mandatory": false,
"value": ["p100", "p200"], // Optional tag with specific allowed values
"status": "active"
}
// ... more rules
]key: The tag key name.mandatory:trueif the tag must exist,falseotherwise.value: An optional array of allowed string values for the tag. If omitted or empty, any value is permitted if the tag exists.status: Set to"active"for the rule to be enforced,"inactive"to ignore it.
The analyze command outputs a JSON array to standard output. Each object in the array represents an AWS resource.
[
{
"kind": "ec2", // Type of resource (e.g., ec2, ebs, vpc, s3, elbv2)
"name": "i-0123456789abcdef0", // Resource identifier (Instance ID, ARN, Bucket Name, etc.)
"region": "eu-west-1", // AWS region
"tags": { // Map of existing tags
"Name": "my-instance",
"environment": "production"
},
"issues": [ // Optional: Array of validation issues found
{
"issue_type": "MissingMandatory", // Type of issue (MissingMandatory, InvalidValue, MissingDesirable)
"tag_key": "owner", // Tag key related to the issue
// "tag_value": "...", // Included for InvalidValue issues
// "allowed_values": ["..."], // Included for InvalidValue issues
"recommendation": { // Optional: Map of AI model names to suggested fixes
"qwen2.5-coder:32b": "add:tag(owner=platform)"
}
}
]
}
// ... more resources
]