AWS IAM Permissions by Recommendation
This article details the AWS permissions required for each recommendation.
EC2
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| EC2 Idle | ce:GetRightsizingRecommendation | Fetch AWS-generated TERMINATE recommendations |
| EC2 Idle | ec2:DescribeInstances | List all instances to verify state |
| EC2 Idle | cloudwatch:GetMetricStatistics | CPUUtilization, NetworkIn, NetworkOut per instance (AWS/EC2) |
| EC2 Right Sizing | ce:GetRightsizingRecommendation | Fetch AWS-generated MODIFY recommendations |
| EC2 Right Sizing | ec2:DescribeInstances | List all instances + launch/attach times |
| EC2 Right Sizing | cloudwatch:GetMetricStatistics | CPUUtilization (max+avg), NetworkIn, NetworkOut, mem_used_percent (AWS/EC2 + CWAgent namespace) |
| EC2 Right Sizing | ec2:DescribeInstanceTypes | Windows only - get memory size in MiB to convert MB-remaining to % |
| EC2 Stopped Instances | ec2:DescribeInstances | List all instances + filter stopped |
| EC2 Stopped Instances | ec2:DescribeVolumes | List attached EBS volumes to cost them |
| EC2 Stopped Instances | ec2:DescribeInstances | Verify instance still exists / state (completion) |
IP / Network
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| IP Unattached | ec2:DescribeAddresses | Get EIP allocation details per region |
| IP Unattached | ec2:DescribeNatGateways | Check if IP is attached to NAT gateway |
| NAT Gateway Idle | ec2:DescribeNatGateways | List all NAT gateways |
| NAT Gateway Idle | cloudwatch:GetMetricStatistics | ActiveConnectionCount (AWS/NATGateway) |
| NAT Gateway Idle | ec2:DescribeNatGateways | Verify NAT gateway still exists |
| VPC Endpoint Idle | ec2:DescribeVpcEndpoints | Get service name / VPC ID / creation time |
EBS / Snapshots
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| EBS Unattached | ec2:DescribeVolumes | List all EBS volumes + attachment state |
| EBS Unattached | ec2:DescribeVolumes | Verify volume still exists (completion) |
| EBS Type Change | ec2:DescribeVolumes | List volumes to find gp2/io1 candidates |
| EBS Type Change | cloudwatch:GetMetricStatistics | VolumeRead Ops, VolumeWriteOps, ReadBytes, WriteBytes (AWS/EBS) |
| EBS Outdated Snapshot | ec2:DescribeSnapshots | List own snapshots + creation time |
| EBS Outdated Snapshot | ec2:DescribeImages | Exclude snapshots backing AMIs |
| EBS Outdated Snapshot | ec2:DescribeSnapshots | Verify snapshot still exists (completion) |
| AMI Orphaned Snapshot | ec2:DescribeSnapshots | List snapshots tagged as created by AMI |
| AMI Orphaned Snapshot | ec2:DescribeImages | Find deregistered AMIs whose snapshots are orphaned |
| AMI Orphaned Snapshot | ec2:DescribeVolumes | Exclude snapshots backing existing volumes |
| AMI Orphaned Snapshot | ec2:DescribeSnapshots | Verify snapshot still exists (completion) |
| AWS Backup Outdated Snapshot | ec2:DescribeSnapshots | List snapshots created by AWS Backup |
| AWS Backup Outdated Snapshot | ec2:DescribeSnapshots | Verify snapshot still exists (completion) |
Load Balancer
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| Load Balancer Idle | elasticloadbalancing:DescribeLoadBalancers | List all ALBs/NLBs |
| Load Balancer Idle | elasticloadbalancing:DescribeTargetGroups | List target groups |
| Load Balancer Idle | elasticloadbalancing:DescribeTargetHealth | Check if target groups have registered targets |
| Load Balancer Idle | cloudwatch:GetMetricStatistics | Consumed LCUs (AWS/ApplicationELB) - confirm zero traffic |
| Load Balancer Idle | elasticloadbalancing:DescribeLoadBalancers | Verify LB still exists (completion) |
RDS
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| RDS Idle | rds:DescribeDBInstances | List all RDS instances |
| RDS Idle | cloudwatch:GetMetricStatistics | Database Connections (AWS/RDS) |
| RDS Idle | rds:DescribeDBInstances | Verify instance still exists (completion) |
| RDS Generation Upgrade | rds:DescribeDBInstances | List io1 instances |
| RDS Generation Upgrade | cloudwatch:GetMetricStatistics | ReadIOPS, WriteIOPS (AWS/RDS) |
| RDS Right Sizing | rds:DescribeDBInstances | List instances for rightsizing |
| RDS Right Sizing | cloudwatch:GetMetricStatistics | CPU, Freeable Memory, etc. (AWS/RDS) |
| RDS Right Sizing | rds:DescribeDBClusters | Determine cluster write/read role |
| RDS Provisioned IOPS | rds:DescribeDBInstances | List instances |
| RDS Provisioned IOPS | cloudwatch:GetMetricStatistics | ReadIOPS, WriteIOPS (AWS/RDS) |
| RDS Aurora I/O Optimized | rds:DescribeDBClusters | List Aurora clusters for io-optimized analysis |
| RDS Storage Type Change | rds:DescribeDBInstances | List instances |
| RDS Storage Type Change | cloudwatch:GetMetricStatistics | Read IOPS, Write IOPS (AWS/RDS) |
| RDS Generation Upgrade | rds:DescribeDBInstances | List instances for engine version check |
| RDS Reserved Instance | rds:DescribeDBInstances | List running instances for RI recommendations |
| RDS Extended Support | rds:DescribeDBInstances | List instances vs EOL calendar |
DynamoDB / ElastiCache / Redshift / OpenSearch / DocDB / Kinesis / Neptune
| Recommendation | AWS Permission | CloudWatch Metric |
|---|---|---|
| Dynamo DB Idle | dynamodb:ListTables | ConsumedWriteCapacityUnits, ConsumedReadCapacityUnits (AWS/DynamoDB) |
| Dynamo DB Idle | dynamodb:DescribeTable | Verify table still exists (completion) |
| ElastiCache Idle | elasticache:DescribeCacheClusters | CurrConnections (AWS/ElastiCache) |
| Redshift Idle | redshift:DescribeClusters | DatabaseConnections (AWS/Redshift) |
| Redshift Reserved Instance | redshift:DescribeClusters | (no CloudWatch — DB only) |
| Elasticsearch Idle | es:ListDomainNames | IndexingRate, SearchRate (AWS/ES) |
| Elasticsearch Idle | es:DescribeElasticsearchDomains | |
| OpenSearch Reserved Instance | opensearch:ListDomainNames | |
| OpenSearch Reserved Instance | opensearch:DescribeDomains | |
| OpenSearch Extended Support | opensearch:ListDomainNames | |
| OpenSearch Extended Support | opensearch:DescribeDomains | |
| OpenSearch Extended Support | opensearch:GetCompatibleVersions | |
| DocumentDB Idle | rds:DescribeDBClusters (docdb) | DatabaseConnections (AWS/DocDB) |
| DocumentDB Extended Support | rds:DescribeDBClusters (docdb) | (no CloudWatch) |
| Kinesis Idle | kinesis:ListStreams | PutRecord.Bytes, PutRecords.Bytes (AWS/Kinesis) |
| Kinesis Idle | kinesis:DescribeStream | |
| Neptune DB Idle | rds:DescribeDBClusters (neptune) | GremlinRequestsPerSec, SparqlRequestsPerSec (AWS/Neptune) |
| ElastiCache Reserved Instance | elasticache:DescribeCacheClusters | (no CloudWatch) |
| ElastiCache Extended Support | elasticache:DescribeCacheClusters | (no CloudWatch) |
S3
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| S3 Inactive | s3:ListBuckets | Get bucket creation dates |
| S3 Storage Class | s3:ListBuckets | Get bucket creation dates |
| S3 Storage Class | s3:GetBucketVersioning | Check if versioning enabled |
| S3 Storage Class | s3:GetBucketLifecycleConfiguration | Check existing lifecycle rules |
| S3 Storage Class | cloudwatch:GetMetricStatistics | NumberOfObjects (AWS/S3) |
| S3 Storage Class | cloudwatch:GetMetricStatistics | NonCurrentVersionStorageBytes, NonCurrentVersionObjectCount (AWS/S3/Storage-Lens) |
| S3 Storage Class | cloudwatch:ListMetrics | Discover Storage Lens dimensions for bucket |
| S3 Versioning | (same as S3 Storage Class) | (no CloudWatch) |
| S3 Multipart upload | s3:ListBuckets | Get bucket creation dates |
| S3 Multipart upload | s3:ListMultipartUploads | Enumerate incomplete multipart uploads |
| S3 Multipart upload | s3:ListParts | Size each part to calculate wasted storage cost |
ECS / EKS / K8S
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| ECS Fargate Right-sizing | compute-optimizer:GetECSServiceRecommendations | Get AWS Compute Optimizer Fargate rightsizing data |
| EKS Extended Support | eks:ListClusters | Get cluster version to compare against EKS EOL calendar |
| EKS Extended Support | eks:DescribeCluster | |
| K8s Workload Rightsizing | (inherits AWS base, K8s source) | K8s metrics-server / Prometheus, not AWS APIs |
CloudTrail / CloudWatch / KMS / Secrets Manager / Bedrock
| Recommendation | AWS Permission | Purpose |
|---|---|---|
| Duplicate CloudTrail | cloudtrail:DescribeTrails | List all trails per region to detect duplicates |
| Disabled KMS | kms:ListKeys | Find disabled customer-managed keys |
| Disabled KMS | kms:DescribeKey | |
| Old KMS | kms:ListKeys | Find keys not rotated within threshold |
| Old KMS | kms:DescribeKey | |
| Old KMS | kms:ListKeyRotations | |
| Old KMS | kms:DescribeKey | Verify key still exists (completion) |
| Unused Secrets | secretsmanager:ListSecrets | Find secrets not accessed within threshold |
| Unused Secrets | secretsmanager:DescribeSecret | Verify secret still exists (completion) |
| Bedrock Provisioned Throughput Commitment | bedrock:ListProvisionedModelThroughputs | Find provisioned throughput allocations |
Updated about 12 hours ago
