UPD: Updated inline documentation
This commit is contained in:
parent
f41bba3cd4
commit
50cbe202fa
@ -59,7 +59,8 @@ regions = getAllRegions(client)
|
|||||||
print("AWS Environment Review - " + str(date.today()) + "\n\n")
|
print("AWS Environment Review - " + str(date.today()) + "\n\n")
|
||||||
|
|
||||||
printTitle("Ec2 service review")
|
printTitle("Ec2 service review")
|
||||||
printSubTitle("[Cost Optimization] Instances stopped for over 14 days - Consider backing up and terminate instances")
|
printSubTitle("[Cost Optimization] Instances stopped for over 14 days - Consider backing up and terminate instances "
|
||||||
|
"or use AutoScalingGroup to spin up and down instances as needed.")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -71,7 +72,8 @@ for r in regions:
|
|||||||
outTable.append([r, aid, i[0].get("InstanceId"), getAgeFromDate(i[0].get("UsageOperationUpdateTime"))])
|
outTable.append([r, aid, i[0].get("InstanceId"), getAgeFromDate(i[0].get("UsageOperationUpdateTime"))])
|
||||||
printResult(outTable, "Region, AccountID, InstanceId, DaysStopped")
|
printResult(outTable, "Region, AccountID, InstanceId, DaysStopped")
|
||||||
|
|
||||||
printSubTitle("[Security] IDMSv1 allowed - Consider requiring IDMSv2")
|
printSubTitle("[Security] Insecure IDMSv1 allowed - Consider requiring IDMSv2. For more information, "
|
||||||
|
"see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -83,7 +85,8 @@ for r in regions:
|
|||||||
outTable.append([r, aid, i[0].get("InstanceId"), i[0].get("MetadataOptions").get("HttpTokens") ])
|
outTable.append([r, aid, i[0].get("InstanceId"), i[0].get("MetadataOptions").get("HttpTokens") ])
|
||||||
printResult(outTable, "Region, AccountID, InstanceId, IDMSv2")
|
printResult(outTable, "Region, AccountID, InstanceId, IDMSv2")
|
||||||
|
|
||||||
printSubTitle("[Performance Efficiency] Use of previous generation instance type - Consider using current generation instances")
|
printSubTitle("[Performance Efficiency] Use of previous generation instance type - "
|
||||||
|
"Consider using current generation instances")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('ec2', region_name=r)
|
client = boto3.client('ec2', region_name=r)
|
||||||
@ -94,7 +97,7 @@ for r in regions:
|
|||||||
outTable.append([r, aid, i[0].get("InstanceId"), i[0].get("InstanceType")])
|
outTable.append([r, aid, i[0].get("InstanceId"), i[0].get("InstanceType")])
|
||||||
printResult(outTable, "Region, AccountID, InstanceId, InstanceType")
|
printResult(outTable, "Region, AccountID, InstanceId, InstanceType")
|
||||||
|
|
||||||
printSubTitle("[Cost Optimization] Unattached EBS volumes - Consider taking snapshot and delete volumes")
|
printSubTitle("[Cost Optimization] Unattached EBS volumes - Consider backing up the volumes and delete them")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('ec2', region_name=r)
|
client = boto3.client('ec2', region_name=r)
|
||||||
@ -110,7 +113,8 @@ for r in regions:
|
|||||||
outTable.append([r, aid, i.get("VolumeId"), i.get("Size"), i.get("VolumeType")])
|
outTable.append([r, aid, i.get("VolumeId"), i.get("Size"), i.get("VolumeType")])
|
||||||
printResult(outTable, "Region, AccountID, VolumeId, Size, VolumeType")
|
printResult(outTable, "Region, AccountID, VolumeId, Size, VolumeType")
|
||||||
|
|
||||||
printSubTitle("[Cost Optimization] EBS snapshots more than 365 days old - Consider removing snapshots if no longer needed")
|
printSubTitle("[Cost Optimization] EBS snapshots more than 365 days old - "
|
||||||
|
"Consider removing snapshots if no longer needed")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('ec2', region_name=r)
|
client = boto3.client('ec2', region_name=r)
|
||||||
@ -123,7 +127,11 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, SnapshotId, Description, SnapshotAge")
|
printResult(outTable, "Region, AccountID, SnapshotId, Description, SnapshotAge")
|
||||||
|
|
||||||
|
|
||||||
printSubTitle("[Security] Unencrypted EBS volumes - Consider replacing volume with encrypted ones")
|
printSubTitle("[Security] Unencrypted EBS volumes - Consider replacing volume with encrypted ones. "
|
||||||
|
"One can do so by stopping the Ec2 instance, creating snapshot for the unencrypted volume, "
|
||||||
|
"copy the snapshot to a new encrypted snapshot, create a volume from the encrypted snapshot,"
|
||||||
|
"detach the original volume and attach the encrypted volume. Remember to clean up the volumes"
|
||||||
|
"and snapshots afterwards.")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('ec2', region_name=r)
|
client = boto3.client('ec2', region_name=r)
|
||||||
@ -156,7 +164,8 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, PublicIp")
|
printResult(outTable, "Region, AccountID, PublicIp")
|
||||||
|
|
||||||
printTitle("Security group review")
|
printTitle("Security group review")
|
||||||
printSubTitle("[Security] Security group allowing ingress from 0.0.0.0/0 - Consider setting more restrictive sg rules")
|
printSubTitle("[Security] Security group allowing ingress from 0.0.0.0/0 - Consider setting more restrictive rules "
|
||||||
|
"allowing access from specific sources.")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -182,7 +191,8 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, SecurityGroup, Rule, FromPort, ToPort")
|
printResult(outTable, "Region, AccountID, SecurityGroup, Rule, FromPort, ToPort")
|
||||||
|
|
||||||
printTitle("Rds service review")
|
printTitle("Rds service review")
|
||||||
printSubTitle("[Security] Unencrypted RDS instances - Consider encrypting RDS instances")
|
printSubTitle("[Security] Unencrypted RDS instances - Consider encrypting RDS instances. For more detail, see "
|
||||||
|
"https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/encrypt-an-existing-amazon-rds-for-postgresql-db-instance.html")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('rds', region_name=r)
|
client = boto3.client('rds', region_name=r)
|
||||||
@ -197,7 +207,8 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, DBIdentifier, Engine")
|
printResult(outTable, "Region, AccountID, DBIdentifier, Engine")
|
||||||
|
|
||||||
|
|
||||||
printSubTitle("[Reliability] Single AZ RDS instance - Consider enabling multi-az for production")
|
printSubTitle("[Reliability] RDS instance running in single availability zone - "
|
||||||
|
"Consider enabling multi-az for production use.")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('rds', region_name=r)
|
client = boto3.client('rds', region_name=r)
|
||||||
@ -213,7 +224,8 @@ printResult(outTable, "Region, AccountID, DBIdentifier, Engine")
|
|||||||
|
|
||||||
|
|
||||||
printTitle("Lambda service review")
|
printTitle("Lambda service review")
|
||||||
printSubTitle("[Security] Outdated Lambda runtime - Consider changing to currently supported Lambda runtime")
|
printSubTitle("[Security] Outdated Lambda runtime - Consider changing to currently supported Lambda runtime versions, "
|
||||||
|
"listed on https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('lambda', region_name=r)
|
client = boto3.client('lambda', region_name=r)
|
||||||
@ -226,7 +238,7 @@ printResult(outTable, "Region, AccountID, FunctionName, Runtime")
|
|||||||
|
|
||||||
|
|
||||||
printTitle("Iam service review")
|
printTitle("Iam service review")
|
||||||
printSubTitle("[Security] Iam user access key age - Consider rotating access key")
|
printSubTitle("[Security] Iam user access key not rotated for 180 days - Consider rotating access key")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
client = boto3.client('iam', region_name="us-east-1")
|
client = boto3.client('iam', region_name="us-east-1")
|
||||||
@ -239,6 +251,24 @@ for u in users:
|
|||||||
outTable.append([aid, u, i.get("AccessKeyId"), getAgeFromDate(i.get("CreateDate"))])
|
outTable.append([aid, u, i.get("AccessKeyId"), getAgeFromDate(i.get("CreateDate"))])
|
||||||
printResult(outTable, "AccountID, UserName, AccessKeyId, AccessKeyAge")
|
printResult(outTable, "AccountID, UserName, AccessKeyId, AccessKeyAge")
|
||||||
|
|
||||||
|
printSubTitle("[Security] Iam AdministratorAccess policy attached - Consider granting minimum privileges "
|
||||||
|
"to users/groups/roles. AWS managed policies for job functions are recommended. See "
|
||||||
|
"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html")
|
||||||
|
outTable = []
|
||||||
|
|
||||||
|
client = boto3.client('iam', region_name="us-east-1")
|
||||||
|
entityResp = client.list_entities_for_policy(
|
||||||
|
PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
|
||||||
|
)
|
||||||
|
for group in jmespath.search("PolicyGroups[*].GroupName", entityResp):
|
||||||
|
outTable.append([aid, "Group", group])
|
||||||
|
for user in jmespath.search("PolicyUsers[*].UserName", entityResp):
|
||||||
|
outTable.append([aid, "User", user])
|
||||||
|
for role in jmespath.search("PolicyRoles[*].RoleName", entityResp):
|
||||||
|
outTable.append([aid, "Role", role])
|
||||||
|
printResult(outTable, "AccountID, Type, Name")
|
||||||
|
|
||||||
|
|
||||||
printTitle("Cloudwatch service review")
|
printTitle("Cloudwatch service review")
|
||||||
printSubTitle("[Cost Optimization] Cloudwatch LogGroups without retention period - Consider setting retention")
|
printSubTitle("[Cost Optimization] Cloudwatch LogGroups without retention period - Consider setting retention")
|
||||||
outTable = []
|
outTable = []
|
||||||
@ -251,7 +281,7 @@ for r in regions:
|
|||||||
outTable.append([r, aid, i.get("logGroupName"), int(round(i.get("storedBytes")/1024/1024,0))])
|
outTable.append([r, aid, i.get("logGroupName"), int(round(i.get("storedBytes")/1024/1024,0))])
|
||||||
printResult(outTable, "Region, AccountID, LogGroup, SizeMiB")
|
printResult(outTable, "Region, AccountID, LogGroup, SizeMiB")
|
||||||
|
|
||||||
printSubTitle("[Security] Cloudwatch LogGroups unencrypted - Consider encrypting loggroup")
|
printSubTitle("[Security] Cloudwatch LogGroups unencrypted - Consider encrypting LogGroups")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -263,7 +293,8 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, LogGroup")
|
printResult(outTable, "Region, AccountID, LogGroup")
|
||||||
|
|
||||||
printTitle("Backup service review")
|
printTitle("Backup service review")
|
||||||
printSubTitle("[Reliability] Ec2/Rds instances found but AWSBackup plan missing - Consider setting up AWSBackup plans to backup AWS resources")
|
printSubTitle("[Reliability] Ec2/Rds instances found but AWSBackup plan missing - "
|
||||||
|
"Consider setting up AWSBackup plans to backup AWS resources.")
|
||||||
outTable = []
|
outTable = []
|
||||||
for r in regions:
|
for r in regions:
|
||||||
client = boto3.client('backup', region_name=r)
|
client = boto3.client('backup', region_name=r)
|
||||||
@ -294,7 +325,8 @@ for i in jmespath.search("Buckets[*].Name", response):
|
|||||||
printResult(outTable, "AccountID, BucketName")
|
printResult(outTable, "AccountID, BucketName")
|
||||||
|
|
||||||
printTitle("ElastiCache review")
|
printTitle("ElastiCache review")
|
||||||
printSubTitle("[Cost Optimization] ElastiCache instances on x64 platform - Consider Graviton instances such as t4g/r7g for cost saving")
|
printSubTitle("[Cost Optimization] ElastiCache instances on x64 platform - Consider Graviton instances "
|
||||||
|
"such as t4g/r7g to optimize your infrastructure investment.")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -306,7 +338,7 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, CacheClusterId, CacheNodeType")
|
printResult(outTable, "Region, AccountID, CacheClusterId, CacheNodeType")
|
||||||
|
|
||||||
printTitle("LoadBalancer service review")
|
printTitle("LoadBalancer service review")
|
||||||
printSubTitle("[Cost Optimization] LB Target group without targets - Consider removing target groups")
|
printSubTitle("[Cost Optimization] LB Target group without targets - Consider removing empty target groups")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -319,7 +351,9 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, TargetGroup")
|
printResult(outTable, "Region, AccountID, TargetGroup")
|
||||||
|
|
||||||
printTitle("KMS service review")
|
printTitle("KMS service review")
|
||||||
printSubTitle("[Security] Customer Managed Keys do not have auto rotation enabled - Consider enabling auto key rotation")
|
printSubTitle("[Security] Customer Managed Keys do not have auto rotation enabled - "
|
||||||
|
"Consider enabling auto key rotation. When a key is rotated, previous ones "
|
||||||
|
"are still kept within AWS to allow data retrival.")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -338,7 +372,10 @@ for r in regions:
|
|||||||
printResult(outTable, "Region, AccountID, KeyId")
|
printResult(outTable, "Region, AccountID, KeyId")
|
||||||
|
|
||||||
printTitle("ApiGateway service review")
|
printTitle("ApiGateway service review")
|
||||||
printSubTitle("[Security] ApiGateway resource policy missing - Consider restricting access to private API with a policy")
|
printSubTitle("[Security] ApiGateway resource policy missing - Consider restricting access to private API with a "
|
||||||
|
"policy. Private Api should be accessed through Vpc endpoint and a policy ensures the Api cannot "
|
||||||
|
"be accessed otherwise. For more detail, see "
|
||||||
|
"https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-examples.html")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -379,7 +416,9 @@ printResult(outTable, "Region, AccountID, Status")
|
|||||||
|
|
||||||
|
|
||||||
printTitle("Vpc service review")
|
printTitle("Vpc service review")
|
||||||
printSubTitle("[Reliability] Insufficient VPN tunnels - Consider having 2 tunnels for each site VPN connection")
|
printSubTitle("[Reliability] Insufficient VPN tunnels - Consider having 2 tunnels for each site VPN connection. "
|
||||||
|
"AWS performs VPN tunnel endpoint maintenance rather frequently. Having 2 tunnel reduces the risk "
|
||||||
|
"of service interruption.")
|
||||||
outTable = []
|
outTable = []
|
||||||
|
|
||||||
for r in regions:
|
for r in regions:
|
||||||
@ -396,4 +435,5 @@ printResult(outTable, "Region, AccountID, VpnConnection, TunnelCount")
|
|||||||
# TODO
|
# TODO
|
||||||
"""
|
"""
|
||||||
- config enabled for all regions
|
- config enabled for all regions
|
||||||
|
- list users/groups/roles with administrator access
|
||||||
"""
|
"""
|
Loading…
Reference in New Issue
Block a user