mirror of
https://github.com/cdr/code-server.git
synced 2025-12-08 01:12:40 +01:00
This commit adds complete Terraform infrastructure as code for deploying code-server on both EC2 and EKS platforms with enterprise-grade security and SAML/OIDC authentication. Features: - EC2 deployment with Auto Scaling Groups and Application Load Balancer - EKS deployment with managed node groups and AWS Load Balancer Controller - Private network setup with VPC, private subnets, and NAT gateways - SAML/OIDC authentication using OAuth2 Proxy - Security hardening: - KMS encryption for data at rest - TLS encryption in transit - IAM roles with least privilege - Security groups with minimal access - VPC Flow Logs - IMDSv2 enforcement - Auto-scaling capabilities for both EC2 and EKS - CloudWatch logging and monitoring - Automated deployment scripts Terraform Modules: - modules/vpc: VPC with public/private subnets, NAT, and VPC endpoints - modules/security: Security groups, IAM roles, and KMS keys - modules/ec2: EC2 Auto Scaling deployment with ALB - modules/eks: EKS cluster with managed node groups and addons Deployments: - deployments/ec2: EC2 deployment configuration - deployments/eks: EKS deployment configuration with Kubernetes manifests Documentation: - README.md: Comprehensive deployment and operations guide - QUICK-START.md: Quick reference for fast deployment - SAML-SETUP-GUIDE.md: Step-by-step IdP configuration guide Scripts: - scripts/deploy-ec2.sh: Automated EC2 deployment - scripts/deploy-eks.sh: Automated EKS deployment - scripts/destroy-ec2.sh: EC2 cleanup - scripts/destroy-eks.sh: EKS cleanup
334 lines
8 KiB
HCL
334 lines
8 KiB
HCL
# Security Module for Code-Server
|
|
# Creates security groups, IAM roles, and ACM certificates
|
|
|
|
# Security Group for ALB
|
|
resource "aws_security_group" "alb" {
|
|
name_prefix = "${var.name_prefix}-alb-"
|
|
description = "Security group for Application Load Balancer"
|
|
vpc_id = var.vpc_id
|
|
|
|
ingress {
|
|
description = "HTTPS from anywhere"
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
cidr_blocks = var.allowed_cidr_blocks
|
|
}
|
|
|
|
ingress {
|
|
description = "HTTP from anywhere (redirect to HTTPS)"
|
|
from_port = 80
|
|
to_port = 80
|
|
protocol = "tcp"
|
|
cidr_blocks = var.allowed_cidr_blocks
|
|
}
|
|
|
|
egress {
|
|
description = "Allow all outbound"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-alb-sg"
|
|
}
|
|
)
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
# Security Group for EC2 Code-Server instances
|
|
resource "aws_security_group" "code_server_ec2" {
|
|
name_prefix = "${var.name_prefix}-code-server-ec2-"
|
|
description = "Security group for Code-Server EC2 instances"
|
|
vpc_id = var.vpc_id
|
|
|
|
ingress {
|
|
description = "Code-Server port from ALB"
|
|
from_port = 8080
|
|
to_port = 8080
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.alb.id]
|
|
}
|
|
|
|
ingress {
|
|
description = "OAuth2 Proxy from ALB"
|
|
from_port = 4180
|
|
to_port = 4180
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.alb.id]
|
|
}
|
|
|
|
ingress {
|
|
description = "SSH from bastion (if needed)"
|
|
from_port = 22
|
|
to_port = 22
|
|
protocol = "tcp"
|
|
cidr_blocks = var.ssh_allowed_cidr_blocks
|
|
}
|
|
|
|
egress {
|
|
description = "Allow all outbound"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-code-server-ec2-sg"
|
|
}
|
|
)
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
# Security Group for EKS Cluster
|
|
resource "aws_security_group" "eks_cluster" {
|
|
name_prefix = "${var.name_prefix}-eks-cluster-"
|
|
description = "Security group for EKS cluster control plane"
|
|
vpc_id = var.vpc_id
|
|
|
|
egress {
|
|
description = "Allow all outbound"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-eks-cluster-sg"
|
|
}
|
|
)
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
# Security Group for EKS Nodes
|
|
resource "aws_security_group" "eks_nodes" {
|
|
name_prefix = "${var.name_prefix}-eks-nodes-"
|
|
description = "Security group for EKS worker nodes"
|
|
vpc_id = var.vpc_id
|
|
|
|
ingress {
|
|
description = "Allow nodes to communicate with each other"
|
|
from_port = 0
|
|
to_port = 65535
|
|
protocol = "tcp"
|
|
self = true
|
|
}
|
|
|
|
ingress {
|
|
description = "Allow pods to communicate with the cluster API Server"
|
|
from_port = 443
|
|
to_port = 443
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.eks_cluster.id]
|
|
}
|
|
|
|
ingress {
|
|
description = "Allow ALB to reach pods"
|
|
from_port = 0
|
|
to_port = 65535
|
|
protocol = "tcp"
|
|
security_groups = [aws_security_group.alb.id]
|
|
}
|
|
|
|
egress {
|
|
description = "Allow all outbound"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-eks-nodes-sg"
|
|
}
|
|
)
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
# Allow EKS control plane to communicate with nodes
|
|
resource "aws_security_group_rule" "cluster_to_nodes" {
|
|
description = "Allow control plane to communicate with worker nodes"
|
|
from_port = 1025
|
|
to_port = 65535
|
|
protocol = "tcp"
|
|
security_group_id = aws_security_group.eks_nodes.id
|
|
source_security_group_id = aws_security_group.eks_cluster.id
|
|
type = "ingress"
|
|
}
|
|
|
|
# IAM Role for EC2 Code-Server instances
|
|
resource "aws_iam_role" "code_server_ec2" {
|
|
name = "${var.name_prefix}-code-server-ec2-role"
|
|
|
|
assume_role_policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = "sts:AssumeRole"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
Service = "ec2.amazonaws.com"
|
|
}
|
|
}
|
|
]
|
|
})
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# IAM Instance Profile for EC2
|
|
resource "aws_iam_instance_profile" "code_server_ec2" {
|
|
name = "${var.name_prefix}-code-server-ec2-profile"
|
|
role = aws_iam_role.code_server_ec2.name
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# Attach SSM policy for Systems Manager access
|
|
resource "aws_iam_role_policy_attachment" "code_server_ec2_ssm" {
|
|
role = aws_iam_role.code_server_ec2.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
|
|
}
|
|
|
|
# Attach CloudWatch policy for logging
|
|
resource "aws_iam_role_policy_attachment" "code_server_ec2_cloudwatch" {
|
|
role = aws_iam_role.code_server_ec2.name
|
|
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
|
|
}
|
|
|
|
# Custom policy for ECR access (to pull container images)
|
|
resource "aws_iam_role_policy" "code_server_ec2_ecr" {
|
|
name = "${var.name_prefix}-code-server-ec2-ecr-policy"
|
|
role = aws_iam_role.code_server_ec2.id
|
|
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Effect = "Allow"
|
|
Action = [
|
|
"ecr:GetAuthorizationToken",
|
|
"ecr:BatchCheckLayerAvailability",
|
|
"ecr:GetDownloadUrlForLayer",
|
|
"ecr:BatchGetImage"
|
|
]
|
|
Resource = "*"
|
|
}
|
|
]
|
|
})
|
|
}
|
|
|
|
# IAM Role for EKS Cluster
|
|
resource "aws_iam_role" "eks_cluster" {
|
|
name = "${var.name_prefix}-eks-cluster-role"
|
|
|
|
assume_role_policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = "sts:AssumeRole"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
Service = "eks.amazonaws.com"
|
|
}
|
|
}
|
|
]
|
|
})
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# Attach required policies for EKS cluster
|
|
resource "aws_iam_role_policy_attachment" "eks_cluster_policy" {
|
|
role = aws_iam_role.eks_cluster.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "eks_vpc_resource_controller" {
|
|
role = aws_iam_role.eks_cluster.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
|
|
}
|
|
|
|
# IAM Role for EKS Node Group
|
|
resource "aws_iam_role" "eks_nodes" {
|
|
name = "${var.name_prefix}-eks-nodes-role"
|
|
|
|
assume_role_policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = "sts:AssumeRole"
|
|
Effect = "Allow"
|
|
Principal = {
|
|
Service = "ec2.amazonaws.com"
|
|
}
|
|
}
|
|
]
|
|
})
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# Attach required policies for EKS nodes
|
|
resource "aws_iam_role_policy_attachment" "eks_worker_node_policy" {
|
|
role = aws_iam_role.eks_nodes.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "eks_cni_policy" {
|
|
role = aws_iam_role.eks_nodes.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "eks_container_registry_policy" {
|
|
role = aws_iam_role.eks_nodes.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "eks_ssm_policy" {
|
|
role = aws_iam_role.eks_nodes.name
|
|
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
|
|
}
|
|
|
|
# KMS Key for encryption at rest
|
|
resource "aws_kms_key" "code_server" {
|
|
description = "KMS key for Code-Server encryption"
|
|
deletion_window_in_days = 10
|
|
enable_key_rotation = true
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-kms-key"
|
|
}
|
|
)
|
|
}
|
|
|
|
resource "aws_kms_alias" "code_server" {
|
|
name = "alias/${var.name_prefix}-code-server"
|
|
target_key_id = aws_kms_key.code_server.key_id
|
|
}
|