Skip to content

Commit

Permalink
Switch from nginx docker proxy to ALB
Browse files Browse the repository at this point in the history
We used to handle load balancing using
https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion. This
broke and proved hard to fix. After trying Caddy, I gave up and switched
to an AWS Application Load Balancer and the AWS Certificate Manager, at
the cost of adding some ridiculously baroque setup.

I need to go back and comment some of this, but for now, I need sleep.
  • Loading branch information
emk committed Oct 28, 2018
1 parent 7279eb5 commit 7ed50e4
Show file tree
Hide file tree
Showing 15 changed files with 207 additions and 215 deletions.
19 changes: 11 additions & 8 deletions dns.tf
Expand Up @@ -11,21 +11,25 @@ resource "aws_route53_record" "forum" {
zone_id = "${aws_route53_zone.primary.zone_id}"
name = "forum"
type = "A"
ttl = "300"

# Get the IP address of our server's Elastic IP.
records = ["${module.language_learners_server.public_ip}"]
alias {
name = "${aws_lb.web_sites.dns_name}"
zone_id = "${aws_lb.web_sites.zone_id}"
evaluate_target_health = false
}
}

# Our "super-challenge" record.
resource "aws_route53_record" "super_challenge" {
zone_id = "${aws_route53_zone.primary.zone_id}"
name = "super-challenge"
type = "A"
ttl = "300"

# Get the IP address of our server's Elastic IP.
records = ["${module.language_learners_server.public_ip}"]
alias {
name = "${aws_lb.web_sites.dns_name}"
zone_id = "${aws_lb.web_sites.zone_id}"
evaluate_target_health = false
}
}

# An "old-forum" record while we're migrating.
Expand All @@ -37,8 +41,7 @@ resource "aws_route53_record" "old-forum" {
records = ["34.204.9.245"]
}

# Our "www" record, still pointing to the old setup, but we'll update this
# soon to point to a Jekyll-based blog.
# Our "www" record, pointing to a blog hosted on GitHub Pages.
resource "aws_route53_record" "www" {
zone_id = "${aws_route53_zone.primary.zone_id}"
name = "www"
Expand Down
1 change: 1 addition & 0 deletions github_ecs_pipeline/build.tf
Expand Up @@ -14,6 +14,7 @@ resource "aws_codebuild_project" "build" {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/docker:1.12.1"
type = "LINUX_CONTAINER"
privileged_mode = true

environment_variable {
"name" = "IMAGE_REPO_NAME"
Expand Down
14 changes: 14 additions & 0 deletions github_ecs_pipeline/ecs.tf
Expand Up @@ -36,4 +36,18 @@ resource "aws_ecs_service" "service" {
# version.
deployment_maximum_percent = 100
deployment_minimum_healthy_percent = 0

# Allow our ECS to talk to our load balancer on behalf of our service.
iam_role = "arn:aws:iam::771600087445:role/ecsServiceRole"

# Hook this up to our load balancer so we get web traffic.
load_balancer {
target_group_arn = "${aws_lb_target_group.target_group.arn}"
container_name = "${var.name}"
container_port = 80
}

# Don't try to create this until our ALB listener actually has a validated
# certificate assigned.
depends_on = ["aws_lb_listener_certificate.cert"]
}
52 changes: 52 additions & 0 deletions github_ecs_pipeline/load_balancing.tf
@@ -0,0 +1,52 @@
# Register this container with our AWS "application load balancer", which can
# serve multiple domains with certificates.

resource "aws_lb_target_group" "target_group" {
name = "${var.name}"
port = 80
protocol = "HTTP"
vpc_id = "vpc-5abfab3c"
}

resource "aws_lb_listener_rule" "proxy" {
listener_arn = "${var.listener_arn}"
priority = "${var.listener_rule_priority}"

action {
type = "forward"
target_group_arn = "${aws_lb_target_group.target_group.arn}"
}

condition {
field = "host-header"
values = ["${var.host}"]
}
}

resource "aws_acm_certificate" "cert" {
domain_name = "${var.host}"
validation_method = "DNS"

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "cert_validation" {
name = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
type = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
zone_id = "${var.zone_id}"
records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
ttl = 60
}

resource "aws_acm_certificate_validation" "cert" {
certificate_arn = "${aws_acm_certificate.cert.arn}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}

resource "aws_lb_listener_certificate" "cert" {
listener_arn = "${var.listener_arn}"
certificate_arn = "${aws_acm_certificate_validation.cert.certificate_arn}"
}

16 changes: 16 additions & 0 deletions github_ecs_pipeline/variables.tf
Expand Up @@ -4,6 +4,10 @@ variable "name" {
description = "The name of the pipeline, and the image it builds."
}

variable "host" {
description = "The hostname to use for this service."
}

variable "github_repo" {
description = "The name of the GitHub repository we build."
}
Expand Down Expand Up @@ -45,6 +49,18 @@ variable "taskdef_revision" {
description = "The revision of the taskdef that we defined using Terraform. Usually overriden by deployment pipelines."
}

variable "zone_id" {
description = "The DNS zone ID to use for HTTPS certificate confirmation."
}

variable "listener_arn" {
description = "The HTTPS listener associated with our load balancer."
}

variable "listener_rule_priority" {
description = "The priority for the listener rule on our load balancer. Must be unique."
}

variable "notification_topic_arn" {
description = "The ARN of an SNS notification topic that will receive messages when something interesting happens."
}
77 changes: 77 additions & 0 deletions load_balancer.tf
@@ -0,0 +1,77 @@
resource "aws_lb" "web_sites" {
name = "web-sites"
internal = false
load_balancer_type = "application"
security_groups = ["${aws_security_group.load_balancer.id}"]
subnets = ["subnet-011dc549", "subnet-0f045d6a"]
}

resource "aws_lb_listener" "web_sites_https" {
load_balancer_arn = "${aws_lb.web_sites.arn}"
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2015-05"
certificate_arn = "${aws_acm_certificate_validation.language_learners.certificate_arn}"

default_action {
type = "redirect"
redirect {
host = "forum.language-learners.org"
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}

# An AWS security group describing the firewall rules for a load balancer.
resource "aws_security_group" "load_balancer" {
name = "load-balancer"
description = "Allow HTTP and HTTPS traffic."

# Allow inbound HTTP traffic.
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

# Allow inbound HTTPS traffic.
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

# Allow all outbound traffic.
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_acm_certificate" "language_learners" {
domain_name = "language-learners.org"
validation_method = "DNS"

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "language_learners_validation" {
name = "${aws_acm_certificate.language_learners.domain_validation_options.0.resource_record_name}"
type = "${aws_acm_certificate.language_learners.domain_validation_options.0.resource_record_type}"
zone_id = "${aws_route53_zone.primary.zone_id}"
records = ["${aws_acm_certificate.language_learners.domain_validation_options.0.resource_record_value}"]
ttl = 60
}

resource "aws_acm_certificate_validation" "language_learners" {
certificate_arn = "${aws_acm_certificate.language_learners.arn}"
validation_record_fqdns = ["${aws_route53_record.language_learners_validation.fqdn}"]
}
91 changes: 0 additions & 91 deletions nginx-proxy-container-definitions.json

This file was deleted.

69 changes: 0 additions & 69 deletions nginx_proxy.tf

This file was deleted.

0 comments on commit 7ed50e4

Please sign in to comment.