resource "aws_security_group" "instance" { name = "forgejo" description = "Forgejo git server" vpc_id = var.existing_vpc_id } resource "aws_vpc_security_group_ingress_rule" "instance_http_alb" { security_group_id = aws_security_group.instance.id referenced_security_group_id = aws_security_group.alb.id from_port = 3000 to_port = 3000 ip_protocol = "tcp" description = "HTTP from the Forgejo ALB" } resource "aws_vpc_security_group_ingress_rule" "instance_http_vpc" { security_group_id = aws_security_group.instance.id cidr_ipv4 = local.vpc_cidr from_port = 3000 to_port = 3000 ip_protocol = "tcp" description = "HTTP from the prod VPC" } resource "aws_vpc_security_group_ingress_rule" "instance_http_office" { security_group_id = aws_security_group.instance.id cidr_ipv4 = local.office_vpn_cidr from_port = 3000 to_port = 3000 ip_protocol = "tcp" description = "HTTP from the office VPN. 10.10 is not routed to 10.70 yet." } resource "aws_vpc_security_group_ingress_rule" "instance_ssh_vpc" { security_group_id = aws_security_group.instance.id cidr_ipv4 = local.vpc_cidr from_port = 2222 to_port = 2222 ip_protocol = "tcp" description = "Git SSH from the prod VPC" } resource "aws_vpc_security_group_ingress_rule" "instance_ssh_office" { security_group_id = aws_security_group.instance.id cidr_ipv4 = local.office_vpn_cidr from_port = 2222 to_port = 2222 ip_protocol = "tcp" description = "Git SSH from the office VPN. 10.10 is not routed to 10.70 yet." } resource "aws_vpc_security_group_egress_rule" "instance_all" { security_group_id = aws_security_group.instance.id cidr_ipv4 = "0.0.0.0/0" ip_protocol = "-1" description = "Outbound for GitHub, Codeberg, S3, and SSM" } resource "aws_instance" "forgejo" { ami = var.ami_id instance_type = "t4g.small" subnet_id = local.instance_subnet_id vpc_security_group_ids = [aws_security_group.instance.id] iam_instance_profile = aws_iam_instance_profile.forgejo.name associate_public_ip_address = true user_data = local.user_data user_data_replace_on_change = true metadata_options { http_endpoint = "enabled" http_tokens = "required" } root_block_device { volume_size = 20 volume_type = "gp3" encrypted = true delete_on_termination = true } tags = { Name = "forgejo" forgejo-backup = "true" } } resource "aws_ebs_volume" "data" { availability_zone = data.aws_subnet.instance.availability_zone size = 50 type = "gp3" encrypted = true tags = { Name = "forgejo-data" forgejo-backup = "true" } lifecycle { prevent_destroy = true } } resource "aws_volume_attachment" "data" { device_name = "/dev/xvdf" volume_id = aws_ebs_volume.data.id instance_id = aws_instance.forgejo.id stop_instance_before_detaching = true } resource "aws_ssm_parameter" "backup_prefix" { name = "/forgejo/backup-s3-prefix" description = "S3 key prefix for Forgejo backup dumps" type = "String" value = local.backup_s3_prefix } resource "aws_dlm_lifecycle_policy" "snapshots" { description = "Nightly EBS snapshots for Forgejo" execution_role_arn = aws_iam_role.dlm.arn state = "ENABLED" policy_details { resource_types = ["INSTANCE"] target_tags = { forgejo-backup = "true" } schedule { name = "forgejo-nightly" create_rule { interval = 24 interval_unit = "HOURS" times = ["06:00"] } retain_rule { count = 30 } copy_tags = true tags_to_add = { forgejo-backup = "true" } } } }