mirror of
https://github.com/cdr/code-server.git
synced 2025-12-07 08:52:16 +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
346 lines
8.9 KiB
HCL
346 lines
8.9 KiB
HCL
# EC2 Module for Code-Server Deployment
|
|
# Deploys code-server on EC2 instances with Auto Scaling, ALB, and OAuth2 Proxy
|
|
|
|
# Get latest Amazon Linux 2023 AMI
|
|
data "aws_ami" "amazon_linux" {
|
|
most_recent = true
|
|
owners = ["amazon"]
|
|
|
|
filter {
|
|
name = "name"
|
|
values = ["al2023-ami-*-x86_64"]
|
|
}
|
|
|
|
filter {
|
|
name = "virtualization-type"
|
|
values = ["hvm"]
|
|
}
|
|
}
|
|
|
|
# Generate random password for code-server if not provided
|
|
resource "random_password" "code_server" {
|
|
count = var.code_server_password == "" ? 1 : 0
|
|
length = 32
|
|
special = true
|
|
}
|
|
|
|
# Store password in AWS Secrets Manager
|
|
resource "aws_secretsmanager_secret" "code_server_password" {
|
|
name = "${var.name_prefix}-code-server-password"
|
|
description = "Code-Server password"
|
|
recovery_window_in_days = 7
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_secretsmanager_secret_version" "code_server_password" {
|
|
secret_id = aws_secretsmanager_secret.code_server_password.id
|
|
secret_string = var.code_server_password != "" ? var.code_server_password : random_password.code_server[0].result
|
|
}
|
|
|
|
# User data script for EC2 instances
|
|
locals {
|
|
user_data = templatefile("${path.module}/user-data.sh", {
|
|
code_server_version = var.code_server_version
|
|
region = var.aws_region
|
|
secret_name = aws_secretsmanager_secret.code_server_password.name
|
|
oauth2_client_id = var.oauth2_client_id
|
|
oauth2_client_secret = var.oauth2_client_secret
|
|
oauth2_issuer_url = var.oauth2_issuer_url
|
|
oauth2_redirect_url = var.oauth2_redirect_url
|
|
cookie_secret = var.oauth2_cookie_secret
|
|
allowed_emails = join(",", var.oauth2_allowed_emails)
|
|
})
|
|
}
|
|
|
|
# Launch Template
|
|
resource "aws_launch_template" "code_server" {
|
|
name_prefix = "${var.name_prefix}-code-server-"
|
|
image_id = var.ami_id != "" ? var.ami_id : data.aws_ami.amazon_linux.id
|
|
instance_type = var.instance_type
|
|
|
|
iam_instance_profile {
|
|
name = var.iam_instance_profile_name
|
|
}
|
|
|
|
vpc_security_group_ids = [var.security_group_id]
|
|
|
|
user_data = base64encode(local.user_data)
|
|
|
|
block_device_mappings {
|
|
device_name = "/dev/xvda"
|
|
|
|
ebs {
|
|
volume_size = var.ebs_volume_size
|
|
volume_type = var.ebs_volume_type
|
|
encrypted = true
|
|
kms_key_id = var.kms_key_arn
|
|
delete_on_termination = true
|
|
}
|
|
}
|
|
|
|
metadata_options {
|
|
http_endpoint = "enabled"
|
|
http_tokens = "required"
|
|
http_put_response_hop_limit = 1
|
|
instance_metadata_tags = "enabled"
|
|
}
|
|
|
|
monitoring {
|
|
enabled = true
|
|
}
|
|
|
|
tag_specifications {
|
|
resource_type = "instance"
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-code-server"
|
|
}
|
|
)
|
|
}
|
|
|
|
tag_specifications {
|
|
resource_type = "volume"
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-code-server-volume"
|
|
}
|
|
)
|
|
}
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# Auto Scaling Group
|
|
resource "aws_autoscaling_group" "code_server" {
|
|
name = "${var.name_prefix}-code-server-asg"
|
|
vpc_zone_identifier = var.subnet_ids
|
|
target_group_arns = [aws_lb_target_group.code_server.arn, aws_lb_target_group.oauth2_proxy.arn]
|
|
health_check_type = "ELB"
|
|
health_check_grace_period = 300
|
|
min_size = var.min_instances
|
|
max_size = var.max_instances
|
|
desired_capacity = var.desired_instances
|
|
|
|
launch_template {
|
|
id = aws_launch_template.code_server.id
|
|
version = "$Latest"
|
|
}
|
|
|
|
tag {
|
|
key = "Name"
|
|
value = "${var.name_prefix}-code-server"
|
|
propagate_at_launch = true
|
|
}
|
|
|
|
dynamic "tag" {
|
|
for_each = var.tags
|
|
content {
|
|
key = tag.key
|
|
value = tag.value
|
|
propagate_at_launch = true
|
|
}
|
|
}
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
ignore_changes = [desired_capacity]
|
|
}
|
|
}
|
|
|
|
# Application Load Balancer
|
|
resource "aws_lb" "code_server" {
|
|
name = "${var.name_prefix}-code-server-alb"
|
|
internal = var.internal_alb
|
|
load_balancer_type = "application"
|
|
security_groups = [var.alb_security_group_id]
|
|
subnets = var.alb_subnet_ids
|
|
|
|
enable_deletion_protection = var.enable_deletion_protection
|
|
enable_http2 = true
|
|
enable_cross_zone_load_balancing = true
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-code-server-alb"
|
|
}
|
|
)
|
|
}
|
|
|
|
# Target Group for OAuth2 Proxy
|
|
resource "aws_lb_target_group" "oauth2_proxy" {
|
|
name = "${var.name_prefix}-oauth2-tg"
|
|
port = 4180
|
|
protocol = "HTTP"
|
|
vpc_id = var.vpc_id
|
|
|
|
health_check {
|
|
enabled = true
|
|
healthy_threshold = 2
|
|
unhealthy_threshold = 2
|
|
timeout = 5
|
|
interval = 30
|
|
path = "/ping"
|
|
matcher = "200"
|
|
}
|
|
|
|
deregistration_delay = 30
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-oauth2-tg"
|
|
}
|
|
)
|
|
}
|
|
|
|
# Target Group for Code-Server
|
|
resource "aws_lb_target_group" "code_server" {
|
|
name = "${var.name_prefix}-code-server-tg"
|
|
port = 8080
|
|
protocol = "HTTP"
|
|
vpc_id = var.vpc_id
|
|
|
|
health_check {
|
|
enabled = true
|
|
healthy_threshold = 2
|
|
unhealthy_threshold = 2
|
|
timeout = 5
|
|
interval = 30
|
|
path = "/healthz"
|
|
matcher = "200"
|
|
}
|
|
|
|
deregistration_delay = 30
|
|
|
|
stickiness {
|
|
type = "lb_cookie"
|
|
cookie_duration = 86400
|
|
enabled = true
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-code-server-tg"
|
|
}
|
|
)
|
|
}
|
|
|
|
# HTTPS Listener (primary)
|
|
resource "aws_lb_listener" "https" {
|
|
count = var.certificate_arn != "" ? 1 : 0
|
|
load_balancer_arn = aws_lb.code_server.arn
|
|
port = "443"
|
|
protocol = "HTTPS"
|
|
ssl_policy = "ELBSecurityPolicy-TLS-1-2-2017-01"
|
|
certificate_arn = var.certificate_arn
|
|
|
|
default_action {
|
|
type = "forward"
|
|
target_group_arn = aws_lb_target_group.oauth2_proxy.arn
|
|
}
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# HTTP Listener (redirect to HTTPS)
|
|
resource "aws_lb_listener" "http" {
|
|
load_balancer_arn = aws_lb.code_server.arn
|
|
port = "80"
|
|
protocol = "HTTP"
|
|
|
|
default_action {
|
|
type = var.certificate_arn != "" ? "redirect" : "forward"
|
|
|
|
dynamic "redirect" {
|
|
for_each = var.certificate_arn != "" ? [1] : []
|
|
content {
|
|
port = "443"
|
|
protocol = "HTTPS"
|
|
status_code = "HTTP_301"
|
|
}
|
|
}
|
|
|
|
target_group_arn = var.certificate_arn == "" ? aws_lb_target_group.oauth2_proxy.arn : null
|
|
}
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# CloudWatch Log Group for Code-Server
|
|
resource "aws_cloudwatch_log_group" "code_server" {
|
|
name = "/aws/ec2/${var.name_prefix}-code-server"
|
|
retention_in_days = var.log_retention_days
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
# Auto Scaling Policies
|
|
resource "aws_autoscaling_policy" "scale_up" {
|
|
count = var.enable_autoscaling ? 1 : 0
|
|
name = "${var.name_prefix}-code-server-scale-up"
|
|
autoscaling_group_name = aws_autoscaling_group.code_server.name
|
|
adjustment_type = "ChangeInCapacity"
|
|
scaling_adjustment = 1
|
|
cooldown = 300
|
|
}
|
|
|
|
resource "aws_autoscaling_policy" "scale_down" {
|
|
count = var.enable_autoscaling ? 1 : 0
|
|
name = "${var.name_prefix}-code-server-scale-down"
|
|
autoscaling_group_name = aws_autoscaling_group.code_server.name
|
|
adjustment_type = "ChangeInCapacity"
|
|
scaling_adjustment = -1
|
|
cooldown = 300
|
|
}
|
|
|
|
# CloudWatch Alarms for Auto Scaling
|
|
resource "aws_cloudwatch_metric_alarm" "cpu_high" {
|
|
count = var.enable_autoscaling ? 1 : 0
|
|
alarm_name = "${var.name_prefix}-code-server-cpu-high"
|
|
comparison_operator = "GreaterThanThreshold"
|
|
evaluation_periods = "2"
|
|
metric_name = "CPUUtilization"
|
|
namespace = "AWS/EC2"
|
|
period = "300"
|
|
statistic = "Average"
|
|
threshold = "80"
|
|
|
|
dimensions = {
|
|
AutoScalingGroupName = aws_autoscaling_group.code_server.name
|
|
}
|
|
|
|
alarm_description = "This metric monitors ec2 cpu utilization"
|
|
alarm_actions = [aws_autoscaling_policy.scale_up[0].arn]
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_cloudwatch_metric_alarm" "cpu_low" {
|
|
count = var.enable_autoscaling ? 1 : 0
|
|
alarm_name = "${var.name_prefix}-code-server-cpu-low"
|
|
comparison_operator = "LessThanThreshold"
|
|
evaluation_periods = "2"
|
|
metric_name = "CPUUtilization"
|
|
namespace = "AWS/EC2"
|
|
period = "300"
|
|
statistic = "Average"
|
|
threshold = "20"
|
|
|
|
dimensions = {
|
|
AutoScalingGroupName = aws_autoscaling_group.code_server.name
|
|
}
|
|
|
|
alarm_description = "This metric monitors ec2 cpu utilization"
|
|
alarm_actions = [aws_autoscaling_policy.scale_down[0].arn]
|
|
|
|
tags = var.tags
|
|
}
|