From ca99ba565a109a815360313d2585cb9560a7be96 Mon Sep 17 00:00:00 2001 From: Krisjanis Lejejs Date: Mon, 23 Sep 2024 18:04:57 +0300 Subject: [PATCH] Migrate to using service module, support multiple regions --- .modules/service/ecs.tf | 2 +- .modules/webservice/dns.tf | 4 +- infrastructure/main.tf | 14 +++++ infrastructure/outputs.tf | 20 +++++++ stun_server/ecs.tf | 87 ----------------------------- stun_server/main.tf | 28 +++++++++- stun_server/{ => region}/dns.tf | 4 +- stun_server/region/ecs.tf | 30 ++++++++++ stun_server/region/module.tf | 37 ++++++++++++ stun_server/{ => region}/network.tf | 2 +- stun_server/region/variables.tf | 19 +++++++ 11 files changed, 151 insertions(+), 96 deletions(-) delete mode 100644 stun_server/ecs.tf rename stun_server/{ => region}/dns.tf (59%) create mode 100644 stun_server/region/ecs.tf create mode 100644 stun_server/region/module.tf rename stun_server/{ => region}/network.tf (86%) create mode 100644 stun_server/region/variables.tf diff --git a/.modules/service/ecs.tf b/.modules/service/ecs.tf index d01de91..0ce4efe 100644 --- a/.modules/service/ecs.tf +++ b/.modules/service/ecs.tf @@ -56,4 +56,4 @@ resource "aws_ecs_task_definition" "task" { } }, var.container_definitions) ]) -} \ No newline at end of file +} diff --git a/.modules/webservice/dns.tf b/.modules/webservice/dns.tf index 2515168..77e9e63 100644 --- a/.modules/webservice/dns.tf +++ b/.modules/webservice/dns.tf @@ -5,8 +5,8 @@ data "cloudflare_zone" "dns_zone" { resource "cloudflare_record" "instance_dns" { zone_id = data.cloudflare_zone.dns_zone.id name = coalesce(var.subdomain, lower(var.service_name)) - value = lower(aws_alb.main.dns_name) + content = lower(aws_alb.main.dns_name) type = "CNAME" ttl = 1 proxied = var.cloudflare_proxy -} \ No newline at end of file +} diff --git a/infrastructure/main.tf b/infrastructure/main.tf index 46782cb..4c207e9 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -18,3 +18,17 @@ module "us_east_1" { ecs_policy = aws_iam_instance_profile.ecs_instance_profile.arn network_cidr = var.network_cidr["us-east-1"] } + +module "eu_central_1" { + source = "./region" + region = "eu-central-1" + ecs_policy = aws_iam_instance_profile.ecs_instance_profile.arn + network_cidr = var.network_cidr["eu-central-1"] +} + +module "ap_southeast_1" { + source = "./region" + region = "ap-southeast-1" + ecs_policy = aws_iam_instance_profile.ecs_instance_profile.arn + network_cidr = var.network_cidr["ap-southeast-1"] +} diff --git a/infrastructure/outputs.tf b/infrastructure/outputs.tf index e907ee1..be95563 100644 --- a/infrastructure/outputs.tf +++ b/infrastructure/outputs.tf @@ -12,3 +12,23 @@ output "us-east-1" { "network_id" : module.us_east_1.network_id, } } + +output "eu-central-1" { + description = "Outputs for the eu-central-1 region" + value = { + "public_subnets" : module.eu_central_1.public_subnets, + "private_subnets" : module.eu_central_1.private_subnets, + "ecs_cluster" : module.eu_central_1.ecs_cluster, + "network_id" : module.eu_central_1.network_id, + } +} + +output "ap-southeast-1" { + description = "Outputs for the ap-southeast-1 region" + value = { + "public_subnets" : module.ap_southeast_1.public_subnets, + "private_subnets" : module.ap_southeast_1.private_subnets, + "ecs_cluster" : module.ap_southeast_1.ecs_cluster, + "network_id" : module.ap_southeast_1.network_id, + } +} diff --git a/stun_server/ecs.tf b/stun_server/ecs.tf deleted file mode 100644 index fed0a29..0000000 --- a/stun_server/ecs.tf +++ /dev/null @@ -1,87 +0,0 @@ -resource "aws_ecs_service" "stun-server" { - name = "stun-server" - - cluster = data.tfe_outputs.infrastructure.values.ecs_cluster - task_definition = aws_ecs_task_definition.stun-server.arn - count = 1 - desired_count = 1 - - deployment_minimum_healthy_percent = 100 - deployment_maximum_percent = 200 - health_check_grace_period_seconds = 90 - launch_type = "FARGATE" - - # Required to fetch the public IP address of the ECS service - enable_ecs_managed_tags = true - wait_for_steady_state = true - - network_configuration { - assign_public_ip = true - security_groups = [aws_security_group.stun_sg.id] - subnets = [ - data.tfe_outputs.infrastructure.values.public_subnets[0], - data.tfe_outputs.infrastructure.values.public_subnets[1] - ] - } -} - -data "aws_network_interface" "stun_server_interface" { - filter { - name = "tag:aws:ecs:serviceName" - values = [aws_ecs_service.stun-server.name] - } -} - -resource "aws_cloudwatch_log_group" "aws_logs" { - name = "/ecs/stun-server" - retention_in_days = 14 -} - -resource "aws_ecs_task_definition" "stun-server" { - family = "stun-server" - - count = 1 - cpu = 2048 - memory = 4096 - - execution_role_arn = aws_iam_role.ecs_task_execution_role.arn - network_mode = "awsvpc" - requires_compatibilities = ["FARGATE"] - - runtime_platform { - operating_system_family = "LINUX" - cpu_architecture = "ARM64" - } - - container_definitions = jsonencode([ - { - name = "stun-server" - image = "ghcr.io/home-assistant/stun:${var.image_tag}" - cpu = 2048 - memory = 4096 - essential = true - - portMappings = [ - { - containerPort = 3478 - hostPort = 3478 - protocol = "tcp" - }, - { - containerPort = 3478 - hostPort = 3478 - protocol = "udp" - } - ], - - logConfiguration = { - logDriver = "awslogs" - options = { - "awslogs-group" = "/ecs/stun-server" - "awslogs-region" = "us-east-1" - "awslogs-stream-prefix" = "ecs" - } - } - } - ]) -} diff --git a/stun_server/main.tf b/stun_server/main.tf index 10ca2e3..4b8378e 100644 --- a/stun_server/main.tf +++ b/stun_server/main.tf @@ -12,7 +12,29 @@ provider "aws" { region = "us-east-1" } -data "tfe_outputs" "infrastructure" { - organization = "home_assistant" - workspace = "infrastructure" +module "us_east_1" { + source = "./region" + + region = "us-east-1" + domain_name = var.domain_name + subdomain = "stun-us" + image_tag = var.image_tag +} + +module "eu_central_1" { + source = "./region" + + region = "eu-central-1" + domain_name = var.domain_name + subdomain = "stun-eu" + image_tag = var.image_tag +} + +module "ap_southeast_1" { + source = "./region" + + region = "ap-southeast-1" + domain_name = var.domain_name + subdomain = "stun-ap" + image_tag = var.image_tag } diff --git a/stun_server/dns.tf b/stun_server/region/dns.tf similarity index 59% rename from stun_server/dns.tf rename to stun_server/region/dns.tf index 6527651..1a65dee 100644 --- a/stun_server/dns.tf +++ b/stun_server/region/dns.tf @@ -4,8 +4,8 @@ data "cloudflare_zone" "dns_zone" { resource "cloudflare_record" "instance_dns" { zone_id = data.cloudflare_zone.dns_zone.id - name = "" # TODO: Add the subdomain - content = data.aws_network_interface.stun_server_interface.association[0].public_ip + name = var.subdomain + content = module.stun_server.aws_network_interface.stun_server_interface.association[0].public_ip type = "A" proxied = true } diff --git a/stun_server/region/ecs.tf b/stun_server/region/ecs.tf new file mode 100644 index 0000000..321c0e4 --- /dev/null +++ b/stun_server/region/ecs.tf @@ -0,0 +1,30 @@ +resource "aws_ecs_service" "stun-server" { + name = local.service_name + cluster = data.tfe_outputs.infrastructure.values[var.region].ecs_cluster + task_definition = module.stun_server.task_definition + desired_count = 1 + deployment_minimum_healthy_percent = 100 + deployment_maximum_percent = 200 + health_check_grace_period_seconds = 90 + launch_type = local.launch_type + + # Required to fetch the public IP address of the ECS service + enable_ecs_managed_tags = true + wait_for_steady_state = true + + network_configuration { + assign_public_ip = true + security_groups = [aws_security_group.stun_sg.id] + subnets = [ + data.tfe_outputs.infrastructure.values.public_subnets[0], + data.tfe_outputs.infrastructure.values.public_subnets[1] + ] + } +} + +data "aws_network_interface" "stun_server_interface" { + filter { + name = "tag:aws:ecs:serviceName" + values = [aws_ecs_service.stun-server.name] + } +} diff --git a/stun_server/region/module.tf b/stun_server/region/module.tf new file mode 100644 index 0000000..d02d639 --- /dev/null +++ b/stun_server/region/module.tf @@ -0,0 +1,37 @@ +locals { + service_name = "stun-server" + launch_type = "FARGATE" +} + +data "tfe_outputs" "infrastructure" { + organization = "home_assistant" + workspace = "infrastructure" +} + +module "stun_server" { + source = "../../.modules/service" + + service_name = local.service_name + container_image = "ghcr.io/home-assistant/stun-server" + container_version = var.image_tag + launch_type = local.launch_type + region = var.region + ecs_cpu = 2048 + ecs_memory = 4096 + container_definitions = { + portMappings = [ + { + containerPort = 3478 + hostPort = 3478 + protocol = "tcp" + }, + { + containerPort = 3478 + hostPort = 3478 + protocol = "udp" + } + ], + } + webservice = true + rolling_updates = true +} diff --git a/stun_server/network.tf b/stun_server/region/network.tf similarity index 86% rename from stun_server/network.tf rename to stun_server/region/network.tf index 8bc9278..c7edf76 100644 --- a/stun_server/network.tf +++ b/stun_server/region/network.tf @@ -1,5 +1,5 @@ resource "aws_security_group" "stun_sg" { - vpc_id = data.tfe_outputs.infrastructure.values["us-east-1"].network_id + vpc_id = data.tfe_outputs.infrastructure.values[var.region].network_id egress { from_port = 0 diff --git a/stun_server/region/variables.tf b/stun_server/region/variables.tf new file mode 100644 index 0000000..5a74545 --- /dev/null +++ b/stun_server/region/variables.tf @@ -0,0 +1,19 @@ +variable "region" { + description = "The region to deploy the STUN server to" + type = string + +} + +variable "domain_name" { + description = "The base domain name" + type = string +} + +variable "subdomain" { + description = "The subdomain to use for the STUN server" + type = string +} +variable "image_tag" { + description = "Version of the Stun server to deploy" + type = string +}