feat: Terraform Foundation - AWS Landing Zone

Enterprise-grade multi-tenant AWS cloud foundation.

Modules:
- GitHub OIDC for keyless CI/CD authentication
- IAM account settings and security baseline
- AWS Config Rules for compliance
- ABAC (Attribute-Based Access Control)
- SCPs (Service Control Policies)

Features:
- Multi-account architecture
- Cost optimization patterns
- Security best practices
- Comprehensive documentation

Tech: Terraform, AWS Organizations, IAM Identity Center
This commit is contained in:
2026-02-01 20:06:28 +00:00
commit 6136cde9bb
145 changed files with 30832 additions and 0 deletions

View File

@@ -0,0 +1,431 @@
################################################################################
# CloudWatch Dashboard Module
#
# Creates CloudWatch dashboards for common AWS services:
# - ECS services
# - RDS databases
# - Lambda functions
# - ALB/NLB
# - API Gateway
#
# Usage:
# module "dashboard" {
# source = "../modules/cloudwatch-dashboard"
# name = "myapp-prod"
#
# ecs_clusters = ["prod-cluster"]
# ecs_services = ["myapp-api"]
# rds_instances = ["myapp-db"]
# lambda_functions = ["myapp-worker"]
# alb_arns = ["arn:aws:elasticloadbalancing:..."]
# }
################################################################################
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
variable "name" {
type = string
description = "Dashboard name"
}
variable "ecs_clusters" {
type = list(string)
default = []
description = "ECS cluster names to monitor"
}
variable "ecs_services" {
type = list(string)
default = []
description = "ECS service names to monitor"
}
variable "rds_instances" {
type = list(string)
default = []
description = "RDS instance identifiers"
}
variable "lambda_functions" {
type = list(string)
default = []
description = "Lambda function names"
}
variable "alb_arns" {
type = list(string)
default = []
description = "ALB ARN suffixes (app/name/id)"
}
variable "api_gateway_apis" {
type = list(string)
default = []
description = "API Gateway API IDs"
}
variable "sqs_queues" {
type = list(string)
default = []
description = "SQS queue names"
}
variable "dynamodb_tables" {
type = list(string)
default = []
description = "DynamoDB table names"
}
variable "tags" {
type = map(string)
default = {}
}
data "aws_region" "current" {}
locals {
region = data.aws_region.current.name
# ECS widgets
ecs_widgets = length(var.ecs_clusters) > 0 ? [
{
type = "metric"
x = 0
y = 0
width = 12
height = 6
properties = {
title = "ECS CPU Utilization"
region = local.region
metrics = [
for i, cluster in var.ecs_clusters : [
"AWS/ECS", "CPUUtilization",
"ClusterName", cluster,
"ServiceName", try(var.ecs_services[i], cluster)
]
]
stat = "Average"
period = 300
}
},
{
type = "metric"
x = 12
y = 0
width = 12
height = 6
properties = {
title = "ECS Memory Utilization"
region = local.region
metrics = [
for i, cluster in var.ecs_clusters : [
"AWS/ECS", "MemoryUtilization",
"ClusterName", cluster,
"ServiceName", try(var.ecs_services[i], cluster)
]
]
stat = "Average"
period = 300
}
}
] : []
# RDS widgets
rds_widgets = length(var.rds_instances) > 0 ? [
{
type = "metric"
x = 0
y = 6
width = 8
height = 6
properties = {
title = "RDS CPU Utilization"
region = local.region
metrics = [
for db in var.rds_instances : [
"AWS/RDS", "CPUUtilization",
"DBInstanceIdentifier", db
]
]
stat = "Average"
period = 300
}
},
{
type = "metric"
x = 8
y = 6
width = 8
height = 6
properties = {
title = "RDS Database Connections"
region = local.region
metrics = [
for db in var.rds_instances : [
"AWS/RDS", "DatabaseConnections",
"DBInstanceIdentifier", db
]
]
stat = "Average"
period = 300
}
},
{
type = "metric"
x = 16
y = 6
width = 8
height = 6
properties = {
title = "RDS Free Storage"
region = local.region
metrics = [
for db in var.rds_instances : [
"AWS/RDS", "FreeStorageSpace",
"DBInstanceIdentifier", db
]
]
stat = "Average"
period = 300
}
}
] : []
# Lambda widgets
lambda_widgets = length(var.lambda_functions) > 0 ? [
{
type = "metric"
x = 0
y = 12
width = 8
height = 6
properties = {
title = "Lambda Invocations"
region = local.region
metrics = [
for fn in var.lambda_functions : [
"AWS/Lambda", "Invocations",
"FunctionName", fn
]
]
stat = "Sum"
period = 300
}
},
{
type = "metric"
x = 8
y = 12
width = 8
height = 6
properties = {
title = "Lambda Errors"
region = local.region
metrics = [
for fn in var.lambda_functions : [
"AWS/Lambda", "Errors",
"FunctionName", fn
]
]
stat = "Sum"
period = 300
}
},
{
type = "metric"
x = 16
y = 12
width = 8
height = 6
properties = {
title = "Lambda Duration"
region = local.region
metrics = [
for fn in var.lambda_functions : [
"AWS/Lambda", "Duration",
"FunctionName", fn
]
]
stat = "Average"
period = 300
}
}
] : []
# ALB widgets
alb_widgets = length(var.alb_arns) > 0 ? [
{
type = "metric"
x = 0
y = 18
width = 8
height = 6
properties = {
title = "ALB Request Count"
region = local.region
metrics = [
for alb in var.alb_arns : [
"AWS/ApplicationELB", "RequestCount",
"LoadBalancer", alb
]
]
stat = "Sum"
period = 300
}
},
{
type = "metric"
x = 8
y = 18
width = 8
height = 6
properties = {
title = "ALB 5xx Errors"
region = local.region
metrics = [
for alb in var.alb_arns : [
"AWS/ApplicationELB", "HTTPCode_ELB_5XX_Count",
"LoadBalancer", alb
]
]
stat = "Sum"
period = 300
}
},
{
type = "metric"
x = 16
y = 18
width = 8
height = 6
properties = {
title = "ALB Response Time"
region = local.region
metrics = [
for alb in var.alb_arns : [
"AWS/ApplicationELB", "TargetResponseTime",
"LoadBalancer", alb
]
]
stat = "Average"
period = 300
}
}
] : []
# SQS widgets
sqs_widgets = length(var.sqs_queues) > 0 ? [
{
type = "metric"
x = 0
y = 24
width = 12
height = 6
properties = {
title = "SQS Messages Visible"
region = local.region
metrics = [
for q in var.sqs_queues : [
"AWS/SQS", "ApproximateNumberOfMessagesVisible",
"QueueName", q
]
]
stat = "Average"
period = 300
}
},
{
type = "metric"
x = 12
y = 24
width = 12
height = 6
properties = {
title = "SQS Age of Oldest Message"
region = local.region
metrics = [
for q in var.sqs_queues : [
"AWS/SQS", "ApproximateAgeOfOldestMessage",
"QueueName", q
]
]
stat = "Maximum"
period = 300
}
}
] : []
# DynamoDB widgets
dynamodb_widgets = length(var.dynamodb_tables) > 0 ? [
{
type = "metric"
x = 0
y = 30
width = 12
height = 6
properties = {
title = "DynamoDB Read Capacity"
region = local.region
metrics = [
for t in var.dynamodb_tables : [
"AWS/DynamoDB", "ConsumedReadCapacityUnits",
"TableName", t
]
]
stat = "Sum"
period = 300
}
},
{
type = "metric"
x = 12
y = 30
width = 12
height = 6
properties = {
title = "DynamoDB Write Capacity"
region = local.region
metrics = [
for t in var.dynamodb_tables : [
"AWS/DynamoDB", "ConsumedWriteCapacityUnits",
"TableName", t
]
]
stat = "Sum"
period = 300
}
}
] : []
all_widgets = concat(
local.ecs_widgets,
local.rds_widgets,
local.lambda_widgets,
local.alb_widgets,
local.sqs_widgets,
local.dynamodb_widgets
)
}
resource "aws_cloudwatch_dashboard" "main" {
dashboard_name = var.name
dashboard_body = jsonencode({
widgets = local.all_widgets
})
}
output "dashboard_name" {
value = aws_cloudwatch_dashboard.main.dashboard_name
}
output "dashboard_arn" {
value = aws_cloudwatch_dashboard.main.dashboard_arn
}