Skip to content

Commit

Permalink
Add DNS records for environment (#23)
Browse files Browse the repository at this point in the history
Forward to API Gateway and use the DNS endpoint for tests.

I've weighted 100% to eu-west-1 for now because multi-region signatures aren't well supported yet (i.e. you need to know which region you're signing for) and all our traffic originates in eu-west-1, but we should really take a proper look at this for future reliability.

#minor
  • Loading branch information
gregtyler authored Oct 26, 2023
1 parent d28a9a7 commit c230418
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 11 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/env-destroy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,3 @@ jobs:
terraform workspace select default
terraform workspace delete ${{ inputs.workspace_name }}
working-directory: ./terraform/environment

- name: Destroy deployment environment
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/environments/${{ inputs.workspace_name }}
6 changes: 6 additions & 0 deletions terraform/account/apigateway.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
resource "aws_iam_role" "api_gateway_cloudwatch" {
name = "api-gateway-cloudwatch-global"
assume_role_policy = data.aws_iam_policy_document.api_gateway_assume_role.json

provider = aws.global
}

data "aws_iam_policy_document" "api_gateway_assume_role" {
Expand All @@ -12,9 +14,13 @@ data "aws_iam_policy_document" "api_gateway_assume_role" {
identifiers = ["apigateway.amazonaws.com"]
}
}

provider = aws.global
}

resource "aws_iam_role_policy_attachment" "api_gateway_log_to_cloudwatch" {
role = aws_iam_role.api_gateway_cloudwatch.id
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"

provider = aws.global
}
28 changes: 28 additions & 0 deletions terraform/account/region/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
locals {
domain_name = var.is_production ? data.aws_route53_zone.service.name : "*.${data.aws_route53_zone.service.name}"
}

data "aws_route53_zone" "service" {
name = "lpa-store.api.opg.service.justice.gov.uk"
provider = aws.management
}

resource "aws_acm_certificate" "environment" {
domain_name = local.domain_name
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}

provider = aws.region
}

resource "aws_route53_record" "validation" {
name = sort(aws_acm_certificate.environment.domain_validation_options[*].resource_record_name)[0]
type = sort(aws_acm_certificate.environment.domain_validation_options[*].resource_record_type)[0]
zone_id = data.aws_route53_zone.service.id
records = [sort(aws_acm_certificate.environment.domain_validation_options[*].resource_record_value)[0]]
ttl = 60
allow_overwrite = true
provider = aws.management
}
13 changes: 13 additions & 0 deletions terraform/account/region/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_version = ">= 1.4.0"

required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [
aws.region,
aws.management,
]
}
}
}
4 changes: 4 additions & 0 deletions terraform/account/region/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "is_production" {
description = "Whether this is a production environment"
type = bool
}
21 changes: 21 additions & 0 deletions terraform/account/regions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module "eu_west_1" {
source = "./region"

is_production = local.account.is_production

providers = {
aws.region = aws.eu_west_1
aws.management = aws.management_eu_west_1
}
}

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

is_production = local.account.is_production

providers = {
aws.region = aws.eu_west_2
aws.management = aws.management_eu_west_2
}
}
57 changes: 57 additions & 0 deletions terraform/account/terraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ terraform {
}

