Comprehensive security guidelines for cloud architectures generated by Megha Agent.
- Network Security
- Identity & Access Management
- Data Protection
- Application Security
- Compliance & Governance
- Incident Response
- Principle: Defense in depth with multiple layers
┌─────────────────────────────────────┐
│ Internet Gateway │
│ Public Tier │
├─────────────────────────────────────┤
│ NAT Gateway (Egress Control) │
│ Private Tier │
├─────────────────────────────────────┤
│ Database Tier (Isolated) │
└─────────────────────────────────────┘
Best Practices:
- ✓ Use multiple availability zones
- ✓ Implement public/private subnet separation
- ✓ Database tier should be completely isolated
- ✓ Use VPC endpoints for AWS service access (no internet)
Security Groups (Stateful, applied to resources):
# Web tier - accept HTTP/HTTPS
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# App tier - only from web tier
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.web.id]
}
# Database - only from app tier
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}Network ACLs (Stateless, applied to subnets):
- Default allow all
- Add explicit DENY rules for suspicious traffic
- Block known bad IPs/ranges
# AWS Shield + WAF
resource "aws_wafv2_web_acl" "main" {
scope = "CLOUDFRONT"
rule {
name = "RateLimitRule"
priority = 0
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "RateLimitMetric"
sampled_requests_enabled = true
}
}
}- Least Privilege Principle
# ✗ DON'T - Too permissive
policy_document = jsonencode({
Statement = [{
Effect = "Allow"
Action = "s3:*"
Resource = "*"
}]
})
# ✓ DO - Specific permissions
policy_document = jsonencode({
Statement = [{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject"
]
Resource = "arn:aws:s3:::my-bucket/uploads/*"
}]
})- Use IAM Roles Instead of Keys
# ✓ Preferred: Use instance roles
resource "aws_iam_instance_profile" "app" {
role = aws_iam_role.app_role.name
}
# ✗ Avoid: Access keys (if possible)
# Access keys should only be for users who truly need them- MFA Enforcement
# Require MFA for console access
resource "aws_iam_user" "developer" {
name = "dev-user"
}
# Add to policy requiring MFA
{
"Condition": {
"Bool": { "aws:MultiFactorAuthPresent": "true" }
}
}Use service roles, not shared credentials:
- Lambda → RDS: Use RDS IAM authentication
- EC2 → S3: Use instance role
- Container → Secrets Manager: Use task role
- Temporary Credentials
# Get temporary credentials
aws sts assume-role \
--role-arn arn:aws:iam::ACCOUNT:role/MyRole \
--role-session-name MySession- Session Duration Limits
max_session_duration = 3600 # 1 hour maxAWS Services:
# S3 - Server-side encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.main.arn
}
}
}
# RDS - Encryption at rest
resource "aws_db_instance" "main" {
storage_encrypted = true
kms_key_id = aws_kms_key.main.arn
}
# EBS - Encrypted volumes
resource "aws_ebs_volume" "main" {
encrypted = true
kms_key_id = aws_kms_key.main.arn
}# Force HTTPS
resource "aws_s3_bucket_policy" "force_https" {
bucket = aws_s3_bucket.main.id
policy = jsonencode({
Statement = [{
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = [
aws_s3_bucket.main.arn,
"${aws_s3_bucket.main.arn}/*"
]
Condition = {
Bool = { "aws:SecureTransport": "false" }
}
}]
})
}
# TLS 1.2+ for database connections
resource "aws_db_instance" "main" {
# Requires SSL/TLS for connections
db_subnet_group_name = aws_db_subnet_group.main.name
publicly_accessible = false
}# Use AWS KMS for key management
resource "aws_kms_key" "main" {
description = "Master key for data encryption"
deletion_window_in_days = 7
enable_key_rotation = true # Automatic annual rotation
tags = {
Name = "main-key"
}
}
# Rotate keys regularly
resource "aws_kms_alias" "main" {
name = "alias/main-key"
target_key_id = aws_kms_key.main.key_id
}# Use Secrets Manager (not .env files)
resource "aws_secretsmanager_secret" "db_password" {
name = "db-password"
}
resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = jsonencode({
username = "admin"
password = random_password.db.result
})
}
# Retrieve in application
# Never log or expose secrets- API Gateway Authentication
resource "aws_api_gateway_rest_api" "main" {
name = "secure-api"
}
resource "aws_api_gateway_resource" "main" {
rest_api_id = aws_api_gateway_rest_api.main.id
parent_id = aws_api_gateway_rest_api.main.root_resource_id
path_part = "protected"
}
resource "aws_api_gateway_method" "main" {
rest_api_id = aws_api_gateway_rest_api.main.id
resource_id = aws_api_gateway_resource.main.id
http_method = "GET"
authorization = "AWS_IAM" # Require IAM authentication
}- Rate Limiting & Throttling
resource "aws_api_gateway_method_settings" "main" {
method_path = "*/*"
resource_rest_api_id = aws_api_gateway_rest_api.main.id
stage_name = aws_api_gateway_stage.main.stage_name
settings {
throttling_burst_limit = 5000
throttling_rate_limit = 10000
}
}# Use minimal base images
# Scan images for vulnerabilities
# Don't run as root
resource "aws_ecs_task_definition" "app" {
container_definitions = jsonencode([{
image = "my-image:v1.0"
user = "1000" # Non-root user
readonly_root_filesystem = true
logConfiguration = {
logDriver = "awslogs"
}
}])
}# Enable CloudTrail for all API calls
resource "aws_cloudtrail" "main" {
name = "organization-trail"
s3_bucket_name = aws_s3_bucket.cloudtrail_logs.id
include_global_service_events = true
is_multi_region_trail = true
enable_log_file_validation = true
depends_on = [aws_s3_bucket_policy.cloudtrail]
}
# Enable VPC Flow Logs
resource "aws_flow_log" "main" {
iam_role_arn = aws_iam_role.flowlogs.arn
log_destination = aws_cloudwatch_log_group.flowlogs.arn
traffic_type = "ALL"
vpc_id = aws_vpc.main.id
}# AWS Config for compliance
resource "aws_config_config_rule" "s3_encryption" {
name = "s3-bucket-server-side-encryption-enabled"
source {
owner = "AWS"
source_identifier = "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED"
}
}
# Enable Security Hub
resource "aws_securityhub_account" "main" {}# Enforce region-specific storage
resource "aws_s3_bucket" "data" {
bucket = "company-data-bucket"
}
# Restrict to specific region
resource "aws_s3_bucket_policy" "regional" {
bucket = aws_s3_bucket.data.id
policy = jsonencode({
Statement = [{
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = "${aws_s3_bucket.data.arn}/*"
Condition = {
StringNotEquals = {
"aws:RequestedRegion": "us-east-1"
}
}
}]
})
}# CloudWatch alarms for security events
resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" {
alarm_name = "UnauthorizedAPICallsAlarm"
comparison_operator = "GreaterThanOrEqualToEventCount"
evaluation_periods = 1
metric_name = "UnauthorizedAPICallsMetric"
period = 300
statistic = "Sum"
threshold = 1
alarm_actions = [aws_sns_topic.security_alerts.arn]
}# Lambda function for automated response
resource "aws_lambda_function" "security_response" {
filename = "security_response.zip"
handler = "index.handler"
role = aws_iam_role.lambda.arn
# Triggered by security events
}
# EventBridge rule to trigger
resource "aws_cloudwatch_event_rule" "security_finding" {
event_pattern = jsonencode({
source = ["aws.securityhub"]
detail-type = ["Security Hub Findings"]
})
}- VPC properly configured with public/private subnets
- All data encrypted at rest (KMS)
- All data encrypted in transit (TLS 1.2+)
- IAM roles follow least privilege
- MFA enabled for all human users
- CloudTrail enabled and logging to S3
- CloudWatch alarms configured for security events
- WAF/Shield enabled on public-facing resources
- Security groups properly restricted
- Backup and disaster recovery tested
- Secrets stored in Secrets Manager, not in code
- Regular security assessments scheduled
- Incident response plan documented
- Compliance scanning enabled (AWS Config, Security Hub)
See Cost Optimization Guide for balancing security with efficiency.