Skip to content

Commit

Permalink
UML-3108 Two region environment (#2486)
Browse files Browse the repository at this point in the history
* UML-3108 Enable option for two regions in environment Terraform
  • Loading branch information
Sam Ainsworth authored Jan 12, 2024
1 parent ad36f84 commit 5f13664
Show file tree
Hide file tree
Showing 26 changed files with 231 additions and 122 deletions.
6 changes: 4 additions & 2 deletions scripts/pipeline/ci_ingress/ci_ingress.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ class IngressManager:
aws_account_id = ''
aws_iam_session = ''
aws_ec2_client = ''
aws_region = ''
security_groups = []

def __init__(self, config_file):
self.read_parameters_from_file(config_file)
self.set_iam_role_session()
self.aws_ec2_client = boto3.client(
'ec2',
region_name='eu-west-1',
region_name=self.aws_region,
aws_access_key_id=self.aws_iam_session['Credentials']['AccessKeyId'],
aws_secret_access_key=self.aws_iam_session['Credentials']['SecretAccessKey'],
aws_session_token=self.aws_iam_session['Credentials']['SessionToken'])
Expand All @@ -25,6 +26,7 @@ def read_parameters_from_file(self, config_file):
with open(config_file) as json_file:
parameters = json.load(json_file)
self.aws_account_id = parameters['account_id']
self.aws_region = parameters['active_region']
self.security_groups = [
parameters['viewer_load_balancer_security_group_name'],
parameters['actor_load_balancer_security_group_name']]
Expand All @@ -39,7 +41,7 @@ def set_iam_role_session(self):

sts = boto3.client(
'sts',
region_name='eu-west-1',
region_name=self.aws_region,
)
session = sts.assume_role(
RoleArn=role_arn,
Expand Down
3 changes: 3 additions & 0 deletions service-api/app/config/autoload/envs.global.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
'region' => getenv('AWS_REGION') ?: 'eu-west-1',
'version' => 'latest',

'ApiGateway' => [
'endpoint_region' => getenv('API_GATEWAY_REGION') ?: 'eu-west-1',
],
'DynamoDb' => [
'endpoint' => getenv('AWS_ENDPOINT_DYNAMODB') ?: null,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@ private function buildHeaders(): array

return $headerLines;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __invoke(ContainerInterface $container): RequestSigner

$token = $config['codes_api']['static_auth_token'] ?? null;

$aws_region = $config['aws']['region'] ?? 'eu-west-1';
$aws_region = $config['aws']['ApiGateway']['endpoint_region'] ?? 'eu-west-1';

return new RequestSigner(new SignatureV4('execute-api', $aws_region), $token);
}
Expand Down
4 changes: 2 additions & 2 deletions terraform/environment/cognito_client.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ resource "aws_cognito_user_pool_client" "use_a_lasting_power_of_attorney_admin"
read_attributes = []
write_attributes = []

callback_urls = ["https://${module.eu_west_1.route53_fqdns.admin}/oauth2/idpresponse"]
logout_urls = ["https://${module.eu_west_1.route53_fqdns.admin}/"]
callback_urls = ["https://${module.eu_west_1[0].route53_fqdns.admin}/oauth2/idpresponse"]
logout_urls = ["https://${module.eu_west_1[0].route53_fqdns.admin}/"]
}

moved {
Expand Down
23 changes: 13 additions & 10 deletions terraform/environment/config_file.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ resource "local_file" "cluster_config" {
}

locals {

active_region = [for k, v in local.environment.regions : k if v["is_active"] == true][0]

cluster_config = {
actor_users_table = aws_dynamodb_table.actor_users_table.name
cluster_name = module.eu_west_1.ecs_cluster.name
cluster_name = local.active_region == "eu-west-1" ? module.eu_west_1[0].ecs_cluster.name : module.eu_west_2[0].ecs_cluster.name
account_id = local.environment.account_id
actor_lpa_codes_table = aws_dynamodb_table.actor_codes_table.name
viewer_codes_table = aws_dynamodb_table.viewer_codes_table.name
user_lpa_actor_map = aws_dynamodb_table.user_lpa_actor_map.name
stats_table = aws_dynamodb_table.stats_table.name
actor_fqdn = module.eu_west_1.route53_fqdns.actor
viewer_fqdn = module.eu_west_1.route53_fqdns.viewer
admin_fqdn = module.eu_west_1.route53_fqdns.admin
public_facing_use_fqdn = module.eu_west_1.route53_fqdns.public_facing_use
public_facing_view_fqdn = module.eu_west_1.route53_fqdns.public_facing_view
viewer_load_balancer_security_group_name = module.eu_west_1.security_group_names.viewer_loadbalancer
actor_load_balancer_security_group_name = module.eu_west_1.security_group_names.actor_loadbalancer

actor_fqdn = local.active_region == "eu-west-1" ? module.eu_west_1[0].route53_fqdns.actor : module.eu_west_2[0].route53_fqdns.actor
viewer_fqdn = local.active_region == "eu-west-1" ? module.eu_west_1[0].route53_fqdns.viewer : module.eu_west_2[0].route53_fqdns.viewer
admin_fqdn = local.active_region == "eu-west-1" ? module.eu_west_1[0].route53_fqdns.admin : module.eu_west_2[0].route53_fqdns.admin
public_facing_use_fqdn = local.active_region == "eu-west-1" ? module.eu_west_1[0].route53_fqdns.public_facing_use : module.eu_west_2[0].route53_fqdns.public_facing_use
public_facing_view_fqdn = local.active_region == "eu-west-1" ? module.eu_west_1[0].route53_fqdns.public_facing_view : module.eu_west_2[0].route53_fqdns.public_facing_view
viewer_load_balancer_security_group_name = local.active_region == "eu-west-1" ? module.eu_west_1[0].security_group_names.viewer_loadbalancer : module.eu_west_2[0].security_group_names.viewer_loadbalancer
actor_load_balancer_security_group_name = local.active_region == "eu-west-1" ? module.eu_west_1[0].security_group_names.actor_loadbalancer : module.eu_west_2[0].security_group_names.actor_loadbalancer
active_region = local.active_region
}
}
}
2 changes: 1 addition & 1 deletion terraform/environment/lambda.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Function to update use a lpa event statistics to stats table
module "lambda_update_statistics" {
source = "./modules/lambda"
lambda_name = "update-statistics"
description = "Function to update use a lpa event statistics to stats table"
environment_variables = {
ENVIRONMENT = local.environment_name
REGION = data.aws_region.current.name
Expand Down
8 changes: 4 additions & 4 deletions terraform/environment/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@ variable "environments" {
}),
regions = map(
object({
name = string
is_active = bool
is_primary = bool
enabled = bool // Are we creating resources other than DynamoDB tables in this region? (e.g. ECS services, ALBs, etc.)
name = string // The name of the region (e.g. eu-west-2)
is_active = bool // Is this the region that is currently receiving traffic? Only one region should be active at a time.
is_primary = bool // Is this the region where the primary DynamoDB tables are located? The primary region should not be changed once set.
})
)
})
Expand All @@ -120,7 +121,6 @@ locals {
environment_name = lower(replace(terraform.workspace, "_", "-"))
environment = contains(keys(var.environments), local.environment_name) ? var.environments[local.environment_name] : var.environments["default"]
dns_namespace_env = local.environment.account_name == "production" ? "" : "${local.environment_name}."
dev_wildcard = local.environment.account_name == "production" ? "" : "*."
capacity_provider = local.environment.fargate_spot ? "FARGATE_SPOT" : "FARGATE"

mandatory_moj_tags = {
Expand Down
12 changes: 0 additions & 12 deletions terraform/environment/modules/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ variable "image_uri" {
default = null
}

variable "description" {
description = "Description of your Lambda Function (or Layer)"
type = string
default = null
}

variable "lambda_role_policy_document" {
description = "The policy JSON for the lambda IAM role. This policy JSON is merged with Logging and ECR access included in the module."
type = string
default = null
}

variable "environment_variables" {
description = "A map that defines environment variables for the Lambda Function."
type = map(string)
Expand Down
8 changes: 4 additions & 4 deletions terraform/environment/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
output "admin_domain" {
value = "https://${module.eu_west_1.route53_fqdns.admin}"
value = "https://${local.cluster_config.admin_fqdn}"
}

output "public_facing_use_domain" {
value = "https://${module.eu_west_1.route53_fqdns.public_facing_use}"
value = "https://${local.cluster_config.public_facing_use_fqdn}"
}

output "public_facing_view_domain" {
value = "https://${module.eu_west_1.route53_fqdns.public_facing_view}"
}
value = "https://${local.cluster_config.public_facing_view_fqdn}"
}
90 changes: 83 additions & 7 deletions terraform/environment/region.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
module "eu_west_1" {

count = local.environment.regions["eu-west-1"].enabled ? 1 : 0

source = "./region"

account_name = local.environment.account_name
Expand Down Expand Up @@ -34,15 +37,83 @@ module "eu_west_1" {
ship_metrics_queue_enabled = local.environment.ship_metrics_queue_enabled
sirius_account_id = local.environment.sirius_account_id

admin_cognito = {
id = aws_cognito_user_pool_client.use_a_lasting_power_of_attorney_admin.id
user_pool_id = local.admin_cognito_user_pool_id
user_pool_domain_name = local.admin_cognito_user_pool_domain_name
user_pool_client_secret = aws_cognito_user_pool_client.use_a_lasting_power_of_attorney_admin.client_secret
user_pool_id_token_validity = aws_cognito_user_pool_client.use_a_lasting_power_of_attorney_admin.id_token_validity
}

acm_certificate_arns = {
use = data.aws_acm_certificate.certificate_use.arn
view = data.aws_acm_certificate.certificate_view.arn
admin = data.aws_acm_certificate.certificate_admin.arn
public_facing_use = data.aws_acm_certificate.public_facing_certificate_use.arn
public_facing_view = data.aws_acm_certificate.public_facing_certificate_view.arn
dynamodb_tables = {
"actor_codes_table" = aws_dynamodb_table.actor_codes_table
"stats_table" = aws_dynamodb_table.stats_table
"actor_users_table" = aws_dynamodb_table.actor_users_table
"viewer_codes_table" = aws_dynamodb_table.viewer_codes_table
"viewer_activity_table" = aws_dynamodb_table.viewer_activity_table
"user_lpa_actor_map" = aws_dynamodb_table.user_lpa_actor_map
}

feature_flags = {
"allow_gov_one_login" = local.environment.application_flags.allow_gov_one_login
"instructions_and_preferences" = local.environment.application_flags.instructions_and_preferences
"dont_send_lpas_registered_after_sep_2019_to_cleansing_team" = local.environment.application_flags.dont_send_lpas_registered_after_sep_2019_to_cleansing_team
"allow_meris_lpas" = local.environment.application_flags.allow_meris_lpas
"deploy_opentelemetry_sidecar" = local.environment.deploy_opentelemetry_sidecar
"delete_lpa_feature" = local.environment.application_flags.delete_lpa_feature
}

providers = {
aws.region = aws.eu_west_1
aws.management = aws.management
aws.us-east-1 = aws.us-east-1
}
}

moved {
from = module.eu_west_1
to = module.eu_west_1[0]
}

module "eu_west_2" {

count = local.environment.regions["eu-west-2"].enabled ? 1 : 0

source = "./region"

account_name = local.environment.account_name
admin_container_version = var.admin_container_version
autoscaling = local.environment.autoscaling
associate_alb_with_waf_web_acl_enabled = local.environment.associate_alb_with_waf_web_acl_enabled
capacity_provider = local.capacity_provider
container_version = var.container_version
cookie_expires_use = local.environment.cookie_expires_use
cookie_expires_view = local.environment.cookie_expires_view
dns_namespace_env = local.dns_namespace_env
ecs_execution_role = module.iam.ecs_execution_role
ecs_task_roles = module.iam.ecs_task_roles
environment_name = local.environment_name
google_analytics_id_use = local.environment.google_analytics_id_use
google_analytics_id_view = local.environment.google_analytics_id_view
iap_images_endpoint = local.environment.iap_images_endpoint
load_balancer_deletion_protection_enabled = local.environment.load_balancer_deletion_protection_enabled
logging_level = local.environment.logging_level
log_retention_days = local.environment.log_retention_in_days
lpa_codes_endpoint = local.environment.lpa_codes_endpoint
lpas_collection_endpoint = local.environment.lpas_collection_endpoint
moj_sites = module.allow_list.moj_sites
notify_key_secret_name = local.environment.notify_key_secret_name
parameter_store_arns = [aws_ssm_parameter.system_message_view_en.arn, aws_ssm_parameter.system_message_view_cy.arn, aws_ssm_parameter.system_message_use_en.arn, aws_ssm_parameter.system_message_use_cy.arn]
pagerduty_service_id = local.environment.pagerduty_service_id
pdf_container_version = local.environment.pdf_container_version
public_access_enabled = var.public_access_enabled
regions = local.environment.regions
session_expires_use = local.environment.session_expires_use
session_expires_view = local.environment.session_expires_view
session_expiry_warning = local.environment.session_expiry_warning
ship_metrics_queue_enabled = local.environment.ship_metrics_queue_enabled
sirius_account_id = local.environment.sirius_account_id

admin_cognito = {
id = aws_cognito_user_pool_client.use_a_lasting_power_of_attorney_admin.id
user_pool_id = local.admin_cognito_user_pool_id
Expand Down Expand Up @@ -70,8 +141,13 @@ module "eu_west_1" {
}

providers = {
aws.region = aws.eu_west_1
aws.region = aws.eu_west_2
aws.management = aws.management
aws.us-east-1 = aws.us-east-1
}
}

moved {
from = module.eu_west_2
to = module.eu_west_2[0]
}
15 changes: 13 additions & 2 deletions terraform/environment/region/actor_load_balancer.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ resource "aws_shield_application_layer_automatic_response" "actor" {
count = var.associate_alb_with_waf_web_acl_enabled ? 1 : 0
resource_arn = aws_lb.actor.arn
action = "COUNT"

provider = aws.region
}

resource "aws_lb_target_group" "actor" {
Expand Down Expand Up @@ -63,7 +65,7 @@ resource "aws_lb_listener" "actor_loadbalancer" {
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-FS-1-2-2019-08"

certificate_arn = var.acm_certificate_arns.use
certificate_arn = data.aws_acm_certificate.certificate_use.arn

default_action {
target_group_arn = aws_lb_target_group.actor.arn
Expand All @@ -75,7 +77,9 @@ resource "aws_lb_listener" "actor_loadbalancer" {

resource "aws_lb_listener_certificate" "actor_loadbalancer_live_service_certificate" {
listener_arn = aws_lb_listener.actor_loadbalancer.arn
certificate_arn = var.acm_certificate_arns.public_facing_use
certificate_arn = data.aws_acm_certificate.public_facing_certificate_use.arn

provider = aws.region
}

# redirect root to gov.uk
Expand Down Expand Up @@ -107,6 +111,8 @@ resource "aws_lb_listener_rule" "redirect_use_root_to_gov" {

# rewrite to live service url
resource "aws_lb_listener_rule" "rewrite_use_to_live_service_url" {
count = local.route53_fqdns.public_facing_use != "" ? 1 : 0

listener_arn = aws_lb_listener.actor_loadbalancer.arn
priority = 2
action {
Expand All @@ -132,6 +138,11 @@ resource "aws_lb_listener_rule" "rewrite_use_to_live_service_url" {
provider = aws.region
}

moved {
from = aws_lb_listener_rule.rewrite_use_to_live_service_url
to = aws_lb_listener_rule.rewrite_use_to_live_service_url[0]
}

# maintenance site switching
resource "aws_ssm_parameter" "actor_maintenance_switch" {
name = "${var.environment_name}_actor_enable_maintenance"
Expand Down
4 changes: 2 additions & 2 deletions terraform/environment/region/admin_load_balancer.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ resource "aws_lb_listener" "admin_loadbalancer" {
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-FS-1-2-2019-08"

certificate_arn = var.acm_certificate_arns.admin
certificate_arn = data.aws_acm_certificate.certificate_admin.arn

default_action {
type = "authenticate-oidc"
Expand Down Expand Up @@ -110,7 +110,7 @@ moved {

resource "aws_lb_listener_certificate" "admin_loadbalancer_live_service_certificate" {
listener_arn = aws_lb_listener.admin_loadbalancer.arn
certificate_arn = var.acm_certificate_arns.public_facing_use
certificate_arn = data.aws_acm_certificate.public_facing_certificate_use.arn

provider = aws.region
}
Expand Down
4 changes: 4 additions & 0 deletions terraform/environment/region/api_ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ locals {
{
name = "LOGIN_SERIAL_CACHE_TIMEOUT",
value = "60"
},
{
name = "API_GATEWAY_REGION",
value = "eu-west-1"
}
]
})
Expand Down
29 changes: 29 additions & 0 deletions terraform/environment/region/certificates.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
data "aws_acm_certificate" "certificate_view" {
domain = "${local.dev_wildcard}view.lastingpowerofattorney.opg.service.justice.gov.uk"

provider = aws.region
}

data "aws_acm_certificate" "certificate_use" {
domain = "${local.dev_wildcard}use.lastingpowerofattorney.opg.service.justice.gov.uk"

provider = aws.region
}

data "aws_acm_certificate" "certificate_admin" {
domain = "${local.dev_wildcard}admin.lastingpowerofattorney.opg.service.justice.gov.uk"

provider = aws.region
}

data "aws_acm_certificate" "public_facing_certificate_view" {
domain = "${local.dev_wildcard}view-lasting-power-of-attorney.service.gov.uk"

provider = aws.region
}

data "aws_acm_certificate" "public_facing_certificate_use" {
domain = "${local.dev_wildcard}use-lasting-power-of-attorney.service.gov.uk"

provider = aws.region
}
Loading

0 comments on commit 5f13664

Please sign in to comment.