provider "aws" {
alias = "eu_west_1"
region = "eu-west-1"

assume_role {
Expand All @@ -29,3 +30,59 @@ provider "aws" {
tags = local.default_tags
}
}

provider "aws" {
alias = "eu_west_2"
region = "eu-west-2"

assume_role {
role_arn = "arn:aws:iam::${local.account.account_id}:role/${var.default_role}"
session_name = "terraform-session"
}

default_tags {
tags = local.default_tags
}
}

provider "aws" {
alias = "global"
region = "us-east-1"

assume_role {
role_arn = "arn:aws:iam::${local.account.account_id}:role/${var.default_role}"
session_name = "terraform-session"
}

default_tags {
tags = local.default_tags
}
}

provider "aws" {
alias = "management_eu_west_1"
region = "eu-west-1"

assume_role {
role_arn = "arn:aws:iam::311462405659:role/${var.management_role}"
session_name = "terraform-session"
}

default_tags {
tags = local.default_tags
}
}

provider "aws" {
alias = "management_eu_west_2"
region = "eu-west-2"

assume_role {
role_arn = "arn:aws:iam::311462405659:role/${var.management_role}"
session_name = "terraform-session"
}

default_tags {
tags = local.default_tags
}
}
6 changes: 6 additions & 0 deletions terraform/account/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ variable "default_role" {
type = string
default = "lpa-store-ci"
}

variable "management_role" {
description = "Role to assume in Management account"
type = string
default = "lpa-store-ci"
}
12 changes: 12 additions & 0 deletions terraform/environment/region/apigateway.tf
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,15 @@ resource "aws_lambda_permission" "api_gateway_invoke" {

provider = aws.region
}

resource "aws_api_gateway_base_path_mapping" "mapping" {
api_id = aws_api_gateway_rest_api.lpa_store.id
stage_name = aws_api_gateway_stage.current.stage_name
domain_name = aws_api_gateway_domain_name.lpa_store.domain_name

lifecycle {
create_before_destroy = true
}

provider = aws.region
}
45 changes: 45 additions & 0 deletions terraform/environment/region/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
locals {
a_record = terraform.workspace == "production" ? data.aws_route53_zone.service.name : var.environment_name
domain_name = terraform.workspace == "production" ? data.aws_route53_zone.service.name : "${local.a_record}.${data.aws_route53_zone.service.name}"
}

data "aws_route53_zone" "service" {
name = "lpa-store.api.opg.service.justice.gov.uk"
provider = aws.management
}

data "aws_acm_certificate" "root" {
domain = terraform.workspace == "production" ? data.aws_route53_zone.service.name : "*.${data.aws_route53_zone.service.name}"
provider = aws.region
}

resource "aws_route53_record" "environment_record" {
name = local.a_record
type = "A"
zone_id = data.aws_route53_zone.service.id
set_identifier = data.aws_region.current.name

weighted_routing_policy {
weight = var.dns_weighting
}

alias {
evaluate_target_health = true
name = aws_api_gateway_domain_name.lpa_store.regional_domain_name
zone_id = aws_api_gateway_domain_name.lpa_store.regional_zone_id
}

provider = aws.management
}

resource "aws_api_gateway_domain_name" "lpa_store" {
domain_name = local.domain_name
regional_certificate_arn = data.aws_acm_certificate.root.arn
security_policy = "TLS_1_2"

endpoint_configuration {
types = ["REGIONAL"]
}

provider = aws.region
}
2 changes: 1 addition & 1 deletion terraform/environment/region/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
output "base_url" {
value = aws_api_gateway_stage.current.invoke_url
value = "https://${local.domain_name}"
}
6 changes: 6 additions & 0 deletions terraform/environment/region/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ variable "allowed_arns" {
description = "List of external ARNs allowed to access the API Gateway"
type = list(string)
}

variable "dns_weighting" {
description = "What percentage of DNS traffic to send to this region"
type = number
default = 50
}
2 changes: 2 additions & 0 deletions terraform/environment/regions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module "eu_west_1" {
dynamodb_name = aws_dynamodb_table.deeds_table.name
environment_name = local.environment_name
allowed_arns = local.environment.allowed_arns
dns_weighting = 100

providers = {
aws.region = aws.eu_west_1
Expand All @@ -21,6 +22,7 @@ module "eu_west_2" {
dynamodb_name = aws_dynamodb_table.deeds_table.name
environment_name = local.environment_name
allowed_arns = local.environment.allowed_arns
dns_weighting = 0

providers = {
aws.region = aws.eu_west_2
Expand Down

0 comments on commit c230418

Please sign in to comment.