Introduction
The AWS Well-Architected Framework provides architectural best practices across six pillars. This guide demonstrates practical implementation of these principles for production systems.
Operational Excellence
Infrastructure as Code
Implement everything as code using Terraform:
# main.tf
terraform {
required_version = ">= 1.0"
backend "s3" {
bucket = "terraform-state-bucket"
key = "production/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-lock"
encrypt = true
}
}
module "vpc" {
source = "./modules/vpc"
cidr_block = var.vpc_cidr
availability_zones = data.aws_availability_zones.available.names
enable_nat_gateway = true
enable_vpn_gateway = true
enable_flow_logs = true
tags = local.common_tags
}
module "eks" {
source = "./modules/eks"
cluster_name = "${var.environment}-cluster"
cluster_version = "1.28"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
node_groups = {
general = {
desired_capacity = 3
min_capacity = 2
max_capacity = 10
instance_types = ["t3.large
}
}
}
Automated Deployment Pipeline
# .github/workflows/deploy.yml
name: Deploy Infrastructure
on:
push:
branches: [main]
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Terraform Plan
run: |
terraform init
terraform plan -out=tfplan
- name: Upload Plan
uses: actions/upload-artifact@v3
with:
name: tfplan
path: tfplan
apply:
needs: plan
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Download Plan
uses: actions/download-artifact@v3
with:
name: tfplan
- name: Terraform Apply
run: |
terraform init
terraform apply tfplan
Security
Multi-Layer Security Architecture
# security.tf
resource "aws_security_group" "alb" {
name_prefix = "${var.environment}-alb-"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_wafv2_web_acl" "main" {
name = "${var.environment}-waf"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "RateLimitRule"
priority = 1
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "RateLimitRule"
sampled_requests_enabled = true
}
}
rule {
name = "AWSManagedRulesCommonRuleSet"
priority = 2
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "CommonRuleSetMetric"
sampled_requests_enabled = true
}
}
}
Secrets Management
resource "aws_secretsmanager_secret" "db_password" {
name_prefix = "${var.environment}-db-password-"
recovery_window_in_days = 7
rotation_rules {
automatically_after_days = 30
}
}
resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = jsonencode({
username = "admin"
password = random_password.db_password.result
})
}
# Use in application
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
}
locals {
db_creds = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)
}
Reliability
Multi-AZ Architecture
resource "aws_rds_cluster" "aurora" {
cluster_identifier = "${var.environment}-aurora-cluster"
engine = "aurora-postgresql"
engine_version = "15.3"
database_name = var.database_name
master_username = local.db_creds.username
master_password = local.db_creds.password
db_subnet_group_name = aws_db_subnet_group.aurora.name
vpc_security_group_ids = [aws_security_group.aurora.id]
backup_retention_period = 30
preferred_backup_window = "03:00-04:00"
enabled_cloudwatch_logs_exports = ["postgresql
db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora.name
skip_final_snapshot = false
final_snapshot_identifier = "${var.environment}-aurora-final-${formatdate("YYYY-MM-DD-hhmm", timestamp())}"
}
resource "aws_rds_cluster_instance" "aurora" {
count = 3
identifier = "${var.environment}-aurora-${count.index}"
cluster_identifier = aws_rds_cluster.aurora.id
instance_class = "db.r6g.large"
engine = aws_rds_cluster.aurora.engine
engine_version = aws_rds_cluster.aurora.engine_version
performance_insights_enabled = true
monitoring_interval = 60
monitoring_role_arn = aws_iam_role.rds_monitoring.arn
}
Auto-Scaling Configuration
resource "aws_autoscaling_group" "app" {
name_prefix = "${var.environment}-app-"
vpc_zone_identifier = module.vpc.private_subnet_ids
target_group_arns = [aws_lb_target_group.app.arn]
health_check_type = "ELB"
health_check_grace_period = 300
min_size = 2
max_size = 10
desired_capacity = 3
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
tag {
key = "Name"
value = "${var.environment}-app"
propagate_at_launch = true
}
}
resource "aws_autoscaling_policy" "target_tracking" {
name = "${var.environment}-target-tracking"
autoscaling_group_name = aws_autoscaling_group.app.name
policy_type = "TargetTrackingScaling"
target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ASGAverageCPUUtilization"
}
target_value = 70.0
}
}
Performance Efficiency
CDN and Caching
resource "aws_cloudfront_distribution" "app" {
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
origin {
domain_name = aws_lb.app.dns_name
origin_id = "ALB-${aws_lb.app.id}"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2
}
}
default_cache_behavior {
allowed_methods = ["DELETE"
- GET"
- HEAD"
- OPTIONS"
- PATCH"
- POST"
- PUT
cached_methods = ["GET"
- HEAD
target_origin_id = "ALB-${aws_lb.app.id}"
forwarded_values {
query_string = true
headers = ["Origin"
- Accept"
- Authorization
cookies {
forward = "all"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000
}
ordered_cache_behavior {
path_pattern = "/api/*"
allowed_methods = ["DELETE"
- GET"
- HEAD"
- OPTIONS"
- PATCH"
- POST"
- PUT
cached_methods = ["GET"
- HEAD"
- OPTIONS
target_origin_id = "ALB-${aws_lb.app.id}"
forwarded_values {
query_string = true
headers = ["*
cookies {
forward = "all"
}
}
viewer_protocol_policy = "https-only"
min_ttl = 0
default_ttl = 0
max_ttl = 0
}
price_class = "PriceClass_100"
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.app.arn
ssl_support_method = "sni-only"
}
}
resource "aws_elasticache_replication_group" "redis" {
replication_group_id = "${var.environment}-redis"
replication_group_description = "Redis cluster for session and cache"
engine = "redis"
node_type = "cache.r6g.large"
number_cache_clusters = 3
automatic_failover_enabled = true
multi_az_enabled = true
subnet_group_name = aws_elasticache_subnet_group.redis.name
security_group_ids = [aws_security_group.redis.id]
at_rest_encryption_enabled = true
transit_encryption_enabled = true
auth_token = random_password.redis_auth.result
snapshot_retention_limit = 7
snapshot_window = "03:00-05:00"
log_delivery_configuration {
destination = aws_cloudwatch_log_group.redis.name
destination_type = "cloudwatch-logs"
log_format = "json"
log_type = "slow-log"
}
}
Cost Optimization
Resource Tagging and Cost Allocation
locals {
common_tags = {
Environment = var.environment
Project = var.project_name
ManagedBy = "Terraform"
CostCenter = var.cost_center
Owner = var.owner_email
}
}
resource "aws_budgets_budget" "monthly" {
name = "${var.environment}-monthly-budget"
budget_type = "COST"
limit_amount = "10000"
limit_unit = "USD"
time_unit = "MONTHLY"
notification {
comparison_operator = "GREATER_THAN"
threshold = 80
threshold_type = "PERCENTAGE"
notification_type = "FORECASTED"
subscriber_email_addresses = [var.owner_email]
}
cost_filters = {
TagKeyValue = "Environment$${var.environment}"
}
}
Spot Instances for Non-Critical Workloads
resource "aws_launch_template" "spot" {
name_prefix = "${var.environment}-spot-"
instance_market_options {
market_type = "spot"
spot_options {
max_price = "0.05"
spot_instance_type = "one-time"
}
}
mixed_instances_policy {
instances_distribution {
on_demand_base_capacity = 1
on_demand_percentage_above_base_capacity = 25
spot_allocation_strategy = "lowest-price"
}
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.app.id
version = "$Latest"
}
override {
instance_type = "t3.medium"
}
override {
instance_type = "t3a.medium"
}
}
}
}
Sustainability
Right-Sizing and Efficiency
resource "aws_compute_optimizer_enrollment_status" "example" {
status = "Active"
}
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux_2.id
instance_type = "t4g.medium" # Graviton instances for better efficiency
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 1
instance_metadata_tags = "enabled"
}
root_block_device {
volume_type = "gp3"
volume_size = 20
encrypted = true
}
}
Monitoring and Observability
Comprehensive Monitoring Setup
resource "aws_cloudwatch_dashboard" "main" {
dashboard_name = "${var.environment}-dashboard"
dashboard_body = jsonencode({
widgets = [
{
type = "metric"
properties = {
metrics = [
["AWS/ApplicationELB"
- TargetResponseTime", { stat = "Average" }],
["."
- RequestCount", { stat = "Sum" }],
["."
- HTTPCode_Target_4XX_Count", { stat = "Sum" }],
["."
- HTTPCode_Target_5XX_Count", { stat = "Sum" }]
]
period = 300
stat = "Average"
region = var.aws_region
title = "ALB Metrics"
}
}
]
})
}
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "${var.environment}-high-cpu"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "300"
statistic = "Average"
threshold = "80"
alarm_description = "This metric monitors EC2 cpu utilization"
dimensions = {
AutoScalingGroupName = aws_autoscaling_group.app.name
}
alarm_actions = [aws_sns_topic.alerts.arn]
}
Conclusion
The AWS Well-Architected Framework provides a solid foundation for building reliable, secure, efficient, and cost-effective systems in the cloud. By implementing these patterns and continuously reviewing your architecture against the framework’s pillars, you can ensure your systems meet the highest standards of cloud excellence.
Comments