Implement AWS security best practices. Master IAM least privilege, VPC design, S3 security, CloudTrail auditing, GuardDuty, and Security Hub for cloud security posture.
AWS Cloud Security Best Practices
IAM Least Privilege
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificS3Actions",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-app-bucket/${aws:PrincipalTag/UserId}/*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "us-east-1"
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
import boto3
import json
def create_least_privilege_role(role_name: str, service: str, permissions: list) -> str:
iam = boto3.client('iam')
# Trust policy
trust_policy = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": f"{service}.amazonaws.com"},
"Action": "sts:AssumeRole",
}]
}
role = iam.create_role(
RoleName=role_name,
AssumeRolePolicyDocument=json.dumps(trust_policy),
Description=f"Least privilege role for {service}",
)
# Create inline policy with only needed permissions
policy = {
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", "Action": permissions, "Resource": "*"}]
}
iam.put_role_policy(
RoleName=role_name,
PolicyName=f"{role_name}-policy",
PolicyDocument=json.dumps(policy),
)
return role['Role']['Arn']
VPC Security Design
import boto3
def create_secure_vpc(cidr: str = "10.0.0.0/16") -> dict:
ec2 = boto3.client('ec2')
# Create VPC
vpc = ec2.create_vpc(CidrBlock=cidr, EnableDnsHostnames=True)
vpc_id = vpc['Vpc']['VpcId']
# Create subnets
public_subnet = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.1.0/24", AvailabilityZone="us-east-1a")
private_subnet = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.2.0/24", AvailabilityZone="us-east-1a")
# VPC Flow Logs
ec2.create_flow_logs(
ResourceIds=[vpc_id],
ResourceType='VPC',
TrafficType='ALL',
LogDestinationType='cloud-watch-logs',
LogGroupName='/vpc/flowlogs',
DeliverLogsPermissionArn=os.getenv('VPC_FLOW_LOGS_ROLE_ARN'),
)
# Default security group - restrict all
default_sg = ec2.describe_security_groups(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]},
{'Name': 'group-name', 'Values': ['default']}]
)['SecurityGroups'][0]['GroupId']
ec2.revoke_security_group_ingress(
GroupId=default_sg,
IpPermissions=[{'IpProtocol': '-1', 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]}]
)
return {'vpc_id': vpc_id, 'public_subnet': public_subnet['Subnet']['SubnetId']}
S3 Security
def secure_s3_bucket(bucket_name: str):
s3 = boto3.client('s3')
# Block all public access
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True,
}
)
# Enable versioning
s3.put_bucket_versioning(
Bucket=bucket_name,
VersioningConfiguration={'Status': 'Enabled'}
)
# Enable SSE with KMS
s3.put_bucket_encryption(
Bucket=bucket_name,
ServerSideEncryptionConfiguration={
'Rules': [{'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'aws:kms',
'KMSMasterKeyID': os.getenv('KMS_KEY_ID'),
}}]
}
)
# Enforce HTTPS
policy = json.dumps({
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [f"arn:aws:s3:::{bucket_name}", f"arn:aws:s3:::{bucket_name}/*"],
"Condition": {"Bool": {"aws:SecureTransport": "false"}},
}]
})
s3.put_bucket_policy(Bucket=bucket_name, Policy=policy)
# Enable CloudTrail logging
s3.put_bucket_logging(
Bucket=bucket_name,
BucketLoggingStatus={
'LoggingEnabled': {
'TargetBucket': f"{bucket_name}-logs",
'TargetPrefix': 'access-logs/',
}
}
)
AWS Security Hub and GuardDuty
def setup_security_monitoring(account_id: str, region: str = 'us-east-1'):
# Enable GuardDuty
gd = boto3.client('guardduty', region_name=region)
detector = gd.create_detector(
Enable=True,
FindingPublishingFrequency='SIX_HOURS',
Features=[
{'Name': 'S3_DATA_EVENTS', 'Status': 'ENABLED'},
{'Name': 'MALWARE_PROTECTION', 'Status': 'ENABLED'},
{'Name': 'RDS_LOGIN_EVENTS', 'Status': 'ENABLED'},
{'Name': 'RUNTIME_MONITORING', 'Status': 'ENABLED'},
]
)
# Enable Security Hub
sh = boto3.client('securityhub', region_name=region)
sh.enable_security_hub(
EnableDefaultStandards=True,
AutoEnableControls=True,
)
# Enable CIS Benchmark standard
sh.batch_enable_standards(
StandardsSubscriptionRequests=[{
'StandardsArn': f'arn:aws:securityhub:{region}::standards/cis-aws-foundations-benchmark/v/1.4.0',
}]
)
# Setup CloudTrail
ct = boto3.client('cloudtrail', region_name=region)
ct.create_trail(
Name='security-trail',
S3BucketName=f'cloudtrail-logs-{account_id}',
IsMultiRegionTrail=True,
EnableLogFileValidation=True,
CloudWatchLogsLogGroupArn=f'arn:aws:logs:{region}:{account_id}:log-group:CloudTrail',
)
ct.start_logging(Name='security-trail')
AWS Security Checklist
| Control |
Service |
| MFA enforcement |
IAM |
| API audit logging |
CloudTrail |
| Threat detection |
GuardDuty |
| Security posture |
Security Hub |
| Data encryption |
KMS |
| Network segmentation |
VPC + Security Groups |
| Vulnerability scanning |
Amazon Inspector |
| Secret management |
Secrets Manager |