From a0e0abdf6c1d8921ab2a02ed0ecb3e159d626f4f Mon Sep 17 00:00:00 2001 From: Dominic Robinson <65237317+drobinson-moj@users.noreply.github.com> Date: Tue, 2 Jan 2024 13:05:45 +0000 Subject: [PATCH] DSOS-2476: RemoteDesktop spike (#4412) * add test rds * test * lb fix * fix * fix security group * lb fix * fix * SG update * dns * test * test * https backend * test * fix * fix * fix * fix * fix * fix * test * fix * fix * test * fix * fix * fix * fix --- .../hmpps-domain-services/locals.tf | 11 +- .../locals_security_groups.tf | 199 ++++++++++---- .../hmpps-domain-services/locals_test.tf | 253 ++++++++++++++++-- terraform/modules/baseline/variables.tf | 1 + 4 files changed, 382 insertions(+), 82 deletions(-) diff --git a/terraform/environments/hmpps-domain-services/locals.tf b/terraform/environments/hmpps-domain-services/locals.tf index a074c7de8b4..7235e059e66 100644 --- a/terraform/environments/hmpps-domain-services/locals.tf +++ b/terraform/environments/hmpps-domain-services/locals.tf @@ -67,12 +67,7 @@ locals { } baseline_secretsmanager_secrets = {} - - baseline_security_groups = { - private-dc = local.security_groups.private_dc - load-balancer = local.security_groups.load-balancer - } - - baseline_sns_topics = {} - baseline_ssm_parameters = {} + baseline_security_groups = local.security_groups + baseline_sns_topics = {} + baseline_ssm_parameters = {} } diff --git a/terraform/environments/hmpps-domain-services/locals_security_groups.tf b/terraform/environments/hmpps-domain-services/locals_security_groups.tf index 8569f1b117a..484f9189db6 100644 --- a/terraform/environments/hmpps-domain-services/locals_security_groups.tf +++ b/terraform/environments/hmpps-domain-services/locals_security_groups.tf @@ -1,46 +1,10 @@ locals { security_group_cidrs_devtest = { - core = module.ip_addresses.azure_fixngo_cidrs.devtest_core - ssh = module.ip_addresses.azure_fixngo_cidrs.devtest - enduserclient = [ - "10.0.0.0/8" - ] - # NOTE: REMOVE THIS WHEN MOVE TO NEW SG's - http7xxx = flatten([ - module.ip_addresses.azure_fixngo_cidrs.devtest, - module.ip_addresses.azure_fixngo_cidrs.internet_egress, - ]) - rdp = { - inbound = ["10.40.165.0/26", "10.112.3.0/26", "10.102.0.0/16"] - } - domain_controllers = module.ip_addresses.azure_fixngo_cidrs.devtest_domain_controllers - jumpservers = module.ip_addresses.azure_fixngo_cidrs.devtest_jumpservers + azure_vnets = module.ip_addresses.azure_fixngo_cidrs.devtest } - security_group_cidrs_preprod_prod = { - core = module.ip_addresses.azure_fixngo_cidrs.prod_core - ssh = flatten([ - module.ip_addresses.azure_fixngo_cidrs.prod_jumpservers, - # AllowProdStudioHostingSshInBound from 10.244.0.0/22 not included - module.ip_addresses.azure_fixngo_cidrs.prod_core, - module.ip_addresses.azure_fixngo_cidrs.prod, # NOTE: may need removing at some point - ]) - enduserclient = [ - "10.0.0.0/8" - ] - # NOTE: REMOVE THIS WHEN MOVE TO NEW SG's - http7xxx = flatten([ - module.ip_addresses.azure_fixngo_cidrs.prod, - module.ip_addresses.azure_fixngo_cidrs.internet_egress, - ]) - rdp = { - inbound = flatten([ - module.ip_addresses.azure_fixngo_cidrs.prod, - ]) - } - domain_controllers = module.ip_addresses.azure_fixngo_cidrs.prod_domain_controllers - jumpservers = module.ip_addresses.azure_fixngo_cidrs.prod_jumpservers + azure_vnets = module.ip_addresses.azure_fixngo_cidrs.prod } security_group_cidrs_by_environment = { development = local.security_group_cidrs_devtest @@ -48,10 +12,143 @@ locals { preproduction = local.security_group_cidrs_preprod_prod production = local.security_group_cidrs_preprod_prod } - security_group_cidrs = local.security_group_cidrs_by_environment[local.environment] + security_group_cidrs = merge(local.security_group_cidrs_by_environment[local.environment], { + enduserclient_internal = [ + "10.0.0.0/8" + ] + enduserclient_public = flatten([ + module.ip_addresses.moj_cidrs.trusted_moj_digital_staff_public + ]) + }) security_groups = { - private_dc = { + rds-ec2s = { + description = "Security group for Remote Desktop Service EC2s" + ingress = { + all-from-self = { + description = "Allow all ingress to self" + from_port = 0 + to_port = 0 + protocol = -1 + self = true + } + http-from-lb = { + description = "Allow http ingress" + from_port = 80 + to_port = 80 + protocol = "TCP" + security_groups = [ + "private-lb", + "public-lb", + ] + } + http-from-euc = { + description = "Allow direct http access for testing" + from_port = 80 + to_port = 80 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_internal + } + https-from-euc = { + description = "Allow direct https access for testing" + from_port = 443 + to_port = 443 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_internal + } + all-from-azure-vnets-vnet = { + description = "Allow all from azure vnets" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = local.security_group_cidrs.azure_vnets + } + } + egress = { + all = { + description = "Allow all egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + security_groups = [] + } + } + } + + public-lb = { + description = "Security group for public load-balancer" + ingress = { + all-from-self = { + description = "Allow all ingress to self" + from_port = 0 + to_port = 0 + protocol = -1 + self = true + } + http_lb = { + description = "Allow http ingress" + from_port = 80 + to_port = 80 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_public + } + https_lb = { + description = "Allow enduserclient https ingress" + from_port = 443 + to_port = 443 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_public + } + } + egress = { + all = { + description = "Allow all traffic outbound" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + } + } + + private-lb = { + description = "Security group for internal load-balancer" + ingress = { + all-from-self = { + description = "Allow all ingress to self" + from_port = 0 + to_port = 0 + protocol = -1 + self = true + } + http_lb = { + description = "Allow http ingress" + from_port = 80 + to_port = 80 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_internal + } + https_lb = { + description = "Allow enduserclient https ingress" + from_port = 443 + to_port = 443 + protocol = "TCP" + cidr_blocks = local.security_group_cidrs.enduserclient_internal + } + } + egress = { + all = { + description = "Allow all traffic outbound" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + } + } + + private-dc = { description = "Security group for Domain Controllers" ingress = { all-from-self = { @@ -61,6 +158,15 @@ locals { protocol = -1 self = true } + http_lb = { + description = "Allow http ingress" + from_port = 80 + to_port = 80 + protocol = "TCP" + security_groups = [ + "load-balancer", + ] + } all-from-noms-test-vnet = { description = "Allow all from noms test vnet" from_port = 0 @@ -102,7 +208,6 @@ locals { } } - ############ NEWLY DEFINED SGs ############ load-balancer = { description = "New security group for load-balancer" @@ -114,27 +219,19 @@ locals { protocol = -1 self = true } - # IMPORTANT: check if an 'allow all from azure' rule is required, rather than subsequent load-balancer rules - /* all-from-fixngo = { - description = "Allow all ingress from fixngo" - from_port = 0 - to_port = 0 - protocol = -1 - cidr_blocks = local.security_group_cidrs.enduserclient - } */ http_lb = { description = "Allow http ingress" from_port = 80 to_port = 80 protocol = "TCP" - cidr_blocks = local.security_group_cidrs.enduserclient + cidr_blocks = local.security_group_cidrs.enduserclient_internal } https_lb = { description = "Allow enduserclient https ingress" from_port = 443 to_port = 443 protocol = "TCP" - cidr_blocks = local.security_group_cidrs.enduserclient + cidr_blocks = local.security_group_cidrs.enduserclient_internal } } egress = { diff --git a/terraform/environments/hmpps-domain-services/locals_test.tf b/terraform/environments/hmpps-domain-services/locals_test.tf index 2c0a0531e62..897de9dd53a 100644 --- a/terraform/environments/hmpps-domain-services/locals_test.tf +++ b/terraform/environments/hmpps-domain-services/locals_test.tf @@ -1,4 +1,3 @@ -# nomis-test environment settings locals { # baseline config @@ -182,50 +181,255 @@ locals { } } + baseline_ec2_instances = { + test-rds-1-b = { + # ami has unwanted ephemeral device, don't copy all the ebs_volumess + config = merge(module.baseline_presets.ec2_instance.config.default, { + ami_name = "hmpps_windows_server_2022_release_2023-12-02T00-00-15.711Z" + availability_zone = "eu-west-2b" + ebs_volumes_copy_all_from_ami = false + user_data_raw = base64encode(file("./templates/windows_server_2022-user-data.yaml")) + }) + instance = merge(module.baseline_presets.ec2_instance.instance.default, { + vpc_security_group_ids = ["rds-ec2s"] + }) + ebs_volumes = { + "/dev/sda1" = { type = "gp3", size = 100 } + } + tags = { + description = "Remote Desktop Services test server 1" + os-type = "Windows" + component = "remotedesktop" + } + } + test-rds-2-c = { + # ami has unwanted ephemeral device, don't copy all the ebs_volumess + config = merge(module.baseline_presets.ec2_instance.config.default, { + ami_name = "hmpps_windows_server_2022_release_2023-12-02T00-00-15.711Z" + availability_zone = "eu-west-2c" + ebs_volumes_copy_all_from_ami = false + user_data_raw = base64encode(file("./templates/windows_server_2022-user-data.yaml")) + }) + instance = merge(module.baseline_presets.ec2_instance.instance.default, { + vpc_security_group_ids = ["rds-ec2s"] + }) + ebs_volumes = { + "/dev/sda1" = { type = "gp3", size = 100 } + } + tags = { + description = "Remote Desktop Services test server 2" + os-type = "Windows" + component = "remotedesktop" + } + } + test-rds-3-b = { + # ami has unwanted ephemeral device, don't copy all the ebs_volumess + config = merge(module.baseline_presets.ec2_instance.config.default, { + ami_name = "hmpps_windows_server_2022_release_2023-12-02T00-00-15.711Z" + availability_zone = "eu-west-2b" + ebs_volumes_copy_all_from_ami = false + user_data_raw = base64encode(file("./templates/windows_server_2022-user-data.yaml")) + }) + instance = merge(module.baseline_presets.ec2_instance.instance.default, { + vpc_security_group_ids = ["rds-ec2s"] + }) + ebs_volumes = { + "/dev/sda1" = { type = "gp3", size = 100 } + } + tags = { + description = "Remote Desktop Services test server 3" + os-type = "Windows" + component = "remotedesktop" + } + } + } + baseline_lbs = { - private = { - internal_lb = true - enable_delete_protection = false - load_balancer_type = "application" - force_destroy_bucket = true - subnets = [ - module.environment.subnet["private"]["eu-west-2a"].id, - module.environment.subnet["private"]["eu-west-2b"].id, - ] - security_groups = ["load-balancer"] + public = { access_logs = false enable_cross_zone_load_balancing = true + enable_delete_protection = false + force_destroy_bucket = true + internal_lb = false + load_balancer_type = "application" + security_groups = ["public-lb"] + subnets = [ + module.environment.subnet["public"]["eu-west-2a"].id, + module.environment.subnet["public"]["eu-west-2b"].id, + module.environment.subnet["public"]["eu-west-2c"].id, + ] instance_target_groups = { - rds-gateway-80 = { + test-rdgateway-http = { port = 80 protocol = "HTTP" health_check = { enabled = true - interval = 5 + interval = 10 healthy_threshold = 3 + matcher = "200-399" + path = "/" port = 80 - protocol = "HTTP" - timeout = 4 + timeout = 5 unhealthy_threshold = 2 } stickiness = { enabled = true type = "lb_cookie" } - #attachments = [ - # { ec2_instance_name = "rds-gateway" }, - #] + attachments = [ + { ec2_instance_name = "test-rds-1-b" }, + ] + } + test-rdweb-https = { + port = 443 + protocol = "HTTPS" + health_check = { + enabled = true + interval = 10 + healthy_threshold = 3 + matcher = "200-399" + path = "/" + port = 443 + protocol = "HTTPS" + timeout = 5 + unhealthy_threshold = 2 + } + stickiness = { + enabled = true + type = "lb_cookie" + } + attachments = [ + { ec2_instance_name = "test-rds-1-b" }, + ] + } + test-rdgateway-http2 = { + port = 80 + protocol = "HTTP" + health_check = { + enabled = true + interval = 10 + healthy_threshold = 3 + matcher = "200-399" + path = "/" + port = 80 + timeout = 5 + unhealthy_threshold = 2 + } + stickiness = { + enabled = true + type = "lb_cookie" + } + attachments = [ + { ec2_instance_name = "test-rds-2-c" }, + ] + } + test-rdweb-https2 = { + port = 443 + protocol = "HTTPS" + health_check = { + enabled = true + interval = 10 + healthy_threshold = 3 + matcher = "200-399" + path = "/" + port = 443 + protocol = "HTTPS" + timeout = 5 + unhealthy_threshold = 2 + } + stickiness = { + enabled = true + type = "lb_cookie" + } + attachments = [ + { ec2_instance_name = "test-rds-2-c" }, + ] } } - listeners = { http = { port = 80 protocol = "HTTP" default_action = { - type = "forward" - target_group_name = "rds-gateway-80" + type = "redirect" + redirect = { + port = 443 + protocol = "HTTPS" + status_code = "HTTP_301" + } + } + } + https = { + port = 443 + protocol = "HTTPS" + ssl_policy = "ELBSecurityPolicy-2016-08" + certificate_names_or_arns = ["application_environment_wildcard_cert"] + default_action = { + type = "fixed-response" + fixed_response = { + content_type = "text/plain" + message_body = "Not implemented" + status_code = "501" + } + } + rules = { + test-rdgateway = { + priority = 300 + actions = [{ + type = "forward" + target_group_name = "test-rdgateway-http" + }] + conditions = [{ + host_header = { + values = [ + "rdgateway.hmpps-domain-services.hmpps-test.modernisation-platform.service.justice.gov.uk", + ] + } + }] + } + test-rdweb = { + priority = 400 + actions = [{ + type = "forward" + target_group_name = "test-rdweb-https" + }] + conditions = [{ + host_header = { + values = [ + "rdweb.hmpps-domain-services.hmpps-test.modernisation-platform.service.justice.gov.uk", + ] + } + }] + } + test-rdgateway2 = { + priority = 500 + actions = [{ + type = "forward" + target_group_name = "test-rdgateway-http2" + }] + conditions = [{ + host_header = { + values = [ + "rdgateway2.hmpps-domain-services.hmpps-test.modernisation-platform.service.justice.gov.uk", + ] + } + }] + } + test-rdweb2 = { + priority = 600 + actions = [{ + type = "forward" + target_group_name = "test-rdweb-https2" + }] + conditions = [{ + host_header = { + values = [ + "rdweb2.hmpps-domain-services.hmpps-test.modernisation-platform.service.justice.gov.uk", + ] + } + }] + } } } } @@ -233,9 +437,12 @@ locals { } baseline_route53_zones = { - "test.hmpps-domain-services.service.justice.gov.uk" = { + "hmpps-test.modernisation-platform.service.justice.gov.uk" = { lb_alias_records = [ - { name = "private", type = "A", lbs_map_key = "private" }, + { name = "rdgateway.hmpps-domain-services", type = "A", lbs_map_key = "public" }, + { name = "rdweb.hmpps-domain-services", type = "A", lbs_map_key = "public" }, + { name = "rdgateway2.hmpps-domain-services", type = "A", lbs_map_key = "public" }, + { name = "rdweb2.hmpps-domain-services", type = "A", lbs_map_key = "public" }, ] } } diff --git a/terraform/modules/baseline/variables.tf b/terraform/modules/baseline/variables.tf index 4f19d5bc7fe..e82a306f8b7 100644 --- a/terraform/modules/baseline/variables.tf +++ b/terraform/modules/baseline/variables.tf @@ -257,6 +257,7 @@ variable "ec2_autoscaling_groups" { matcher = optional(string) path = optional(string) port = optional(number) + protocol = optional(string) timeout = optional(number) unhealthy_threshold = optional(number) }))