mirror of
https://github.com/ghndrx/terraform-foundation.git
synced 2026-02-10 06:45:06 +00:00
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
396 lines
11 KiB
HCL
396 lines
11 KiB
HCL
################################################################################
|
|
# Security Groups Module
|
|
#
|
|
# Creates common security group patterns for multi-tier architectures:
|
|
# - Web tier (HTTP/HTTPS from ALB or internet)
|
|
# - App tier (from web tier only)
|
|
# - Database tier (from app tier only)
|
|
# - Bastion host (SSH from allowed CIDRs)
|
|
# - VPC endpoints (HTTPS from VPC)
|
|
# - EKS patterns (cluster, nodes)
|
|
################################################################################
|
|
|
|
terraform {
|
|
required_version = ">= 1.5.0"
|
|
required_providers {
|
|
aws = {
|
|
source = "hashicorp/aws"
|
|
version = ">= 5.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
data "aws_vpc" "selected" {
|
|
id = var.vpc_id
|
|
}
|
|
|
|
locals {
|
|
vpc_cidr = data.aws_vpc.selected.cidr_block
|
|
}
|
|
|
|
################################################################################
|
|
# Web Tier Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "web" {
|
|
count = var.create_web_tier ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-web-"
|
|
description = "Web tier - HTTP/HTTPS access"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-web"
|
|
Tier = "web"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "web_http" {
|
|
count = var.create_web_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.web[0].id
|
|
description = "HTTP from allowed sources"
|
|
from_port = 80
|
|
to_port = 80
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = var.web_ingress_cidr
|
|
|
|
tags = { Name = "http-ingress" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "web_https" {
|
|
count = var.create_web_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.web[0].id
|
|
description = "HTTPS from allowed sources"
|
|
from_port = 443
|
|
to_port = 443
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = var.web_ingress_cidr
|
|
|
|
tags = { Name = "https-ingress" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "web_all" {
|
|
count = var.create_web_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.web[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# App Tier Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "app" {
|
|
count = var.create_app_tier ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-app-"
|
|
description = "App tier - access from web tier"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-app"
|
|
Tier = "app"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "app_from_web" {
|
|
count = var.create_app_tier && var.create_web_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.app[0].id
|
|
description = "App port from web tier"
|
|
from_port = var.app_port
|
|
to_port = var.app_port
|
|
ip_protocol = "tcp"
|
|
referenced_security_group_id = aws_security_group.web[0].id
|
|
|
|
tags = { Name = "from-web-tier" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "app_from_cidr" {
|
|
count = var.create_app_tier && !var.create_web_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.app[0].id
|
|
description = "App port from VPC"
|
|
from_port = var.app_port
|
|
to_port = var.app_port
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = local.vpc_cidr
|
|
|
|
tags = { Name = "from-vpc" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "app_all" {
|
|
count = var.create_app_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.app[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# Database Tier Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "db" {
|
|
count = var.create_db_tier ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-db-"
|
|
description = "Database tier - access from app tier"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-db"
|
|
Tier = "database"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "db_from_app" {
|
|
count = var.create_db_tier && var.create_app_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.db[0].id
|
|
description = "Database port from app tier"
|
|
from_port = var.db_port
|
|
to_port = var.db_port
|
|
ip_protocol = "tcp"
|
|
referenced_security_group_id = aws_security_group.app[0].id
|
|
|
|
tags = { Name = "from-app-tier" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "db_from_cidr" {
|
|
count = var.create_db_tier && !var.create_app_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.db[0].id
|
|
description = "Database port from VPC"
|
|
from_port = var.db_port
|
|
to_port = var.db_port
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = local.vpc_cidr
|
|
|
|
tags = { Name = "from-vpc" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "db_all" {
|
|
count = var.create_db_tier ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.db[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# Bastion Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "bastion" {
|
|
count = var.create_bastion ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-bastion-"
|
|
description = "Bastion host - SSH from allowed CIDRs"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-bastion"
|
|
Tier = "bastion"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "bastion_ssh" {
|
|
for_each = var.create_bastion ? toset(var.allowed_ssh_cidrs) : []
|
|
|
|
security_group_id = aws_security_group.bastion[0].id
|
|
description = "SSH from ${each.value}"
|
|
from_port = 22
|
|
to_port = 22
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = each.value
|
|
|
|
tags = { Name = "ssh-from-${replace(each.value, "/", "-")}" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "bastion_all" {
|
|
count = var.create_bastion ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.bastion[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# VPC Endpoints Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "endpoints" {
|
|
count = var.create_endpoints ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-endpoints-"
|
|
description = "VPC Endpoints - HTTPS from VPC"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-endpoints"
|
|
Tier = "endpoints"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "endpoints_https" {
|
|
count = var.create_endpoints ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.endpoints[0].id
|
|
description = "HTTPS from VPC"
|
|
from_port = 443
|
|
to_port = 443
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = local.vpc_cidr
|
|
|
|
tags = { Name = "https-from-vpc" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "endpoints_all" {
|
|
count = var.create_endpoints ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.endpoints[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# EKS Cluster Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "eks_cluster" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-eks-cluster-"
|
|
description = "EKS cluster control plane"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-eks-cluster"
|
|
Tier = "eks"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "eks_cluster_https" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.eks_cluster[0].id
|
|
description = "HTTPS from VPC (kubectl)"
|
|
from_port = 443
|
|
to_port = 443
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = local.vpc_cidr
|
|
|
|
tags = { Name = "https-from-vpc" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "eks_cluster_all" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.eks_cluster[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|
|
|
|
################################################################################
|
|
# EKS Nodes Security Group
|
|
################################################################################
|
|
|
|
resource "aws_security_group" "eks_nodes" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
name_prefix = "${var.name_prefix}-eks-nodes-"
|
|
description = "EKS worker nodes"
|
|
vpc_id = var.vpc_id
|
|
|
|
tags = merge(var.tags, {
|
|
Name = "${var.name_prefix}-eks-nodes"
|
|
Tier = "eks"
|
|
"kubernetes.io/cluster/${var.name_prefix}" = "owned"
|
|
})
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "eks_nodes_self" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.eks_nodes[0].id
|
|
description = "Node to node communication"
|
|
ip_protocol = "-1"
|
|
referenced_security_group_id = aws_security_group.eks_nodes[0].id
|
|
|
|
tags = { Name = "node-to-node" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_ingress_rule" "eks_nodes_cluster" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.eks_nodes[0].id
|
|
description = "From cluster control plane"
|
|
from_port = 1025
|
|
to_port = 65535
|
|
ip_protocol = "tcp"
|
|
referenced_security_group_id = aws_security_group.eks_cluster[0].id
|
|
|
|
tags = { Name = "from-cluster" }
|
|
}
|
|
|
|
resource "aws_vpc_security_group_egress_rule" "eks_nodes_all" {
|
|
count = var.create_eks ? 1 : 0
|
|
|
|
security_group_id = aws_security_group.eks_nodes[0].id
|
|
description = "Allow all outbound"
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
|
|
tags = { Name = "all-egress" }
|
|
}
|