diff --git a/terraform/environment/dynamodb.tf b/terraform/environment/dynamodb.tf index 265b2d481b..b1cf71b030 100644 --- a/terraform/environment/dynamodb.tf +++ b/terraform/environment/dynamodb.tf @@ -15,9 +15,18 @@ resource "aws_dynamodb_table" "actor_codes_table" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + # For each region in the environment that is not the primary_region, create a DynamoDB replica. + + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } lifecycle { @@ -45,9 +54,16 @@ resource "aws_dynamodb_table" "stats_table" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } lifecycle { @@ -125,9 +141,16 @@ resource "aws_dynamodb_table" "actor_users_table" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } lifecycle { @@ -171,11 +194,19 @@ resource "aws_dynamodb_table" "viewer_codes_table" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } + lifecycle { prevent_destroy = false } @@ -205,11 +236,19 @@ resource "aws_dynamodb_table" "viewer_activity_table" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } + lifecycle { prevent_destroy = false } @@ -272,9 +311,16 @@ resource "aws_dynamodb_table" "user_lpa_actor_map" { enabled = true } - replica { - region_name = "eu-west-2" - propagate_tags = true + dynamic "replica" { + for_each = [ + for region in local.environment.regions : region + if region.is_primary != true + ] + + content { + region_name = replica.value.name + propagate_tags = true + } } lifecycle { diff --git a/terraform/environment/locals.tf b/terraform/environment/locals.tf index 17ad3e0399..a5cbf801be 100644 --- a/terraform/environment/locals.tf +++ b/terraform/environment/locals.tf @@ -104,7 +104,14 @@ variable "environments" { stats = object({ name = string }) - }) + }), + regions = map( + object({ + name = string + is_active = bool + is_primary = bool + }) + ) }) ) } diff --git a/terraform/environment/region.tf b/terraform/environment/region.tf index 39e3cdf9df..fe1fe38e5e 100644 --- a/terraform/environment/region.tf +++ b/terraform/environment/region.tf @@ -25,6 +25,7 @@ module "eu_west_1" { 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] 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 @@ -73,7 +74,6 @@ module "eu_west_1" { "viewer" = aws_route53_record.viewer_use_my_lpa.fqdn } - providers = { aws.region = aws.eu_west_1 aws.management = aws.management diff --git a/terraform/environment/region/actor_ecs.tf b/terraform/environment/region/actor_ecs.tf index 51e6e2a24b..17d1776acb 100644 --- a/terraform/environment/region/actor_ecs.tf +++ b/terraform/environment/region/actor_ecs.tf @@ -5,7 +5,7 @@ resource "aws_ecs_service" "actor" { name = "actor-service" cluster = aws_ecs_cluster.use_an_lpa.id task_definition = aws_ecs_task_definition.actor.arn - desired_count = var.autoscaling.use.minimum + desired_count = local.use_desired_count platform_version = "1.4.0" network_configuration { diff --git a/terraform/environment/region/admin_ecs.tf b/terraform/environment/region/admin_ecs.tf index 9999ab7cff..ab7f99f6b2 100644 --- a/terraform/environment/region/admin_ecs.tf +++ b/terraform/environment/region/admin_ecs.tf @@ -5,7 +5,7 @@ resource "aws_ecs_service" "admin" { name = "admin-service" cluster = aws_ecs_cluster.use_an_lpa.id task_definition = aws_ecs_task_definition.admin.arn - desired_count = 1 + desired_count = local.admin_desired_count platform_version = "1.4.0" network_configuration { diff --git a/terraform/environment/region/api_ecs.tf b/terraform/environment/region/api_ecs.tf index b25a5dbf3f..4effea21f5 100644 --- a/terraform/environment/region/api_ecs.tf +++ b/terraform/environment/region/api_ecs.tf @@ -5,7 +5,7 @@ resource "aws_ecs_service" "api" { name = "api-service" cluster = aws_ecs_cluster.use_an_lpa.id task_definition = aws_ecs_task_definition.api.arn - desired_count = var.autoscaling.api.minimum + desired_count = local.api_desired_count platform_version = "1.4.0" health_check_grace_period_seconds = 0 diff --git a/terraform/environment/region/locals.tf b/terraform/environment/region/locals.tf index e74dfd5e05..ca9c6f5655 100644 --- a/terraform/environment/region/locals.tf +++ b/terraform/environment/region/locals.tf @@ -1,14 +1,26 @@ locals { policy_region_prefix = lower(replace(data.aws_region.current.name, "-", "")) + # The primary region is the region where the DynamoDB tables are created and replicated to the secondary region. + primary_region = keys({ for region, region_data in var.regions : region => region_data if region_data.is_primary })[0] + is_primary_region = local.primary_region == data.aws_region.current.name ? true : false + is_active_region = var.regions[data.aws_region.current.name].is_active + + # Desired count of the ECS services. Only an active region will have a desired count greater than 0. + use_desired_count = local.is_active_region ? var.autoscaling.use.minimum : 0 + pdf_desired_count = local.is_active_region ? var.autoscaling.pdf.minimum : 0 + view_desired_count = local.is_active_region ? var.autoscaling.view.minimum : 0 + api_desired_count = local.is_active_region ? var.autoscaling.api.minimum : 0 + admin_desired_count = local.is_active_region ? 1 : 0 + # Replace the region in the ARN of the DynamoDB tables with the region of the current stack as the tables are created in the primary region # and replicated to the secondary region. This allows use to grant access to the tables in the secondary region for applications running in the secondary region. dynamodb_tables_arns = { - actor_codes_table_arn = replace(var.dynamodb_tables.actor_codes_table.arn, var.primary_region, data.aws_region.current.name) - stats_table_arn = replace(var.dynamodb_tables.stats_table.arn, var.primary_region, data.aws_region.current.name) - actor_users_table_arn = replace(var.dynamodb_tables.actor_users_table.arn, var.primary_region, data.aws_region.current.name) - viewer_codes_table_arn = replace(var.dynamodb_tables.viewer_codes_table.arn, var.primary_region, data.aws_region.current.name) - viewer_activity_table_arn = replace(var.dynamodb_tables.viewer_activity_table.arn, var.primary_region, data.aws_region.current.name) - user_lpa_actor_map_arn = replace(var.dynamodb_tables.user_lpa_actor_map.arn, var.primary_region, data.aws_region.current.name) + actor_codes_table_arn = replace(var.dynamodb_tables.actor_codes_table.arn, local.primary_region, data.aws_region.current.name) + stats_table_arn = replace(var.dynamodb_tables.stats_table.arn, local.primary_region, data.aws_region.current.name) + actor_users_table_arn = replace(var.dynamodb_tables.actor_users_table.arn, local.primary_region, data.aws_region.current.name) + viewer_codes_table_arn = replace(var.dynamodb_tables.viewer_codes_table.arn, local.primary_region, data.aws_region.current.name) + viewer_activity_table_arn = replace(var.dynamodb_tables.viewer_activity_table.arn, local.primary_region, data.aws_region.current.name) + user_lpa_actor_map_arn = replace(var.dynamodb_tables.user_lpa_actor_map.arn, local.primary_region, data.aws_region.current.name) } } diff --git a/terraform/environment/region/pdf_ecs.tf b/terraform/environment/region/pdf_ecs.tf index 818a5573c3..ac93f08f70 100644 --- a/terraform/environment/region/pdf_ecs.tf +++ b/terraform/environment/region/pdf_ecs.tf @@ -5,7 +5,7 @@ resource "aws_ecs_service" "pdf" { name = "pdf-service" cluster = aws_ecs_cluster.use_an_lpa.id task_definition = aws_ecs_task_definition.pdf.arn - desired_count = var.autoscaling.pdf.minimum + desired_count = local.pdf_desired_count platform_version = "1.4.0" network_configuration { diff --git a/terraform/environment/region/variables.tf b/terraform/environment/region/variables.tf index ba3f9593bf..bb6255ec26 100644 --- a/terraform/environment/region/variables.tf +++ b/terraform/environment/region/variables.tf @@ -174,10 +174,17 @@ variable "public_access_enabled" { default = false } -variable "primary_region" { - description = "The region that is used for the primary DynamoDB table. This is the region that is normally active." - type = string - default = "eu-west-1" +variable "regions" { + description = "Information about which regions are being used" + type = map(object({ + is_primary = bool + is_active = bool + })) + + validation { + condition = length([for region in keys(var.regions) : region if var.regions[region].is_primary]) == 1 + error_message = "One (and only one) region must be marked as primary" + } } variable "route_53_fqdns" { @@ -204,4 +211,4 @@ variable "session_expiry_warning" { variable "sirius_account_id" { description = "The AWS ID of the Sirius account." type = string -} \ No newline at end of file +} diff --git a/terraform/environment/region/viewer_ecs.tf b/terraform/environment/region/viewer_ecs.tf index 1e730e0b11..a95b5f4b66 100644 --- a/terraform/environment/region/viewer_ecs.tf +++ b/terraform/environment/region/viewer_ecs.tf @@ -5,7 +5,7 @@ resource "aws_ecs_service" "viewer" { name = "viewer-service" cluster = aws_ecs_cluster.use_an_lpa.id task_definition = aws_ecs_task_definition.viewer.arn - desired_count = var.autoscaling.view.minimum + desired_count = local.view_desired_count platform_version = "1.4.0" network_configuration { diff --git a/terraform/environment/terraform.tfvars.json b/terraform/environment/terraform.tfvars.json index a4aab5d701..9b09d8ce3e 100644 --- a/terraform/environment/terraform.tfvars.json +++ b/terraform/environment/terraform.tfvars.json @@ -73,6 +73,13 @@ "stats": { "name": "Stats" } + }, + "regions": { + "eu-west-1": { + "name": "eu-west-1", + "is_active": true, + "is_primary": true + } } }, "demo": { @@ -148,6 +155,13 @@ "stats": { "name": "Stats" } + }, + "regions": { + "eu-west-1": { + "name": "eu-west-1", + "is_active": true, + "is_primary": true + } } }, "preproduction": { @@ -223,6 +237,18 @@ "stats": { "name": "Stats" } + }, + "regions": { + "eu-west-1": { + "name": "eu-west-1", + "is_active": true, + "is_primary": true + }, + "eu-west-2": { + "name": "eu-west-2", + "is_active": true, + "is_primary": false + } } }, "production": { @@ -298,6 +324,13 @@ "stats": { "name": "Stats" } + }, + "regions": { + "eu-west-1": { + "name": "eu-west-1", + "is_active": true, + "is_primary": true + } } } }