Skip to content

Commit

Permalink
Add deployment configuration for Stun server (#87)
Browse files Browse the repository at this point in the history
* Add deployment configuration for Stun server

* Update stun_server/main.tf

Co-authored-by: Joakim Sørensen <[email protected]>

* Migrate to using service module, support multiple regions

* PR review fixes

* Add required Terraform version

* Started using AWS region variable, fixed missing AWS provider issue

* Fix image URL, make subdomain be constructed from region

* TF config fixes

* Add region tag to resources

* Code improvements based on PR suggestions

* Change stun server IP output key

* More PR improvements

* Upgrade AWS provider version

* Add dependencies between ECS service, network interface filter and Cloudflare DNS

---------

Co-authored-by: Joakim Sørensen <[email protected]>
  • Loading branch information
klejejs and ludeeus authored Sep 27, 2024
1 parent 4485ecf commit 1b9d95a
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 0 deletions.
37 changes: 37 additions & 0 deletions stun_server/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
terraform {
cloud {
organization = "home_assistant"

workspaces {
name = "stun_server"
}
}
}

provider "aws" {
region = "us-east-1"
}

module "us_east_1" {
source = "./region"

region = "us-east-1"
domain_name = var.domain_name
image_tag = var.image_tag
}

module "eu_central_1" {
source = "./region"

region = "eu-central-1"
domain_name = var.domain_name
image_tag = var.image_tag
}

module "ap_southeast_1" {
source = "./region"

region = "ap-southeast-1"
domain_name = var.domain_name
image_tag = var.image_tag
}
8 changes: 8 additions & 0 deletions stun_server/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "ip" {
description = "The public IP address of the stun server"
value = {
"us-east-1" = module.us_east_1.stun_server_ip
"eu-central-1" = module.eu_central_1.stun_server_ip
"ap-southeast-1" = module.ap_southeast_1.stun_server_ip
}
}
12 changes: 12 additions & 0 deletions stun_server/region/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
data "cloudflare_zone" "dns_zone" {
name = var.domain_name
}

resource "cloudflare_record" "instance_dns" {
zone_id = data.cloudflare_zone.dns_zone.id
name = join("-", ["stun", data.aws_region.current.name])
content = data.aws_network_interface.stun_server_interface.association[0].public_ip
type = "A"
proxied = true
depends_on = [data.aws_network_interface.stun_server_interface]
}
32 changes: 32 additions & 0 deletions stun_server/region/ecs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resource "aws_ecs_service" "stun-server" {
name = local.service_name
cluster = local.infrastructure_region_outputs.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 = "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 = local.infrastructure_region_outputs.public_subnets
}

tags = {
region = data.aws_region.current.name
}
}

data "aws_network_interface" "stun_server_interface" {
filter {
name = "tag:aws:ecs:serviceName"
values = [aws_ecs_service.stun-server.name]
}
depends_on = [aws_ecs_service.stun-server]
}
41 changes: 41 additions & 0 deletions stun_server/region/module.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
locals {
service_name = "stun-server"
infrastructure_region_outputs = data.tfe_outputs.infrastructure.values[data.aws_region.current.name]
}

provider "aws" {
region = var.region
}

data "tfe_outputs" "infrastructure" {
organization = "home_assistant"
workspace = "infrastructure"
}

data "aws_region" "current" {}

module "stun_server" {
source = "../../.modules/service"

service_name = local.service_name
container_image = "ghcr.io/home-assistant/stun"
container_version = var.image_tag
region = data.aws_region.current.name
ecs_cpu = 512
ecs_memory = 1024
container_definitions = {
portMappings = [
{
containerPort = 3478
hostPort = 3478
protocol = "tcp"
},
{
containerPort = 3478
hostPort = 3478
protocol = "udp"
}
],
}
webservice = true
}
30 changes: 30 additions & 0 deletions stun_server/region/network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
resource "aws_security_group" "stun_sg" {
vpc_id = local.infrastructure_region_outputs.network_id

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow STUN traffic TCP"
from_port = 3478
to_port = 3478
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow STUN traffic UDF"
from_port = 3478
to_port = 3478
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
region = data.aws_region.current.name
}
}
4 changes: 4 additions & 0 deletions stun_server/region/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "stun_server_ip" {
description = "The public IP address of the stun server"
value = data.aws_network_interface.stun_server_interface.association[0].public_ip
}
14 changes: 14 additions & 0 deletions stun_server/region/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "region" {
description = "The region to deploy the STUN server to"
type = string
}

variable "domain_name" {
description = "The base domain name"
type = string
}

variable "image_tag" {
description = "Version of the Stun server to deploy"
type = string
}
19 changes: 19 additions & 0 deletions stun_server/region/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terraform {

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}

tfe = {
source = "hashicorp/tfe"
version = "~> 0.58.0"
}

cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
9 changes: 9 additions & 0 deletions stun_server/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "domain_name" {
description = "The base domain name"
type = string
}

variable "image_tag" {
description = "Version of the Stun server to deploy"
type = string
}
10 changes: 10 additions & 0 deletions stun_server/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = "= 1.9.6"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

0 comments on commit 1b9d95a

Please sign in to comment.