diff --git a/tf/modules/nginx_reverseproxy/main.tf b/tf/modules/nginx_reverseproxy/main.tf new file mode 100644 index 00000000..2dcdfeeb --- /dev/null +++ b/tf/modules/nginx_reverseproxy/main.tf @@ -0,0 +1,110 @@ +data "aws_ssm_parameter" "ubuntu_22_ami" { + name = "/aws/service/canonical/ubuntu/server/22.04/stable/current/amd64/hvm/ebs-gp2/ami-id" +} + +# Important note about security groups: +# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group#recreating-a-security-group +resource "aws_security_group" "nginx" { + description = "security group for nginx" + + vpc_id = var.vpc_id + + ingress { + protocol = "tcp" + from_port = 80 + to_port = 80 + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + protocol = "tcp" + from_port = 22 + to_port = 22 + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + + cidr_blocks = [ + "0.0.0.0/0", + ] + } + + tags = var.tags +} + +resource "aws_launch_template" "nginx" { + name_prefix = "${var.name}-nginx-tmpl-" + image_id = data.aws_ssm_parameter.ubuntu_22_ami.value + instance_type = var.instance_type + key_name = var.key_name + + user_data = base64encode(templatefile("${path.module}/templates/setup-reverse-proxy.sh", { + proxy_pass_url = var.proxy_pass_url, + extra_path_config = var.nginx_extra_path_config, + extra_nginx_config = var.nginx_extra_nginx_config, + })) + + lifecycle { + create_before_destroy = true + } + + network_interfaces { + delete_on_termination = true + associate_public_ip_address = true + security_groups = [ + aws_security_group.nginx.id, + ] + } + + tag_specifications { + resource_type = "instance" + tags = var.tags + } +} + +resource "aws_autoscaling_group" "nginx" { + launch_template { + id = aws_launch_template.nginx.id + version = "$Latest" + } + + lifecycle { + create_before_destroy = true + } + + name_prefix = "${var.name}-asg-" + + min_size = 1 + max_size = 2 + desired_capacity = 1 + vpc_zone_identifier = var.subnet_ids + + instance_refresh { + strategy = "Rolling" + preferences { + min_healthy_percentage = 50 + } + } +} + +resource "aws_alb_target_group" "nginx" { + name = var.name + port = 80 + protocol = "HTTP" + vpc_id = var.vpc_id + + lifecycle { + create_before_destroy = true + } + + tags = var.tags +} + +resource "aws_autoscaling_attachment" "nginx" { + autoscaling_group_name = aws_autoscaling_group.nginx.id + lb_target_group_arn = aws_alb_target_group.nginx.arn +} diff --git a/tf/modules/nginx_reverseproxy/outputs.tf b/tf/modules/nginx_reverseproxy/outputs.tf new file mode 100644 index 00000000..aac0d3e1 --- /dev/null +++ b/tf/modules/nginx_reverseproxy/outputs.tf @@ -0,0 +1,6 @@ +output "autoscaling_group_id" { + value = aws_autoscaling_group.nginx.id +} +output "alb_target_group_id" { + value = aws_alb_target_group.nginx.id +} diff --git a/tf/modules/nginx_reverseproxy/templates/setup-reverse-proxy.sh b/tf/modules/nginx_reverseproxy/templates/setup-reverse-proxy.sh new file mode 100644 index 00000000..18e10d15 --- /dev/null +++ b/tf/modules/nginx_reverseproxy/templates/setup-reverse-proxy.sh @@ -0,0 +1,70 @@ +#!/bin/bash +set -e + +sudo apt update +sudo apt install -y nginx + +tmpfile=$(mktemp /tmp/nginx-config.XXXXXX) +cat > $tmpfile < $tmpfile <\\d+\\.\\d+\.\\d+)\. \$ip.0; + ~(?P[^:]+:[^:]+): \$ip::; + default 0.0.0.0; + } + + # log anonymized ipaddr and caching status + log_format ooni_nginx_fmt '\$remote_addr_anon \$upstream_cache_status [\$time_local] ' + '"\$request" \$status \$body_bytes_sent "\$http_referer" "\$http_user_agent"'; + + ${extra_nginx_config} + + access_log syslog:server=unix:/dev/log ooni_nginx_fmt; + error_log syslog:server=unix:/dev/log; + + gzip on; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} +EOF +sudo mv $tmpfile /etc/nginx/nginx.conf + +sudo mkdir -p /var/cache/nginx +sudo chown -R www-data /var/cache/nginx + +sudo nginx -t +sudo systemctl reload nginx diff --git a/tf/modules/nginx_reverseproxy/variables.tf b/tf/modules/nginx_reverseproxy/variables.tf new file mode 100644 index 00000000..8fbf6f62 --- /dev/null +++ b/tf/modules/nginx_reverseproxy/variables.tf @@ -0,0 +1,40 @@ +variable "vpc_id" { + description = "the id of the VPC to deploy the instance into" +} + +variable "subnet_ids" { + description = "the ids of the subnet of the subnets to deploy the instance into" +} + +variable "tags" { + description = "tags to apply to the resources" + default = {} + type = map(string) +} + +variable "key_name" { + description = "Name of AWS key pair" +} + +variable "name" { + description = "Name of the resources" + default = "ooni-backendproxy" +} + +variable "instance_type" { + default = "t2.micro" +} + + +variable "proxy_pass_url" { + description = "URL to pass to the proxy_pass directive" +} + +variable "nginx_extra_nginx_config" { + description = "extra configuration to pass to nginx" + default = "" +} +variable "nginx_extra_path_config" { + description = "extra configuration to pass to nginx" + default = "" +} diff --git a/tf/modules/oonith_service/main.tf b/tf/modules/oonith_service/main.tf index 681016a3..497e1ce6 100644 --- a/tf/modules/oonith_service/main.tf +++ b/tf/modules/oonith_service/main.tf @@ -7,6 +7,7 @@ locals { short_prefix = "oo${substr(var.service_name, 0, 3)}" } + resource "aws_iam_role" "oonith_service_task" { name = "${local.name}-task-role" @@ -188,7 +189,7 @@ resource "aws_alb_target_group" "oonith_service_direct" { # } resource "aws_alb" "oonith_service" { - name = local.name + name_prefix = "ooth" subnets = var.public_subnet_ids security_groups = var.oonith_service_security_groups @@ -208,15 +209,64 @@ resource "aws_alb_listener" "oonith_service_http" { tags = var.tags } +module "oonith_nginx_cache" { + source = "../nginx_reverseproxy" + + vpc_id = var.vpc_id + subnet_ids = var.public_subnet_ids + key_name = var.key_name + instance_type = "t2.micro" + tags = var.tags + + name = "oonith-nginx-cache" + proxy_pass_url = "http://${aws_alb.oonith_service.dns_name}/" + nginx_extra_path_config = <