# 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 }