diff --git a/.github/workflows/code-scanning.yml b/.github/workflows/code-scanning.yml index 015f8bb9d19..bc5f42014d8 100644 --- a/.github/workflows/code-scanning.yml +++ b/.github/workflows/code-scanning.yml @@ -81,7 +81,7 @@ jobs: fetch-depth: 0 - name: Run Checkov action id: checkov - uses: bridgecrewio/checkov-action@6aa9bec7b321bfe25839494e1efc7f2faad84416 # v12.2872.0 + uses: bridgecrewio/checkov-action@d0e41abbcc8c1103c6ae7e451681d071f05e1c20 # v12.2873.0 with: directory: ./ framework: terraform diff --git a/terraform/environments/analytical-platform-compute/helm-charts-actions-runners.tf b/terraform/environments/analytical-platform-compute/helm-charts-actions-runners.tf index 46b311ee25c..b820137ac3e 100644 --- a/terraform/environments/analytical-platform-compute/helm-charts-actions-runners.tf +++ b/terraform/environments/analytical-platform-compute/helm-charts-actions-runners.tf @@ -12,7 +12,7 @@ resource "helm_release" "actions_runner_mojas_airflow" { /* https://github.com/ministryofjustice/analytical-platform-actions-runner */ name = "actions-runner-mojas-airflow" repository = "oci://ghcr.io/ministryofjustice/analytical-platform-charts" - version = "2.319.1-1" + version = "2.319.1-2" chart = "actions-runner" namespace = kubernetes_namespace.actions_runners[0].metadata[0].name values = [ @@ -43,7 +43,7 @@ resource "helm_release" "actions_runner_mojas_airflow_create_a_pipeline" { /* https://github.com/ministryofjustice/analytical-platform-actions-runner */ name = "actions-runner-mojas-airflow-create-a-pipeline" repository = "oci://ghcr.io/ministryofjustice/analytical-platform-charts" - version = "2.319.1-1" + version = "2.319.1-2" chart = "actions-runner" namespace = kubernetes_namespace.actions_runners[0].metadata[0].name values = [ @@ -73,7 +73,7 @@ resource "helm_release" "actions_runner_mojas_create_a_derived_table" { /* https://github.com/ministryofjustice/analytical-platform-actions-runner */ name = "actions-runner-mojas-create-a-derived-table" repository = "oci://ghcr.io/ministryofjustice/analytical-platform-charts" - version = "2.319.1-1" + version = "2.319.1-2" chart = "actions-runner" namespace = kubernetes_namespace.actions_runners[0].metadata[0].name values = [ @@ -96,7 +96,7 @@ resource "helm_release" "actions_runner_mojas_create_a_derived_table_dpr" { /* https://github.com/ministryofjustice/analytical-platform-actions-runner */ name = "actions-runner-mojas-create-a-derived-table-dpr" repository = "oci://ghcr.io/ministryofjustice/analytical-platform-charts" - version = "2.319.1-1" + version = "2.319.1-2" chart = "actions-runner" namespace = kubernetes_namespace.actions_runners[0].metadata[0].name values = [ diff --git a/terraform/environments/analytical-platform-compute/helm-charts-applications.tf b/terraform/environments/analytical-platform-compute/helm-charts-applications.tf index 3675523439d..816cdb48d0e 100644 --- a/terraform/environments/analytical-platform-compute/helm-charts-applications.tf +++ b/terraform/environments/analytical-platform-compute/helm-charts-applications.tf @@ -2,7 +2,7 @@ resource "helm_release" "ui" { /* https://github.com/ministryofjustice/analytical-platform-ui */ name = "ui" repository = "oci://ghcr.io/ministryofjustice/analytical-platform-charts" - version = "0.2.3" + version = "0.2.4" chart = "analytical-platform-ui" namespace = kubernetes_namespace.ui.metadata[0].name values = [ diff --git a/terraform/environments/analytical-platform-ingestion/environment-configuration.tf b/terraform/environments/analytical-platform-ingestion/environment-configuration.tf index bcb4bfea848..dacc6773917 100644 --- a/terraform/environments/analytical-platform-ingestion/environment-configuration.tf +++ b/terraform/environments/analytical-platform-ingestion/environment-configuration.tf @@ -13,9 +13,9 @@ locals { observability_platform = "development" /* Image Versions */ - scan_image_version = "0.0.8" - transfer_image_version = "0.0.13" - notify_image_version = "0.0.14" + scan_image_version = "0.0.9" + transfer_image_version = "0.0.14" + notify_image_version = "0.0.15" /* Target Buckets */ target_buckets = ["mojap-land-dev"] @@ -44,9 +44,9 @@ locals { observability_platform = "production" /* Image Versions */ - scan_image_version = "0.0.8" - transfer_image_version = "0.0.13" - notify_image_version = "0.0.14" + scan_image_version = "0.0.9" + transfer_image_version = "0.0.14" + notify_image_version = "0.0.15" /* Target Buckets */ target_buckets = ["mojap-land"] diff --git a/terraform/environments/apex/application_variables.json b/terraform/environments/apex/application_variables.json index 63cd7a68bf1..ec2100f0197 100644 --- a/terraform/environments/apex/application_variables.json +++ b/terraform/environments/apex/application_variables.json @@ -52,17 +52,17 @@ "oas_lz_cidr": "10.202.4.85/32" }, "test": { - "ec2amiid": "ami-0f9852b626b9b57e7", + "ec2amiid": "ami-00b96c3ab7b1106b4", "ec2instancetype": "t3.large", "workspace_cidr": "10.200.0.0/20", "u01_orahome_size": "20", - "u01_orahome_snapshot": "snap-06c4e808d8156e7b3", + "u01_orahome_snapshot": "snap-08a78be130fecd338", "u02_oradata_size": "100", - "u02_oradata_snapshot": "snap-009a17503aeafa1ea", + "u02_oradata_snapshot": "snap-0c8dd7ca02b76f3b9", "u03_redo_size": "50", - "u03_redo_snapshot": "snap-0e1b92e0b7612f075", + "u03_redo_snapshot": "snap-0e70d2835a67670e3", "u04_arch_size": "50", - "u04_arch_snapshot": "snap-03826f506d4cf5697", + "u04_arch_snapshot": "snap-0a69ef59871cb0c79", "container_instance_type": "linux", "instance_type": "t3a.medium", "key_name": "", diff --git a/terraform/environments/apex/ecs.tf b/terraform/environments/apex/ecs.tf index 9c9f053350c..a1f19d8d699 100644 --- a/terraform/environments/apex/ecs.tf +++ b/terraform/environments/apex/ecs.tf @@ -33,6 +33,6 @@ module "apex-ecs" { ec2_instance_warmup_period = local.application_data.accounts[local.environment].ec2_instance_warmup_period log_group_kms_key = aws_kms_key.cloudwatch_logs_key.arn environment = local.environment - database_tad_password_arn = "arn:aws:ssm:${local.application_data.accounts[local.environment].region}:${local.env_account_id}:parameter/${local.app_db_password_name}" + database_admin_password_arn = "arn:aws:ssm:${local.application_data.accounts[local.environment].region}:${local.env_account_id}:parameter/${local.app_db_password_name}" } \ No newline at end of file diff --git a/terraform/environments/apex/locals.tf b/terraform/environments/apex/locals.tf index 0712f9b3514..3818a632872 100644 --- a/terraform/environments/apex/locals.tf +++ b/terraform/environments/apex/locals.tf @@ -70,11 +70,12 @@ locals { region = local.application_data.accounts[local.environment].region app_db_url = "${aws_route53_record.apex-db.fqdn}:1521:APEX" app_debug_enabled = local.application_data.accounts[local.environment].app_debug_enabled + # Note that the following secret is created manually on Parameter Store db_secret_arn = "arn:aws:ssm:${local.application_data.accounts[local.environment].region}:${local.env_account_id}:parameter/${local.app_db_password_name}" }) env_account_id = local.environment_management.account_ids[terraform.workspace] - app_db_password_name = "APP_APEX_DBPASSWORD_TAD" + app_db_password_name = "APP_APEX_DBPASSWORD_ADMIN" db_hostname = "db.${local.application_name}" database-instance-userdata = < { - name = dvo.resource_record_name - record = dvo.resource_record_value - type = dvo.resource_record_type - } - } - domain_name_main = [for k, v in local.domain_types : v.name if k == "modernisation-platform.service.justice.gov.uk"] - domain_name_sub = [for k, v in local.domain_types : v.name if k != "modernisation-platform.service.justice.gov.uk"] - domain_record_main = [for k, v in local.domain_types : v.record if k == "modernisation-platform.service.justice.gov.uk"] - domain_record_sub = [for k, v in local.domain_types : v.record if k != "modernisation-platform.service.justice.gov.uk"] - domain_type_main = [for k, v in local.domain_types : v.type if k == "modernisation-platform.service.justice.gov.uk"] - domain_type_sub = [for k, v in local.domain_types : v.type if k != "modernisation-platform.service.justice.gov.uk"] - - certificate_arn = aws_acm_certificate.external.arn - - error_codes = [ - 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, - 16, 17, 18, 19, 20, 21, 33, 34, 35, 36, 48, 49, - 50, 51, 52, 53, 54, 60, 61, 64, 65, 66, 67, 68, - 69, 70, 71, 76, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, - 112, 113, 114, 118, 119, 120, 121, 122, 123, 4096, - 16654 - ] - formatted_error_codes = [for error_code in local.error_codes : "err=${error_code}\\s"] -} diff --git a/terraform/environments/delius-core/modules/components/ldap/nlb.tf b/terraform/environments/delius-core/modules/components/ldap/nlb.tf deleted file mode 100644 index db84c092644..00000000000 --- a/terraform/environments/delius-core/modules/components/ldap/nlb.tf +++ /dev/null @@ -1,23 +0,0 @@ -module "nlb" { - source = "../../helpers/nlb" - - providers = { - aws.core-vpc = aws.core-vpc - aws.core-network-services = aws.core-network-services - } - app_name = "ldap" - env_name = var.env_name - internal = true - tags = var.tags - port = 389 - secure_port = 636 - certificate_arn = aws_acm_certificate.external.arn - protocol = "TCP" - subnet_ids = var.account_config.private_subnet_ids - vpc_cidr = var.account_config.shared_vpc_cidr - vpc_id = var.account_config.shared_vpc_id - zone_id = var.account_config.route53_inner_zone_info.zone_id - mp_application_name = var.account_info.application_name - - deregistration_delay = "15" -} diff --git a/terraform/environments/delius-core/modules/components/ldap/outputs.tf b/terraform/environments/delius-core/modules/components/ldap/outputs.tf index e9cc7b70686..83133fb4ac5 100644 --- a/terraform/environments/delius-core/modules/components/ldap/outputs.tf +++ b/terraform/environments/delius-core/modules/components/ldap/outputs.tf @@ -1,15 +1,15 @@ -output "nlb_dns_name" { - value = module.nlb.dns_name +output "efs_sg_id" { + value = module.efs.sg_id } -output "delius_core_ldap_principal_arn" { - value = aws_ssm_parameter.delius_core_ldap_principal.arn +output "efs_fs_id" { + value = module.efs.fs_id } -output "delius_core_ldap_bind_password_arn" { - value = aws_ssm_parameter.delius_core_ldap_bind_password.arn +output "efs_fs_arn" { + value = module.efs.fs_arn } -output "security_group_id" { - value = aws_security_group.ldap.id -} \ No newline at end of file +output "efs_access_point_id" { + value = module.efs.access_point_id +} diff --git a/terraform/environments/delius-core/modules/components/ldap/s3.tf b/terraform/environments/delius-core/modules/components/ldap/s3.tf index 53475f89fee..91d980023bb 100644 --- a/terraform/environments/delius-core/modules/components/ldap/s3.tf +++ b/terraform/environments/delius-core/modules/components/ldap/s3.tf @@ -60,7 +60,7 @@ module "s3_bucket_migration" { principals = { type = "AWS" identifiers = [ - module.ldap_ecs_policies.task_role.arn + var.task_role_arn ] } } diff --git a/terraform/environments/delius-core/modules/components/ldap/secrets.tf b/terraform/environments/delius-core/modules/components/ldap/secrets.tf index 5ad52fd9272..57e8f91e921 100644 --- a/terraform/environments/delius-core/modules/components/ldap/secrets.tf +++ b/terraform/environments/delius-core/modules/components/ldap/secrets.tf @@ -1,67 +1,3 @@ -#################### -# LDAP HOST -#################### - -resource "aws_ssm_parameter" "delius_core_ldap_host" { - name = format("/%s-%s/LDAP_HOST", var.account_info.application_name, var.env_name) - type = "SecureString" - value = "INITIAL_VALUE_OVERRIDDEN" - lifecycle { - ignore_changes = [ - value - ] - } - tags = var.tags -} - -#################### -# LDAP PRINCIPAL -#################### - -resource "aws_ssm_parameter" "delius_core_ldap_principal" { - name = format("/%s-%s/LDAP_PRINCIPAL", var.account_info.application_name, var.env_name) - type = "SecureString" - value = "INITIAL_VALUE_OVERRIDDEN" - lifecycle { - ignore_changes = [ - value - ] - } - tags = var.tags -} - -#################### -# LDAP SEED URI -#################### - -resource "aws_ssm_parameter" "delius_core_ldap_seed_uri" { - name = format("/%s-%s/LDAP_SEED_URI", var.account_info.application_name, var.env_name) - type = "SecureString" - value = "INITIAL_VALUE_OVERRIDDEN" - lifecycle { - ignore_changes = [ - value - ] - } - tags = var.tags -} - -#################### -# LDAP BIND PASSWORD -#################### - -resource "aws_ssm_parameter" "delius_core_ldap_bind_password" { - name = format("/%s-%s/LDAP_BIND_PASSWORD", var.account_info.application_name, var.env_name) - type = "SecureString" - value = "INITIAL_VALUE_OVERRIDDEN" - lifecycle { - ignore_changes = [ - value - ] - } - tags = var.tags -} - #################### # LDAP ADMIN PASSWORD #################### @@ -74,19 +10,3 @@ module "ldap_admin_password" { kms_key_id = var.account_config.kms_keys.general_shared allowed_account_ids = [var.platform_vars.environment_management.account_ids[join("-", ["delius-nextcloud", var.account_info.mp_environment])]] } - -#################### -# LDAP RBAC VERSION -#################### - -resource "aws_ssm_parameter" "delius_core_ldap_rbac_version" { - name = format("/%s-%s/LDAP_RBAC_VERSION", var.account_info.application_name, var.env_name) - type = "SecureString" - value = "INITIAL_VALUE_OVERRIDDEN" - lifecycle { - ignore_changes = [ - value - ] - } - tags = var.tags -} \ No newline at end of file diff --git a/terraform/environments/delius-core/modules/components/ldap/sg.tf b/terraform/environments/delius-core/modules/components/ldap/sg.tf deleted file mode 100644 index e6131c2b604..00000000000 --- a/terraform/environments/delius-core/modules/components/ldap/sg.tf +++ /dev/null @@ -1,72 +0,0 @@ -resource "aws_security_group" "ldap" { - name = "${var.env_name}-ldap-sg" - description = "Security group for the ${var.env_name} ldap service" - vpc_id = var.account_info.vpc_id - tags = var.tags - lifecycle { - create_before_destroy = true - } -} - -resource "aws_security_group_rule" "allow_all_egress" { - description = "Allow all outbound traffic to any IPv4 address" - type = "egress" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - security_group_id = aws_security_group.ldap.id -} - -resource "aws_security_group_rule" "ldap_nlb" { - for_each = toset(["tcp", "udp"]) - description = "Allow inbound traffic from VPC" - type = "ingress" - from_port = var.ldap_config.port - to_port = var.ldap_config.port - protocol = each.value - security_group_id = aws_security_group.ldap.id - cidr_blocks = [var.account_config.shared_vpc_cidr] -} - -resource "aws_security_group_rule" "to_ldap_from_bastion" { - for_each = toset(["tcp", "udp"]) - description = "Allow inbound traffic from bastion" - type = "ingress" - from_port = var.ldap_config.port - to_port = var.ldap_config.port - protocol = each.value - security_group_id = aws_security_group.ldap.id - source_security_group_id = var.bastion_sg_id -} - -resource "aws_security_group_rule" "allow_ldap_from_legacy_env" { - for_each = toset(["tcp", "udp"]) - description = "Allow inbound LDAP traffic from corresponding legacy VPC" - type = "ingress" - from_port = var.ldap_config.port - to_port = var.ldap_config.port - protocol = each.value - security_group_id = aws_security_group.ldap.id - cidr_blocks = var.environment_config.migration_environment_private_cidr -} - -resource "aws_security_group_rule" "allow_ldap_from_cp_env" { - for_each = toset(["tcp", "udp"]) - description = "Allow inbound LDAP traffic from CP" - type = "ingress" - from_port = var.ldap_config.port - to_port = var.ldap_config.port - protocol = each.value - security_group_id = aws_security_group.ldap.id - cidr_blocks = [var.account_info.cp_cidr] -} - -resource "aws_security_group_rule" "efs_ingress_ldap" { - type = "ingress" - from_port = 2049 - to_port = 2049 - protocol = "tcp" - source_security_group_id = module.efs.sg_id - security_group_id = aws_security_group.ldap.id -} diff --git a/terraform/environments/delius-core/modules/components/ldap/variables.tf b/terraform/environments/delius-core/modules/components/ldap/variables.tf index 49897213ebd..26307afd45a 100644 --- a/terraform/environments/delius-core/modules/components/ldap/variables.tf +++ b/terraform/environments/delius-core/modules/components/ldap/variables.tf @@ -25,40 +25,24 @@ variable "ldap_config" { type = any } +variable "enable_platform_backups" { + description = "Enable or disable Mod Platform centralised backups" + type = bool + default = null +} + variable "platform_vars" { type = object({ environment_management = any }) } -variable "source_security_group_id" { - description = "sg of source" - type = string - default = null -} - variable "environment_config" { description = "environment config to pass to the instance" type = any } -variable "bastion_sg_id" { - description = "Security group id of the bastion" - type = string -} - -variable "enable_platform_backups" { - description = "Enable or disable Mod Platform centralised backups" - type = bool - default = null -} - -variable "ecs_cluster_arn" { - description = "The ARN of the ECS cluster" - type = string -} - -variable "sns_topic_arn" { - description = "The ARN of the SNS topic" +variable "task_role_arn" { + description = "The ARN of the task role" type = string } diff --git a/terraform/environments/delius-core/modules/delius_environment/ldap.tf b/terraform/environments/delius-core/modules/delius_environment/ldap.tf index e4e55137009..74e3343cc70 100644 --- a/terraform/environments/delius-core/modules/delius_environment/ldap.tf +++ b/terraform/environments/delius-core/modules/delius_environment/ldap.tf @@ -15,12 +15,9 @@ module "ldap" { environment_config = var.environment_config ldap_config = var.ldap_config - bastion_sg_id = module.bastion_linux.bastion_security_group - - sns_topic_arn = aws_sns_topic.delius_core_alarms.arn - ecs_cluster_arn = module.ecs.ecs_cluster_arn platform_vars = var.platform_vars tags = local.tags enable_platform_backups = var.enable_platform_backups + task_role_arn = "arn:aws:iam::${var.account_info.id}:role/${var.env_name}-ldap-ecs-task" } diff --git a/terraform/environments/delius-core/modules/delius_environment/ldap_ecs.tf b/terraform/environments/delius-core/modules/delius_environment/ldap_ecs.tf new file mode 100644 index 00000000000..5438e5690ec --- /dev/null +++ b/terraform/environments/delius-core/modules/delius_environment/ldap_ecs.tf @@ -0,0 +1,359 @@ +module "ldap_ecs" { + source = "../helpers/delius_microservice" + + name = "ldap" + env_name = var.env_name + + container_cpu = var.delius_microservice_configs.ldap.container_cpu + container_memory = var.delius_microservice_configs.ldap.container_memory + + container_vars_default = { + "LDAP_HOST" = "0.0.0.0", + "SLAPD_LOG_LEVEL" = var.delius_microservice_configs.ldap.slapd_log_level, + "LDAP_PORT" = "389", + "DELIUS_ENVIRONMENT" = "delius-core-${var.env_name}" + } + + container_vars_env_specific = try(var.delius_microservice_configs.ldap.container_vars_env_specific, {}) + + container_secrets_default = { + "BIND_PASSWORD" = aws_ssm_parameter.ldap_bind_password.arn, + "MIGRATION_S3_LOCATION" = aws_ssm_parameter.ldap_seed_uri.arn, + "RBAC_TAG" = aws_ssm_parameter.ldap_rbac_version.arn + } + container_secrets_env_specific = try(var.delius_microservice_configs.ldap.container_secrets_env_specific, {}) + + desired_count = 1 + + container_port_config = [ + { + containerPort = var.delius_microservice_configs.ldap.container_port + protocol = "tcp" + } + ] + + system_controls = [ + { + namespace = "net.ipv4.tcp_keepalive_time" + value = "300" + } + ] + + ecs_cluster_arn = module.ecs.ecs_cluster_arn + cluster_security_group_id = aws_security_group.cluster.id + + bastion_sg_id = module.bastion_linux.bastion_security_group + tags = var.tags + + platform_vars = var.platform_vars + container_image = "${var.platform_vars.environment_management.account_ids["core-shared-services-production"]}.dkr.ecr.eu-west-2.amazonaws.com/delius-core-openldap-ecr-repo:${var.delius_microservice_configs.ldap.image_tag}" + account_config = var.account_config + + health_check = { + command = ["CMD-SHELL", "ldapsearch -x -H ldap://localhost:389 -b '' -s base '(objectclass=*)' namingContexts"] + interval = 30 + retries = 3 + startPeriod = 60 + timeout = 5 + } + account_info = var.account_info + + ignore_changes_service_task_definition = false + + + extra_task_exec_role_policies = { + efs = data.aws_iam_policy_document.ldap_efs_access_policy + } + + providers = { + aws.core-vpc = aws.core-vpc + aws.core-network-services = aws.core-network-services + } + + log_error_pattern = "%${join("|", local.ldap_formatted_error_codes)}%" + sns_topic_arn = aws_sns_topic.delius_core_alarms.arn + enable_platform_backups = var.enable_platform_backups + + efs_volumes = [ + { + host_path = null + name = "delius-core-openldap" + efs_volume_configuration = [{ + file_system_id = module.ldap.efs_fs_id + root_directory = "/" + transit_encryption = "ENABLED" + transit_encryption_port = 2049 + authorization_config = [{ + access_point_id = module.ldap.efs_access_point_id + iam = "DISABLED" + }] + }] + } + ] + + mount_points = [{ + sourceVolume = "delius-core-openldap" + containerPath = "/var/lib/openldap/openldap-data" + readOnly = false + }] + + ecs_service_egress_security_group_ids = [ + { + ip_protocol = "-1" + cidr_ipv4 = "0.0.0.0/0" + description = "Allow all outbound traffic to any IPv4 address" + } + ] + + nlb_ingress_security_group_ids = [ + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + referenced_security_group_id = module.bastion_linux.bastion_security_group + description = "Allow inbound traffic from bastion" + }, + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + { + port = 2049 + ip_protocol = "tcp" + referenced_security_group_id = module.ldap.efs_sg_id + description = "EFS ingress" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "tcp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "udp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "udp" + referenced_security_group_id = module.bastion_linux.bastion_security_group + description = "Allow inbound traffic from bastion" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "tcp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "udp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "tcp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + { + port = var.ldap_config.tls_port + ip_protocol = "udp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + ] + + ecs_service_ingress_security_group_ids = [ + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.account_config.shared_vpc_cidr + description = "Allow inbound traffic from VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + referenced_security_group_id = module.bastion_linux.bastion_security_group + description = "Allow inbound traffic from bastion" + }, + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.environment_config.migration_environment_vpc_cidr + description = "Allow inbound LDAP traffic from corresponding legacy VPC" + }, + { + port = var.ldap_config.port + ip_protocol = "tcp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + { + port = var.ldap_config.port + ip_protocol = "udp" + cidr_ipv4 = var.account_info.cp_cidr + description = "Allow inbound LDAP traffic from CP" + }, + { + port = 2049 + ip_protocol = "tcp" + referenced_security_group_id = module.ldap.efs_sg_id + description = "EFS ingress" + } + ] +} + + +data "aws_iam_policy_document" "ldap_efs_access_policy" { + statement { + actions = [ + "elasticfilesystem:ClientRootAccess", + "elasticfilesystem:ClientWrite", + "elasticfilesystem:ClientMount" + ] + resources = [ + module.ldap.efs_fs_arn + ] + effect = "Allow" + } +} + +locals { + ldap_domain_types = { for dvo in aws_acm_certificate.ldap_external.domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + ldap_domain_name_main = [for k, v in local.ldap_domain_types : v.name if k == "modernisation-platform.service.justice.gov.uk"] + ldap_domain_name_sub = [for k, v in local.ldap_domain_types : v.name if k != "modernisation-platform.service.justice.gov.uk"] + ldap_domain_record_main = [for k, v in local.ldap_domain_types : v.record if k == "modernisation-platform.service.justice.gov.uk"] + ldap_domain_record_sub = [for k, v in local.ldap_domain_types : v.record if k != "modernisation-platform.service.justice.gov.uk"] + ldap_domain_type_main = [for k, v in local.ldap_domain_types : v.type if k == "modernisation-platform.service.justice.gov.uk"] + ldap_domain_type_sub = [for k, v in local.ldap_domain_types : v.type if k != "modernisation-platform.service.justice.gov.uk"] + + ldap_error_codes = [ + 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, + 16, 17, 18, 19, 20, 21, 33, 34, 35, 36, 48, 49, + 50, 51, 52, 53, 54, 60, 61, 64, 65, 66, 67, 68, + 69, 70, 71, 76, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, + 112, 113, 114, 118, 119, 120, 121, 122, 123, 4096, + 16654 + ] + ldap_formatted_error_codes = [for error_code in local.ldap_error_codes : "err=${error_code}\\s"] +} + +resource "aws_lb_listener" "ldaps" { + load_balancer_arn = module.ldap_ecs.nlb_arn + port = 636 + protocol = "TLS" + + default_action { + type = "forward" + target_group_arn = module.ldap_ecs.nlb_target_group_arn_map[389] + } + + certificate_arn = aws_acm_certificate.ldap_external.arn +} + +resource "aws_route53_record" "ldap_external" { + provider = aws.core-vpc + + zone_id = var.account_config.route53_external_zone.zone_id + name = "ldap.${var.env_name}.${var.account_config.dns_suffix}" + type = "CNAME" + ttl = "60" + records = [module.ldap_ecs.nlb_dns_name] +} + +resource "aws_route53_record" "ldap_external_validation" { + provider = aws.core-network-services + + allow_overwrite = true + name = local.ldap_domain_name_main[0] + records = local.ldap_domain_record_main + ttl = 60 + type = local.ldap_domain_type_main[0] + zone_id = var.account_config.route53_network_services_zone.zone_id +} + +resource "aws_acm_certificate" "ldap_external" { + domain_name = "modernisation-platform.service.justice.gov.uk" + validation_method = "DNS" + subject_alternative_names = [aws_route53_record.ldap_external.name] + tags = var.tags + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_route53_record" "ldap_external_validation_subdomain" { + provider = aws.core-vpc + + allow_overwrite = true + name = local.ldap_domain_name_sub[0] + records = local.ldap_domain_record_sub + ttl = 60 + type = local.ldap_domain_type_sub[0] + zone_id = var.account_config.route53_external_zone.zone_id +} + +resource "aws_acm_certificate_validation" "ldap_external" { + certificate_arn = aws_acm_certificate.ldap_external.arn + validation_record_fqdns = [local.ldap_domain_name_main[0], local.ldap_domain_name_sub[0]] +} + +resource "aws_cloudwatch_log_group" "ldap_automation" { + name = "/ecs/ldap-automation-${var.env_name}" + retention_in_days = 7 + tags = var.tags +} \ No newline at end of file diff --git a/terraform/environments/delius-core/modules/delius_environment/pwm.tf b/terraform/environments/delius-core/modules/delius_environment/pwm.tf index 282ea1352aa..e1c63853045 100644 --- a/terraform/environments/delius-core/modules/delius_environment/pwm.tf +++ b/terraform/environments/delius-core/modules/delius_environment/pwm.tf @@ -79,8 +79,8 @@ module "pwm" { container_vars_default = { "CONFIG_XML_BASE64" = base64encode(templatefile("${path.module}/templates/PwmConfiguration.xml.tpl", { - ldap_host_url = "ldap://${module.ldap.nlb_dns_name}:${var.ldap_config.port}" - ldap_user = nonsensitive(module.ldap.delius_core_ldap_principal_arn) + ldap_host_url = "ldap://ldap.${var.env_name}.${var.account_config.dns_suffix}:${var.ldap_config.port}" + ldap_user = nonsensitive(aws_ssm_parameter.ldap_principal.arn) pwm_url = "https://pwm.${var.env_name}.${var.account_config.dns_suffix}" email_from_address = "no-reply@${aws_ses_domain_identity.pwm.domain}" email_smtp_address = "email-smtp.eu-west-2.amazonaws.com" diff --git a/terraform/environments/delius-core/modules/delius_environment/ssm.tf b/terraform/environments/delius-core/modules/delius_environment/ssm.tf index fd26e92cc92..c100a0a7c50 100644 --- a/terraform/environments/delius-core/modules/delius_environment/ssm.tf +++ b/terraform/environments/delius-core/modules/delius_environment/ssm.tf @@ -24,7 +24,18 @@ resource "aws_ssm_parameter" "ldap_bind_password" { ] } tags = local.tags +} +resource "aws_ssm_parameter" "ldap_host" { + name = format("/%s-%s/LDAP_HOST", var.account_info.application_name, var.env_name) + type = "SecureString" + value = module.ldap_ecs.nlb_dns_name + lifecycle { + ignore_changes = [ + value + ] + } + tags = var.tags } resource "aws_ssm_parameter" "ldap_admin_password" { @@ -39,6 +50,42 @@ resource "aws_ssm_parameter" "ldap_admin_password" { tags = local.tags } +resource "aws_ssm_parameter" "ldap_seed_uri" { + name = format("/%s-%s/LDAP_SEED_URI", var.account_info.application_name, var.env_name) + type = "SecureString" + value = "INITIAL_VALUE_OVERRIDDEN" + lifecycle { + ignore_changes = [ + value + ] + } + tags = var.tags +} + +resource "aws_ssm_parameter" "ldap_principal" { + name = format("/%s-%s/LDAP_PRINCIPAL", var.account_info.application_name, var.env_name) + type = "SecureString" + value = "INITIAL_VALUE_OVERRIDDEN" + lifecycle { + ignore_changes = [ + value + ] + } + tags = var.tags +} + +resource "aws_ssm_parameter" "ldap_rbac_version" { + name = format("/%s-%s/LDAP_RBAC_VERSION", var.account_info.application_name, var.env_name) + type = "SecureString" + value = "INITIAL_VALUE_OVERRIDDEN" + lifecycle { + ignore_changes = [ + value + ] + } + tags = var.tags +} + resource "aws_ssm_parameter" "oasys_user" { name = format("/%s-%s/oasys_user", var.account_info.application_name, var.env_name) type = "SecureString" diff --git a/terraform/environments/delius-core/modules/delius_environment/variables.tf b/terraform/environments/delius-core/modules/delius_environment/variables.tf index 29eae19f3b5..eedc38d57af 100644 --- a/terraform/environments/delius-core/modules/delius_environment/variables.tf +++ b/terraform/environments/delius-core/modules/delius_environment/variables.tf @@ -30,6 +30,7 @@ variable "ldap_config" { efs_backup_schedule = string efs_backup_retention_period = string port = optional(number) + tls_port = optional(number) }) default = { name = "default_name" @@ -41,6 +42,7 @@ variable "ldap_config" { efs_backup_schedule = "default_efs_backup_schedule" efs_backup_retention_period = "default_efs_backup_retention_period" port = 389 + tls_port = 636 } } @@ -103,4 +105,4 @@ variable "db_suffix" { variable "env_name_to_dms_config_map" { description = "Map of delius-core environments to DMS configurations" type = any -} \ No newline at end of file +} diff --git a/terraform/environments/delius-core/modules/delius_environment/versions.tf b/terraform/environments/delius-core/modules/delius_environment/versions.tf index bdb3762af70..e5dc6ba202c 100644 --- a/terraform/environments/delius-core/modules/delius_environment/versions.tf +++ b/terraform/environments/delius-core/modules/delius_environment/versions.tf @@ -5,6 +5,10 @@ terraform { version = "~> 5.0" configuration_aliases = [aws.bucket-replication, aws.core-vpc, aws.core-network-services] } + archive = { + source = "hashicorp/archive" + version = "~> 2.4" + } } required_version = ">= 1.0.1" } diff --git a/terraform/environments/delius-core/modules/delius_environment/weblogic.tf b/terraform/environments/delius-core/modules/delius_environment/weblogic.tf index 5f518ac415f..10b58ea5a31 100644 --- a/terraform/environments/delius-core/modules/delius_environment/weblogic.tf +++ b/terraform/environments/delius-core/modules/delius_environment/weblogic.tf @@ -8,8 +8,8 @@ module "weblogic" { container_vars_default = { "JDBC_URL" : aws_ssm_parameter.jdbc_url.arn, "JDBC_PASSWORD" : aws_ssm_parameter.jdbc_password.arn, - "LDAP_PRINCIPAL" : module.ldap.delius_core_ldap_principal_arn, - "LDAP_CREDENTIAL" : module.ldap.delius_core_ldap_bind_password_arn + "LDAP_PRINCIPAL" : aws_ssm_parameter.ldap_principal.arn, + "LDAP_CREDENTIAL" : aws_ssm_parameter.ldap_bind_password.arn } desired_count = 0 diff --git a/terraform/environments/delius-core/modules/delius_environment/weblogic_eis.tf b/terraform/environments/delius-core/modules/delius_environment/weblogic_eis.tf index 17fdf668f64..cd68c989724 100644 --- a/terraform/environments/delius-core/modules/delius_environment/weblogic_eis.tf +++ b/terraform/environments/delius-core/modules/delius_environment/weblogic_eis.tf @@ -7,7 +7,7 @@ module "weblogic_eis" { container_vars_default = { "LDAP_PORT" : var.ldap_config.port, - "LDAP_HOST" : module.ldap.nlb_dns_name, + "LDAP_HOST" : module.ldap_ecs.nlb_dns_name, "AWS_XRAY_TRACING_NAME" : "weblogic-eis", "COOKIE_SECURE" : "true", "DELIUS_API_URL" : "todo", @@ -43,8 +43,8 @@ module "weblogic_eis" { container_secrets_default = { "JDBC_URL" : aws_ssm_parameter.jdbc_url.arn, "JDBC_PASSWORD" : aws_ssm_parameter.jdbc_password.arn, - "LDAP_PRINCIPAL" : module.ldap.delius_core_ldap_principal_arn, - "LDAP_CREDENTIAL" : module.ldap.delius_core_ldap_bind_password_arn, + "LDAP_PRINCIPAL" : aws_ssm_parameter.ldap_principal.arn, + "LDAP_CREDENTIAL" : aws_ssm_parameter.ldap_bind_password.arn, "MERGE_SECRET" : data.aws_ssm_parameter.delius_core_merge_api_client_secret.arn, "PDFCREATION_SECRET" : data.aws_ssm_parameter.pdfcreation_secret.arn, "USERMANAGEMENT_SECRET" : data.aws_ssm_parameter.usermanagement_secret.arn diff --git a/terraform/environments/delius-core/modules/helpers/delius_microservice/ecs.tf b/terraform/environments/delius-core/modules/helpers/delius_microservice/ecs.tf index c3a6d3aca95..551ef78f499 100644 --- a/terraform/environments/delius-core/modules/helpers/delius_microservice/ecs.tf +++ b/terraform/environments/delius-core/modules/helpers/delius_microservice/ecs.tf @@ -22,14 +22,16 @@ module "container_definition" { "awslogs-stream-prefix" = "${var.env_name}-${var.name}" } } + system_controls = var.system_controls } module "ecs_policies" { - source = "../ecs_policies" - env_name = var.env_name - service_name = var.name - tags = var.tags - extra_task_role_policies = var.extra_task_role_policies + source = "../ecs_policies" + env_name = var.env_name + service_name = var.name + tags = var.tags + extra_task_role_policies = var.extra_task_role_policies + extra_task_exec_role_policies = var.extra_task_exec_role_policies } module "ecs_service" { diff --git a/terraform/environments/delius-core/modules/helpers/delius_microservice/load_balancing.tf b/terraform/environments/delius-core/modules/helpers/delius_microservice/load_balancing.tf index ff3369faf40..ba5f280699c 100644 --- a/terraform/environments/delius-core/modules/helpers/delius_microservice/load_balancing.tf +++ b/terraform/environments/delius-core/modules/helpers/delius_microservice/load_balancing.tf @@ -157,3 +157,25 @@ resource "aws_route53_record" "services_nlb_r53_record" { zone_id = aws_lb.delius_microservices.zone_id } } + +resource "aws_vpc_security_group_ingress_rule" "nlb_custom_rules" { + for_each = { for index, rule in var.nlb_ingress_security_group_ids : index => rule } + security_group_id = aws_security_group.delius_microservices_service_nlb.id + description = "custom rule" + from_port = each.value.port + to_port = each.value.port + ip_protocol = each.value.ip_protocol + cidr_ipv4 = each.value.cidr_ipv4 + referenced_security_group_id = each.value.referenced_security_group_id +} + +resource "aws_vpc_security_group_egress_rule" "nlb_custom_rules" { + for_each = { for index, rule in var.nlb_egress_security_group_ids : index => rule } + security_group_id = aws_security_group.delius_microservices_service_nlb.id + description = "custom rule" + from_port = each.value.port + to_port = each.value.port + ip_protocol = each.value.ip_protocol + cidr_ipv4 = each.value.cidr_ipv4 + referenced_security_group_id = each.value.referenced_security_group_id +} diff --git a/terraform/environments/delius-core/modules/helpers/delius_microservice/outputs.tf b/terraform/environments/delius-core/modules/helpers/delius_microservice/outputs.tf index 501a72e7c21..532500bac32 100644 --- a/terraform/environments/delius-core/modules/helpers/delius_microservice/outputs.tf +++ b/terraform/environments/delius-core/modules/helpers/delius_microservice/outputs.tf @@ -30,3 +30,17 @@ output "rds_endpoint" { output "rds_port" { value = var.create_rds ? aws_db_instance.this[0].port : null } + +output "nlb_arn" { + value = aws_lb.delius_microservices.arn +} + +output "nlb_dns_name" { + value = aws_lb.delius_microservices.dns_name +} + +output "nlb_target_group_arn_map" { + value = { + for k, v in aws_lb_target_group.service : k => v.arn + } +} diff --git a/terraform/environments/delius-core/modules/helpers/delius_microservice/sg.tf b/terraform/environments/delius-core/modules/helpers/delius_microservice/sg.tf index 83e7d1a8b0c..7c36b34824a 100644 --- a/terraform/environments/delius-core/modules/helpers/delius_microservice/sg.tf +++ b/terraform/environments/delius-core/modules/helpers/delius_microservice/sg.tf @@ -30,6 +30,7 @@ resource "aws_vpc_security_group_egress_rule" "ecs_service_to_db" { } resource "aws_vpc_security_group_ingress_rule" "alb_to_ecs_service" { + count = var.alb_security_group_id == null ? 0 : 1 security_group_id = aws_security_group.ecs_service.id description = "load balancer to ecs service" from_port = var.container_port_config[0].containerPort @@ -78,13 +79,14 @@ resource "aws_vpc_security_group_ingress_rule" "nlb_to_ecs_service" { } resource "aws_vpc_security_group_ingress_rule" "custom_rules" { - for_each = { for index, rule in var.ecs_service_ingress_security_group_ids : index => rule } - security_group_id = aws_security_group.ecs_service.id - description = "custom rule" - from_port = each.value.port - to_port = each.value.port - ip_protocol = each.value.ip_protocol - cidr_ipv4 = each.value.cidr_ipv4 + for_each = { for index, rule in var.ecs_service_ingress_security_group_ids : index => rule } + security_group_id = aws_security_group.ecs_service.id + description = "custom rule" + from_port = each.value.port + to_port = each.value.port + ip_protocol = each.value.ip_protocol + cidr_ipv4 = each.value.cidr_ipv4 + referenced_security_group_id = each.value.referenced_security_group_id } resource "aws_vpc_security_group_egress_rule" "custom_rules" { diff --git a/terraform/environments/delius-core/modules/helpers/delius_microservice/variables.tf b/terraform/environments/delius-core/modules/helpers/delius_microservice/variables.tf index d8bad10af3b..999281ce66f 100644 --- a/terraform/environments/delius-core/modules/helpers/delius_microservice/variables.tf +++ b/terraform/environments/delius-core/modules/helpers/delius_microservice/variables.tf @@ -203,6 +203,7 @@ variable "enable_platform_backups" { variable "db_ingress_security_groups" { description = "Additional RDS/elasticache ingress security groups" type = list(string) + default = [] } variable "tags" { @@ -250,6 +251,7 @@ variable "target_group_protocol_version" { variable "certificate_arn" { description = "The ARN of the certificate to use for the target group" type = string + default = null } variable "microservice_lb" { @@ -371,6 +373,7 @@ variable "container_secrets_env_specific" { variable "alb_security_group_id" { description = "The security group ID of the ALB" type = string + default = null } variable "health_check_path" { @@ -504,6 +507,7 @@ variable "ecs_service_ingress_security_group_ids" { type = list(object({ referenced_security_group_id = optional(string, null) cidr_ipv4 = optional(string, null) + description = optional(string, null) port = number ip_protocol = string })) @@ -516,6 +520,7 @@ variable "ecs_service_egress_security_group_ids" { referenced_security_group_id = optional(string, null) cidr_ipv4 = optional(string, null) port = optional(number, null) + description = optional(string, null) ip_protocol = string })) default = [] @@ -567,6 +572,7 @@ variable "sns_topic_arn" { variable "frontend_lb_arn_suffix" { description = "Used by alarms" type = string + default = "" } variable "extra_task_role_policies" { @@ -575,6 +581,12 @@ variable "extra_task_role_policies" { default = {} } +variable "extra_task_exec_role_policies" { + description = "A map of data \"aws_iam_policy_document\" objects, keyed by name, to attach to the task exec role" + type = map(any) + default = {} +} + variable "health_check" { description = "The health check configuration for the container" type = object({ @@ -586,3 +598,33 @@ variable "health_check" { }) default = null } + +variable "nlb_ingress_security_group_ids" { + description = "Security group ids to allow ingress to the ECS service" + type = list(object({ + referenced_security_group_id = optional(string, null) + cidr_ipv4 = optional(string, null) + description = optional(string, null) + port = number + ip_protocol = string + })) + default = [] +} + +variable "nlb_egress_security_group_ids" { + description = "Security group ids to allow egress from the ECS service" + type = list(object({ + referenced_security_group_id = optional(string, null) + cidr_ipv4 = optional(string, null) + port = optional(number, null) + description = optional(string, null) + ip_protocol = string + })) + default = [] +} + +variable "system_controls" { + description = "The system controls for the container" + type = list + default = [] +} diff --git a/terraform/environments/delius-core/modules/helpers/ecs_policies/main.tf b/terraform/environments/delius-core/modules/helpers/ecs_policies/main.tf index ce8454bd974..757aac70c17 100644 --- a/terraform/environments/delius-core/modules/helpers/ecs_policies/main.tf +++ b/terraform/environments/delius-core/modules/helpers/ecs_policies/main.tf @@ -94,11 +94,11 @@ data "aws_iam_policy_document" "ecs_task_exec" { } } } - -resource "aws_iam_role" "task_exec" { - name = "${var.env_name}-${var.service_name}-ecs-task-exec" - assume_role_policy = data.aws_iam_policy_document.ecs_task_exec.json - tags = var.tags +resource "aws_iam_role_policy" "exec_actions" { + for_each = var.extra_task_exec_role_policies + name = "${var.env_name}-${var.service_name}-ecs-task-exec-${each.key}" + policy = each.value.json + role = aws_iam_role.task_exec.id } data "aws_iam_policy_document" "task_exec" { @@ -106,7 +106,7 @@ data "aws_iam_policy_document" "task_exec" { effect = "Allow" resources = ["*"] - actions = concat([ + actions = [ "ssm:GetParameters", "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", @@ -117,7 +117,7 @@ data "aws_iam_policy_document" "task_exec" { "logs:PutLogEvents", "secretsmanager:GetSecretValue", "kms:Decrypt", - ], var.extra_exec_role_allow_statements) + ] } } @@ -126,3 +126,10 @@ resource "aws_iam_role_policy" "task_exec" { policy = data.aws_iam_policy_document.task_exec.json role = aws_iam_role.task_exec.id } + + +resource "aws_iam_role" "task_exec" { + name = "${var.env_name}-${var.service_name}-ecs-task-exec" + assume_role_policy = data.aws_iam_policy_document.ecs_task_exec.json + tags = var.tags +} diff --git a/terraform/environments/delius-core/modules/helpers/ecs_policies/variables.tf b/terraform/environments/delius-core/modules/helpers/ecs_policies/variables.tf index 5c354d8bf92..33eacc0ca4f 100644 --- a/terraform/environments/delius-core/modules/helpers/ecs_policies/variables.tf +++ b/terraform/environments/delius-core/modules/helpers/ecs_policies/variables.tf @@ -16,6 +16,13 @@ variable "extra_task_role_policies" { description = "A map of data \"aws_iam_policy_document\" objects, keyed by name, to attach to the task role" } +variable "extra_task_exec_role_policies" { + type = map(any) + default = {} + description = "A map of data \"aws_iam_policy_document\" objects, keyed by name, to attach to the task exec role" +} + + variable "extra_service_role_allow_statements" { type = list(string) default = [] diff --git a/terraform/environments/digital-prison-reporting/main.tf b/terraform/environments/digital-prison-reporting/main.tf index 20cce9c52cc..3135e2b3ade 100644 --- a/terraform/environments/digital-prison-reporting/main.tf +++ b/terraform/environments/digital-prison-reporting/main.tf @@ -589,7 +589,7 @@ module "glue_s3_data_reconciliation_job" { name = "${local.project}-data-reconciliation-job-${local.env}" short_name = "${local.project}-data-reconciliation-job" command_type = "glueetl" - description = "Reconciles data across DataHub.\nArguments:\n--dpr.config.key: (Required) config key e.g. prisoner\n" + description = "Reconciles data across DataHub.\nArguments:\n--dpr.config.key: (Required) config key e.g. prisoner\n--dpr.dms.replication.task.id: (Required) ID of the DMS replication task to reconcile against the raw zone\n--dpr.reconciliation.checks.to.run: (Optional) Allows restricting the set of checks that will be run" create_security_configuration = local.create_sec_conf job_language = "scala" temp_dir = "s3://${module.s3_glue_job_bucket.bucket_id}/tmp/${local.project}-data-reconciliation-${local.env}/" @@ -632,6 +632,8 @@ module "glue_s3_data_reconciliation_job" { "--dpr.aws.region" = local.account_region "--dpr.config.s3.bucket" = module.s3_glue_job_bucket.bucket_id, "--dpr.log.level" = local.glue_job_common_log_level + "--dpr.raw.s3.path" = "s3://${module.s3_raw_bucket.bucket_id}/" + "--dpr.raw.archive.s3.path" = "s3://${module.s3_raw_archive_bucket.bucket_id}/" "--dpr.structured.s3.path" = "s3://${module.s3_structured_bucket.bucket_id}/" "--dpr.curated.s3.path" = "s3://${module.s3_curated_bucket.bucket_id}/" "--dpr.nomis.glue.connection.name" = aws_glue_connection.glue_nomis_connection[0].name diff --git a/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/pipeline.tf b/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/pipeline.tf index 987603189d8..5759dafdb19 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/pipeline.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/pipeline.tf @@ -6,7 +6,7 @@ module "data_ingestion_pipeline" { step_function_name = var.data_ingestion_pipeline dms_task_time_out = var.pipeline_dms_task_time_out - additional_policies = var.pipeline_additional_policies + step_function_execution_role_arn = var.step_function_execution_role_arn # Send this block to the calling repo Pipeline #depends_on = [ diff --git a/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/variables.tf b/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/variables.tf index d36562151ea..a56e085fe1a 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/variables.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/ingestion-pipeline/variables.tf @@ -17,10 +17,9 @@ variable "pipeline_dms_task_time_out" { default = 86400 # 24 hours } -variable "pipeline_additional_policies" { - description = "Pipeline Additional policies" - type = list(string) - default = [] +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" } variable "glue_s3_data_deletion_job" { diff --git a/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/pipeline.tf b/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/pipeline.tf index ba529eed42e..0c1b810af0d 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/pipeline.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/pipeline.tf @@ -6,7 +6,7 @@ module "reload_pipeline" { step_function_name = var.reload_pipeline dms_task_time_out = var.pipeline_dms_task_time_out - additional_policies = var.pipeline_additional_policies + step_function_execution_role_arn = var.step_function_execution_role_arn definition = jsonencode( { diff --git a/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/variables.tf b/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/variables.tf index 065f6cbd59c..aec1ea3d7cd 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/variables.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/reload-pipeline/variables.tf @@ -16,10 +16,9 @@ variable "pipeline_dms_task_time_out" { default = 86400 # 24 hours } -variable "pipeline_additional_policies" { - description = "Pipeline Additional policies" - type = list(string) - default = [] +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" } variable "glue_stop_glue_instance_job" { diff --git a/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/pipeline.tf b/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/pipeline.tf index 530794dc435..24197de03fe 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/pipeline.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/pipeline.tf @@ -5,7 +5,7 @@ module "replay_pipeline" { enable_step_function = var.setup_replay_pipeline step_function_name = var.replay_pipeline - additional_policies = var.pipeline_additional_policies + step_function_execution_role_arn = var.step_function_execution_role_arn definition = jsonencode( { diff --git a/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/variables.tf b/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/variables.tf index 3527724df2e..32d7246e872 100644 --- a/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/variables.tf +++ b/terraform/environments/digital-prison-reporting/modules/domains/replay-pipeline/variables.tf @@ -10,10 +10,9 @@ variable "replay_pipeline" { default = "" } -variable "pipeline_additional_policies" { - description = "Pipeline Additional policies" - type = list(string) - default = [] +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" } variable "dms_replication_task_arn" { diff --git a/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/pipeline.tf b/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/pipeline.tf new file mode 100644 index 00000000000..fe762f9db31 --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/pipeline.tf @@ -0,0 +1,64 @@ +# Step Function for Starting the CDC Pipeline +module "cdc_start_pipeline" { + source = "../../step_function" + + enable_step_function = var.setup_start_cdc_pipeline + step_function_name = var.start_cdc_pipeline + + step_function_execution_role_arn = var.step_function_execution_role_arn + + definition = jsonencode( + { + "Comment" : "Step Function for Starting the CDC Pipeline", + "StartAt" : "Stop DMS Replication Task", + "States" : { + "Stop DMS Replication Task" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun.sync", + "Parameters" : { + "JobName" : var.stop_dms_task_job, + "Arguments" : { + "--dpr.dms.replication.task.id" : var.replication_task_id + } + }, + "Next" : "Stop Glue Streaming Job" + }, + "Stop Glue Streaming Job" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun.sync", + "Parameters" : { + "JobName" : var.glue_stop_glue_instance_job, + "Arguments" : { + "--dpr.stop.glue.instance.job.name" : var.glue_reporting_hub_cdc_jobname + } + }, + "Next" : "Start Glue Streaming Job" + }, + "Start Glue Streaming Job" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun", + "Parameters" : { + "JobName" : var.glue_reporting_hub_cdc_jobname, + "Arguments" : { + "--dpr.config.s3.bucket" : var.s3_glue_bucket_id, + "--dpr.config.key" : var.domain + } + }, + "Next" : "Resume DMS Replication Task" + }, + "Resume DMS Replication Task" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::aws-sdk:databasemigration:startReplicationTask", + "Parameters" : { + "ReplicationTaskArn" : var.dms_replication_task_arn, + "StartReplicationTaskType" : "resume-processing" + }, + "End" : true + } + } + } + ) + + tags = var.tags + +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/variables.tf b/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/variables.tf new file mode 100644 index 00000000000..88d027b1a9c --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/domains/start-cdc-pipeline/variables.tf @@ -0,0 +1,56 @@ +variable "setup_start_cdc_pipeline" { + description = "Enable Maintenance Pipeline, True or False" + type = bool + default = false +} + +variable "start_cdc_pipeline" { + description = "Name for Maintenance Pipeline" + type = string +} + +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" +} + +variable "replication_task_id" { + type = string + description = "ID of the replication task" +} + +variable "dms_replication_task_arn" { + type = string + description = "ARN of the replication task" +} + +variable "glue_reporting_hub_cdc_jobname" { + description = "Glue Reporting Hub CDC JobName" + type = string +} + +variable "s3_glue_bucket_id" { + description = "S3, Glue Bucket ID" + type = string +} + +variable "glue_stop_glue_instance_job" { + description = "Name of job to stop the current running instance of the streaming job" + type = string +} + +variable "stop_dms_task_job" { + description = "Name of job to stop a running DMS task" + type = string +} + +variable "tags" { + type = map(string) + default = {} + description = "(Optional) Key-value map of resource tags" +} + +variable "domain" { + type = string + description = "Domain Name" +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/pipeline.tf b/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/pipeline.tf new file mode 100644 index 00000000000..92b1179f255 --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/pipeline.tf @@ -0,0 +1,55 @@ +# Step Function for Stopping the CDC Pipeline +module "cdc_stop_pipeline" { + source = "../../step_function" + + enable_step_function = var.setup_stop_cdc_pipeline + step_function_name = var.stop_cdc_pipeline + + step_function_execution_role_arn = var.step_function_execution_role_arn + + definition = jsonencode( + { + "Comment" : "Step Function for Stopping the CDC Pipeline", + "StartAt" : "Stop DMS Replication Task", + "States" : { + "Stop DMS Replication Task" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun.sync", + "Parameters" : { + "JobName" : var.stop_dms_task_job, + "Arguments" : { + "--dpr.dms.replication.task.id" : var.replication_task_id + } + }, + "Next" : "Check All Pending Files Have Been Processed" + }, + "Check All Pending Files Have Been Processed" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun", + "Parameters" : { + "JobName" : var.glue_unprocessed_raw_files_check_job, + "Arguments" : { + "--dpr.orchestration.wait.interval.seconds" : "60" + "--dpr.orchestration.max.attempts" : "120" + } + }, + "Next" : "Stop Glue Streaming Job" + }, + "Stop Glue Streaming Job" : { + "Type" : "Task", + "Resource" : "arn:aws:states:::glue:startJobRun.sync", + "Parameters" : { + "JobName" : var.glue_stop_glue_instance_job, + "Arguments" : { + "--dpr.stop.glue.instance.job.name" : var.glue_reporting_hub_cdc_jobname + } + }, + "End" : true + } + } + } + ) + + tags = var.tags + +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/variables.tf b/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/variables.tf new file mode 100644 index 00000000000..22af2a709f4 --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/domains/stop-cdc-pipeline/variables.tf @@ -0,0 +1,56 @@ +variable "setup_stop_cdc_pipeline" { + description = "Enable Maintenance Pipeline, True or False" + type = bool + default = false +} + +variable "stop_cdc_pipeline" { + description = "Name for Maintenance Pipeline" + type = string +} + +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" +} + +variable "replication_task_id" { + type = string + description = "ID of the replication task" +} + +variable "glue_reporting_hub_cdc_jobname" { + description = "Glue Reporting Hub CDC JobName" + type = string +} + +variable "s3_glue_bucket_id" { + description = "S3, Glue Bucket ID" + type = string +} + +variable "glue_stop_glue_instance_job" { + description = "Name of job to stop the current running instance of the streaming job" + type = string +} + +variable "stop_dms_task_job" { + description = "Name of job to stop a running DMS task" + type = string +} + +variable "glue_unprocessed_raw_files_check_job" { + description = "Name of job to ensure raw files have been processed" + type = string +} + +variable "tags" { + type = map(string) + default = {} + description = "(Optional) Key-value map of resource tags" +} + +variable "domain" { + type = string + description = "Domain Name" +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/ec2/iam.tf b/terraform/environments/digital-prison-reporting/modules/ec2/iam.tf index 17ca28af24d..a1635d9f8b0 100644 --- a/terraform/environments/digital-prison-reporting/modules/ec2/iam.tf +++ b/terraform/environments/digital-prison-reporting/modules/ec2/iam.tf @@ -1,3 +1,5 @@ +# tflint-ignore-file: Terraform_required_version, terraform_required_providers + resource "aws_iam_role" "kinesis-agent-instance-role" { name = "${var.name}-role" path = "/" @@ -138,7 +140,7 @@ resource "aws_iam_policy" "glue-full-access" { data "aws_iam_policy_document" "glue-access" { #checkov:skip=CKV_AWS_110:"Ensure IAM policies does not allow privilege escalation. Will be addressed as part of https://dsdmoj.atlassian.net/browse/DPR2-1083" #checkov:skip=CKV_AWS_111:"Ensure IAM policies does not allow write access without constraints" - #checkov:skip=CKV_AWS_109:"Ensure IAM policies does not allow permissions management / resource exposure without constraints" + #checkov:skip=CKV_AWS_109:"Ensure IAM policies does not allow permissions management/resource exposure without constraints" #checkov:skip=CKV_AWS_356:"Ensure no IAM policies documents allow "*" as a statement's resource for restrictable actions. Will be addressed as part of https://dsdmoj.atlassian.net/browse/DPR2-1083" statement { diff --git a/terraform/environments/digital-prison-reporting/modules/ec2/main.tf b/terraform/environments/digital-prison-reporting/modules/ec2/main.tf index 10a955ad096..11ba9ba174f 100644 --- a/terraform/environments/digital-prison-reporting/modules/ec2/main.tf +++ b/terraform/environments/digital-prison-reporting/modules/ec2/main.tf @@ -1,3 +1,5 @@ +# tflint-ignore-file: terraform_required_version, terraform_required_providers + data "aws_caller_identity" "current" {} data "template_file" "user_data" { @@ -32,6 +34,9 @@ resource "aws_security_group" "ec2_sec_group" { resource "aws_security_group_rule" "ingress_traffic" { #checkov:skip=CKV_AWS_24: "Ensure no security groups allow ingress from 0.0.0.0:0 to port 22" #checkov:skip=CKV_AWS_260: "Ensure no security groups allow ingress from 0.0.0.0:0 to port 80" + # tfsec:ignore:AVD-AWS-0097 - Ignoring the risk of allowing all egress traffic to public IPs + # tfsec:ignore:AVD-AWS-0104 - Security group rule allows egress to multiple public internet addresses. + for_each = var.ec2_sec_rules description = format("Traffic for %s %d", each.value.protocol, each.value.from_port) from_port = each.value.from_port @@ -56,6 +61,9 @@ resource "aws_security_group_rule" "ingress_traffic_from_security_groups" { # Needs revision for Egress after POC resource "aws_security_group_rule" "egress_traffic" { #checkov:skip=CKV_AWS_23:"Ensure every security group and rule has a description" + # tfsec:ignore:AVD-AWS-0097 - Ignoring the risk of allowing all egress traffic to public IPs + # tfsec:ignore:AVD-AWS-0104 - Security group rule allows egress to multiple public internet addresses. + security_group_id = aws_security_group.ec2_sec_group.id type = "egress" from_port = 0 diff --git a/terraform/environments/digital-prison-reporting/modules/ec2/outputs.tf b/terraform/environments/digital-prison-reporting/modules/ec2/outputs.tf index 42716f775b3..be3088c617d 100644 --- a/terraform/environments/digital-prison-reporting/modules/ec2/outputs.tf +++ b/terraform/environments/digital-prison-reporting/modules/ec2/outputs.tf @@ -1,3 +1,5 @@ +# tflint-ignore-file: terraform_required_version, terraform_required_providers + output "private_key" { value = tls_private_key.ec2-user.private_key_pem sensitive = true diff --git a/terraform/environments/digital-prison-reporting/modules/ec2/variables.tf b/terraform/environments/digital-prison-reporting/modules/ec2/variables.tf index 8905a9d6d4b..81e5a21c640 100644 --- a/terraform/environments/digital-prison-reporting/modules/ec2/variables.tf +++ b/terraform/environments/digital-prison-reporting/modules/ec2/variables.tf @@ -1,5 +1,8 @@ +# tflint-ignore-file: terraform_required_version, terraform_required_providers + variable "name" { description = "The EC2 Sec name." + type = string } variable "env" { @@ -20,7 +23,9 @@ variable "aws_region" { description = "AWS Region" } -variable "ec2_terminate_behavior" {} +variable "ec2_terminate_behavior" { + type = string +} variable "description" { type = string @@ -34,15 +39,22 @@ variable "tags" { description = "(Optional) Key-value map of resource tags." } -variable "vpc" {} +variable "vpc" { + type = string +} variable "ec2_sec_rules" { description = "A Map of map of security group Rules to associate with" + type = map(object({ + from_port = number + to_port = number + protocol = string + })) default = { "TCP_80" = { "from_port" = 80, - "to_port" : 80, - "protocol" = "TCP" + "to_port" = 80, + "protocol" = "TCP" }, "TCP_443" = { "from_port" = 443, @@ -69,6 +81,12 @@ variable "ec2_sec_rules" { variable "ec2_sec_rules_source_sec_group" { description = "A Map of security group Rules that allows ingress from a specified security group" + type = map(object({ + from_port = number + to_port = number + protocol = string + source_security_group_id = string + })) default = {} } @@ -78,12 +96,17 @@ variable "cidr" { default = null } -variable "ec2_instance_type" {} +variable "ec2_instance_type" { + type = string +} -variable "ami_image_id" {} +variable "ami_image_id" { + type = string +} variable "subnet_ids" { description = "subnet IDs to associate with" + type = string default = null } @@ -113,6 +136,7 @@ variable "iam_instance_profile" { variable "ebs_size" { description = "EBS Block Size" + type = number default = 20 } @@ -130,11 +154,13 @@ variable "ebs_delete_on_termination" { variable "region" { description = "Current AWS Region." + type = string default = "eu-west-2" } variable "account" { description = "AWS Account ID." + type = string default = "" } @@ -146,4 +172,5 @@ variable "scale_down" { #variable "s3_policy_arn" { # description = "S3 policy ARN, to be attached to Ec2 Instance Profile" -#} \ No newline at end of file +# type = string +#} diff --git a/terraform/environments/digital-prison-reporting/modules/ec2/versions.tf b/terraform/environments/digital-prison-reporting/modules/ec2/versions.tf new file mode 100644 index 00000000000..ea265eb2f9b --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/ec2/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_providers { + aws = { + version = "~> 5.0" + source = "hashicorp/aws" + } + + } + required_version = "~> 1.0" +} diff --git a/terraform/environments/digital-prison-reporting/modules/glue_job/main.tf b/terraform/environments/digital-prison-reporting/modules/glue_job/main.tf index a5a6c1b7dc3..c59f27d20e1 100644 --- a/terraform/environments/digital-prison-reporting/modules/glue_job/main.tf +++ b/terraform/environments/digital-prison-reporting/modules/glue_job/main.tf @@ -120,6 +120,7 @@ data "aws_iam_policy_document" "extra-policy-document" { } statement { actions = [ + "dms:DescribeTableStatistics", "dms:DescribeReplicationTasks", "dms:StopReplicationTask" ] diff --git a/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/main.tf b/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/main.tf new file mode 100644 index 00000000000..c98ac04f1f8 --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/main.tf @@ -0,0 +1,23 @@ +resource "aws_scheduler_schedule" "schedule" { + count = var.create_pipeline_schedule ? 1 : 0 + + name = var.pipeline_name + description = var.description + flexible_time_window { + mode = var.time_window_mode + maximum_window_in_minutes = var.time_window_mode == "OFF" ? null : var.maximum_window_in_minutes + } + + schedule_expression = var.schedule_expression + schedule_expression_timezone = var.schedule_expression_timezone + + target { + arn = var.state_machine_arn + role_arn = var.step_function_execution_role_arn + + input = jsonencode({ + StateMachineArn = var.state_machine_arn + Input = "" + }) + } +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/variables.tf b/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/variables.tf new file mode 100644 index 00000000000..e86eafa3046 --- /dev/null +++ b/terraform/environments/digital-prison-reporting/modules/pipeline_trigger/variables.tf @@ -0,0 +1,48 @@ +variable "create_pipeline_schedule" { + type = bool + default = false + description = "Create pipeline trigger" +} + +variable "pipeline_name" { + type = string + description = "Name of the pipeline trigger" +} + +variable "description" { + type = string + description = "Short description of the pipeline trigger" +} + +variable "time_window_mode" { + type = string + default = "OFF" + description = "(Optional) The time window mode e.g. OFF/FLEXIBLE" +} + +variable "maximum_window_in_minutes" { + type = number + default = null + description = "(Optional) The maximum time window in minutes" +} + +variable "schedule_expression" { + type = string + description = "Schedule expression for the pipeline trigger" +} + +variable "schedule_expression_timezone" { + type = string + description = "Schedule expression time zone for the pipeline trigger" + default = "Europe/London" +} + +variable "state_machine_arn" { + type = string + description = "The ARN of the step function" +} + +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" +} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/step_function/iam.tf b/terraform/environments/digital-prison-reporting/modules/step_function/iam.tf deleted file mode 100644 index 4cec9528549..00000000000 --- a/terraform/environments/digital-prison-reporting/modules/step_function/iam.tf +++ /dev/null @@ -1,65 +0,0 @@ -data "aws_iam_policy_document" "step_function_role" { - statement { - effect = "Allow" - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - - identifiers = [ - "states.amazonaws.com", - ] - } - } -} - -data "aws_iam_policy_document" "step_function_execution" { - statement { - resources = [ - "*" - ] - - actions = [ - "logs:CreateLogDelivery", - "logs:GetLogDelivery", - "logs:UpdateLogDelivery", - "logs:DeleteLogDelivery", - "logs:ListLogDeliveries", - "logs:PutResourcePolicy", - "logs:DescribeResourcePolicies", - "logs:DescribeLogGroups" - ] - } - - statement { - resources = ["*"] - - actions = [ - "xray:PutTraceSegments", - "xray:PutTelemetryRecords", - "xray:GetSamplingRules", - "xray:GetSamplingTargets" - ] - } -} - -resource "aws_iam_policy" "step_function_execution" { - count = var.enable_step_function ? 1 : 0 - - name = "${var.step_function_name}-policy" - policy = data.aws_iam_policy_document.step_function_execution.json -} - -resource "aws_iam_role" "step_function_role" { - count = var.enable_step_function ? 1 : 0 - - name = "${var.step_function_name}-role" - assume_role_policy = data.aws_iam_policy_document.step_function_role.json -} - -resource "aws_iam_role_policy_attachment" "step_function_role_policy_attachment" { - for_each = var.enable_step_function ? toset(var.additional_policies) : toset([]) - - role = aws_iam_role.step_function_role[0].id - policy_arn = each.value -} \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/modules/step_function/main.tf b/terraform/environments/digital-prison-reporting/modules/step_function/main.tf index 18462fafa4a..b513498a157 100644 --- a/terraform/environments/digital-prison-reporting/modules/step_function/main.tf +++ b/terraform/environments/digital-prison-reporting/modules/step_function/main.tf @@ -2,7 +2,7 @@ resource "aws_sfn_state_machine" "data_ingestion_step_function" { count = var.enable_step_function ? 1 : 0 name = var.step_function_name - role_arn = aws_iam_role.step_function_role[0].arn + role_arn = var.step_function_execution_role_arn definition = var.definition diff --git a/terraform/environments/digital-prison-reporting/modules/step_function/variables.tf b/terraform/environments/digital-prison-reporting/modules/step_function/variables.tf index d5cd9b55dbe..9f672d4cfe7 100644 --- a/terraform/environments/digital-prison-reporting/modules/step_function/variables.tf +++ b/terraform/environments/digital-prison-reporting/modules/step_function/variables.tf @@ -19,6 +19,12 @@ variable "step_function_name" { type = string } +variable "step_function_log_retention_in_days" { + description = "(Optional) The log retention in days for the step-function." + default = 7 + type = string +} + variable "dms_task_time_out" { description = "(Optional) The duration after which the DMS load step is deemed to have failed." default = 86400 # 24 hours @@ -29,14 +35,13 @@ variable "definition" { description = "(Required) The definition of the step function" } -variable "additional_policies" { - description = "(Optional) The list of Policies used for this Step Function." - type = list(any) - default = [] -} - variable "tags" { type = map(string) default = {} description = "(Optional) Key-value map of resource tags." +} + +variable "step_function_execution_role_arn" { + type = string + description = "The ARN of the step function execution role" } \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/notifications.tf b/terraform/environments/digital-prison-reporting/notifications.tf index 4d767beaf8b..9edd85a30e3 100644 --- a/terraform/environments/digital-prison-reporting/notifications.tf +++ b/terraform/environments/digital-prison-reporting/notifications.tf @@ -63,7 +63,7 @@ module "glue_status_change_rule" { "source": ["aws.glue"], "detail-type": ["Glue Job State Change"], "detail": { - "state": ["STOPPED", "FAILED", "TIMEOUT"] + "state": ["FAILED", "TIMEOUT"] } } PATTERN diff --git a/terraform/environments/digital-prison-reporting/policy.tf b/terraform/environments/digital-prison-reporting/policy.tf index 92d82b2a5cf..8a7c5d9c407 100644 --- a/terraform/environments/digital-prison-reporting/policy.tf +++ b/terraform/environments/digital-prison-reporting/policy.tf @@ -881,4 +881,99 @@ resource "aws_iam_role_policy_attachment" "analytical_platform_share_policy_atta role = aws_iam_role.analytical_platform_share_role[each.key].name policy_arn = "arn:aws:iam::aws:policy/AWSLakeFormationCrossAccountManager" +} + +# IAM Policy and roles for executing a step-function +data "aws_iam_policy_document" "step_function_execution_assume_policy_document" { + statement { + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + + identifiers = [ + "scheduler.amazonaws.com", + "states.amazonaws.com" + ] + } + } +} + +data "aws_iam_policy_document" "step_function_execution_policy_document" { + statement { + actions = [ + "states:StartExecution" + ] + + resources = [ + "arn:aws:states:*:*:stateMachine:*" + ] + } + + statement { + resources = [ + "*" + ] + + actions = [ + "logs:CreateLogDelivery", + "logs:GetLogDelivery", + "logs:UpdateLogDelivery", + "logs:DeleteLogDelivery", + "logs:ListLogDeliveries", + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:PutResourcePolicy", + "logs:DescribeResourcePolicies", + "logs:DescribeLogGroups", + "logs:PutDestination" + ] + } + + statement { + resources = ["*"] + + actions = [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords", + "xray:GetSamplingRules", + "xray:GetSamplingTargets" + ] + } +} + +resource "aws_iam_policy" "step_function_execution_policy" { + name = "${local.project}-step-function-execution-policy" + policy = data.aws_iam_policy_document.step_function_execution_policy_document.json +} + +resource "aws_iam_role" "step_function_execution_role" { + name = "${local.project}-step-function-execution-role" + assume_role_policy = data.aws_iam_policy_document.step_function_execution_assume_policy_document.json +} + +resource "aws_iam_role_policy_attachment" "step_function_role_policy_attachment" { + role = aws_iam_role.step_function_execution_role.id + policy_arn = aws_iam_policy.step_function_execution_policy.arn +} + +resource "aws_iam_role_policy_attachment" "step_function_role_dms_policy_attachment" { + role = aws_iam_role.step_function_execution_role.id + policy_arn = aws_iam_policy.start_dms_task_policy.arn +} + +resource "aws_iam_role_policy_attachment" "step_function_role_glue_policy_attachment" { + role = aws_iam_role.step_function_execution_role.id + policy_arn = aws_iam_policy.trigger_glue_job_policy.arn +} + +resource "aws_iam_role_policy_attachment" "step_function_role_lambda_policy_attachment" { + role = aws_iam_role.step_function_execution_role.id + policy_arn = aws_iam_policy.invoke_lambda_policy.arn +} + +resource "aws_iam_role_policy_attachment" "step_function_role_all_state_machine_policy_attachment" { + role = aws_iam_role.step_function_execution_role.id + policy_arn = aws_iam_policy.all_state_machine_policy.arn } \ No newline at end of file diff --git a/terraform/environments/digital-prison-reporting/sg.tf b/terraform/environments/digital-prison-reporting/sg.tf index a00ec259001..ebd2878282f 100644 --- a/terraform/environments/digital-prison-reporting/sg.tf +++ b/terraform/environments/digital-prison-reporting/sg.tf @@ -28,7 +28,7 @@ resource "aws_security_group" "lambda_generic" { resource "aws_security_group_rule" "lambda_ingress_generic" { #checkov:skip=CKV_AWS_23: "Ensure every security group and rule has a description" - + count = local.enable_generic_lambda_sg ? 1 : 0 cidr_blocks = [data.aws_vpc.dpr.cidr_block, ] diff --git a/terraform/environments/electronic-monitoring-data/s3.tf b/terraform/environments/electronic-monitoring-data/s3.tf new file mode 100644 index 00000000000..62585f8e9f7 --- /dev/null +++ b/terraform/environments/electronic-monitoring-data/s3.tf @@ -0,0 +1,732 @@ +locals { + environment_map = { + "production" = "prod" + "development" = "dev" + } + environment_shorthand = lookup(local.environment_map, local.environment) + + bucket_prefix = "emds-${local.environment_shorthand}" +} + +# ------------------------------------------------------------------------ +# Account S3 bucket log bucket +# ------------------------------------------------------------------------ + +module "s3-logging-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-bucket-logs-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below two variables and providers configuration are only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + # replication_role_arn = module.s3-bucket.role.arn + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 90 + storage_class = "STANDARD_IA" + }, { + days = 365 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 730 + } + + noncurrent_version_transition = [ + { + days = 90 + storage_class = "STANDARD_IA" + }, { + days = 365 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 730 + } + } + ] + + tags = merge(local.tags, { resource-type = "logging" }) +} + +# ------------------------------------------------------------------------ +# Metadata Store Bucket +# ------------------------------------------------------------------------ + +module "s3-metadata-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-metadata-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below two variables and providers configuration are only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + # replication_role_arn = module.s3-bucket.role.arn + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-metadata/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 90 + storage_class = "STANDARD_IA" + }, { + days = 365 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 730 + } + + noncurrent_version_transition = [ + { + days = 90 + storage_class = "STANDARD_IA" + }, { + days = 365 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 730 + } + } + ] + + tags = merge(local.tags, { Resource_Type = "metadata_store" }) +} + +# resource "aws_s3_bucket_notification" "send_metadata_to_ap_lambda" { +# bucket = module.s3-metadata-bucket.bucket.id + +# lambda_function { +# id = "metadata_bucket_notification" +# lambda_function_arn = module.send_metadata_to_ap.lambda_function_arn +# events = ["s3:ObjectCreated:*"] +# } + +# depends_on = [aws_lambda_permission.send_metadata_to_ap] +# } + +# ---------------------------------- +# Athena Query result storage bucket +# ---------------------------------- + +module "s3-athena-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-athena-query-results-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-athena-query-results/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 365 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} + +# ---------------------------------- +# Unzipped Data Store and log bucket +# ---------------------------------- + +module "s3-unzipped-files-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-unzipped-files-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-unzipped-files/" + + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + expiration = { + days = 7 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# DMS Premigration Assessments bucket +# ------------------------------------------------------------------------ + +module "s3-dms-premigrate-assess-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-dms-premigrate-assess-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-dms-premigrate-assess/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 60 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 120 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# Unstructured directory structure as json bucket +# ------------------------------------------------------------------------ + +module "s3-json-directory-structure-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-json-directory-structure-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-json-directory-structure/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 365 + storage_class = "STANDARD_IA" + }, { + days = 730 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 2190 + } + + noncurrent_version_transition = [ + { + days = 365 + storage_class = "STANDARD_IA" + }, { + days = 730 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 2190 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# Main store bucket +# ------------------------------------------------------------------------ + +module "s3-data-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + bucket_prefix = "${local.bucket_prefix}-data-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-data/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 183 + storage_class = "STANDARD_IA" + }, { + days = 730 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 10000 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# DMS data validation bucket +# ------------------------------------------------------------------------ +module "s3-dms-data-validation-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-dms-data-validation-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-dms-data-validation/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 60 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 120 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# Glue job script store bucket +# ------------------------------------------------------------------------ + +module "s3-glue-job-script-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-glue-job-store-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/${local.bucket_prefix}-glue-job-store/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 60 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 120 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} + +# ------------------------------------------------------------------------ +# DMS target bucket +# ------------------------------------------------------------------------ + + +module "s3-dms-target-store-bucket" { + source = "github.com/ministryofjustice/modernisation-platform-terraform-s3-bucket?ref=52a40b0" + + bucket_prefix = "${local.bucket_prefix}-dms-rds-to-parquet-" + versioning_enabled = true + + # to disable ACLs in preference of BucketOwnership controls as per https://aws.amazon.com/blogs/aws/heads-up-amazon-s3-security-changes-are-coming-in-april-of-2023/ set: + ownership_controls = "BucketOwnerEnforced" + acl = "private" + + # Refer to the below section "Replication" before enabling replication + replication_enabled = false + # Below variable and providers configuration is only relevant if 'replication_enabled' is set to true + # replication_region = "eu-west-2" + providers = { + # Here we use the default provider Region for replication. Destination buckets can be within the same Region as the + # source bucket. On the other hand, if you need to enable cross-region replication, please contact the Modernisation + # Platform team to add a new provider for the additional Region. + # Leave this provider block in even if you are not using replication + aws.bucket-replication = aws + } + + log_buckets = tomap({"main_logging_bucket": module.s3-logging-bucket.bucket}) + log_prefix = "logs/dms-target-store/" + log_partition_date_source = "EventTime" + + lifecycle_rule = [ + { + id = "main" + enabled = "Enabled" + prefix = "" + + tags = { + rule = "log" + autoclean = "true" + } + + transition = [ + { + days = 365 + storage_class = "STANDARD_IA" + }, { + days = 700 + storage_class = "GLACIER" + } + ] + + expiration = { + days = 1000 + } + + noncurrent_version_transition = [ + { + days = 30 + storage_class = "STANDARD_IA" + }, { + days = 90 + storage_class = "GLACIER" + } + ] + + noncurrent_version_expiration = { + days = 365 + } + } + ] + + tags = local.tags +} diff --git a/terraform/environments/nomis-combined-reporting/locals_preproduction.tf b/terraform/environments/nomis-combined-reporting/locals_preproduction.tf index c92967e3d11..36b50e58568 100644 --- a/terraform/environments/nomis-combined-reporting/locals_preproduction.tf +++ b/terraform/environments/nomis-combined-reporting/locals_preproduction.tf @@ -27,6 +27,61 @@ locals { } } + ec2_autoscaling_groups = { + pp-ncr-test = { + autoscaling_group = { + desired_capacity = 1 + max_size = 1 + force_delete = true + vpc_zone_identifier = module.environment.subnets["private"].ids + } + config = { + ami_name = "base_rhel_8_5_*" + iam_resource_names_prefix = "ec2-bip" + instance_profile_policies = [ + "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", + "EC2Default", + "EC2S3BucketWriteAndDeleteAccessPolicy", + "ImageBuilderS3BucketWriteAndDeleteAccessPolicy", + "Ec2PPReportingPolicy", + ] + subnet_name = "private" + } + ebs_volumes = { + "/dev/sdb" = { type = "gp3", size = 100 } + "/dev/sdc" = { type = "gp3", size = 100 } + "/dev/sds" = { type = "gp3", size = 100 } + } + instance = { + disable_api_termination = false + instance_type = "t3.large" + key_name = "ec2-user" + vpc_security_group_ids = ["bip"] + metadata_options_http_tokens = "required" + } + user_data_cloud_init = { + args = { + branch = "ncr/TM-503/preprod-bip-fixes" + ansible_args = "--tags ec2provision" + } + scripts = [ # paths are relative to templates/ dir + "../../../modules/baseline_presets/ec2-user-data/install-ssm-agent.sh", + "../../../modules/baseline_presets/ec2-user-data/ansible-ec2provision.sh.tftpl", + "../../../modules/baseline_presets/ec2-user-data/post-ec2provision.sh", + ] + } + tags = { + backup = "false" + component = "test" + description = "Preprod build testing" + os-type = "Linux" + nomis-combined-reporting-environment = "pp" + server-type = "ncr-bip" + update-ssm-agent = "patchgroup1" + } + } + } + ec2_instances = { ls-ncr-db-1-a = merge(local.ec2_instances.db, { diff --git a/terraform/environments/xhibit-portal/bastion_linux.json b/terraform/environments/xhibit-portal/bastion_linux.json index 634742741e9..0dcc8c42fe9 100644 --- a/terraform/environments/xhibit-portal/bastion_linux.json +++ b/terraform/environments/xhibit-portal/bastion_linux.json @@ -14,7 +14,8 @@ "williamc": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEFmMn3wg4w+Q+pL4DXvzkZ1wfoNMkQSIU+mPG2d68r0zF9F0j61TxwbhQ9zQADhw5tSjSH5p7aVNi8RhYZKRE3fJ6zrmIkhsr7Jhnv2ZBGGuwnehmENX88AIxvVBMtyeCzFKvFVm+wj3CFVpEFA4dkIZn+YJyK5rzlM1meYzyMEd2ww0AAEZnYpucMidAb5b6KJa+Kaw6N1WA7TVxV8kj1TE9omjLWpzFBQJOShbIpzH8hmoGTx/xuL/1ZIrYmLLxxBKGicmv1dgKLqp5YcUokb8jxhzds1xKxmnV1H+MfDaMltNErwZGlq7twgbCKpr4D2U+2xqTS+xll/ShFOL5Om/exQVeByAjjLPs+60kJVVW7Xpd5yi5M5ZKmQO4+TvTdFr3On4/fUWkIrw6r/2L9Mi9J/E1eXxOF7FIzezIDCp8uxhJPR6RAWNJSiSx7VXVSOUz4dgpFyUbOPdaxUWj+o8f3uff9dDDxHESOTdWCQlO9AOIdIe5VhJRSzZPDOs=", "solomona": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC8Z5s6NukuuhdrioJNfRSypI5+fQ3t9wPk6bgYtrJtnvlS+nDlmUAFwbky07al/UvHs8p11sAL97CqJ8Ky0k9WDRrlQm3Boj/lFrdDue+i7aZ7f//WRaMjfIiji1RP5pfrbKptzM+QLYFqoBjbv710599fbK+N2Eu2winqVxDmZk9QchlVyAE9Lc4pVVeU4IpTkVBZ1BhqCz0Y30rtAkqAPXdBskDC7NjM+bWcmBeqwQFkykEd/TThct1ZmzKk+xtEEaP8zkVVzcKoWpsovXOoCm3jTN1ZB4hNtMBiC4KWF3jNoliDmWd2s8rVsk+uuHrMa1nX4kJk8QLKu4YDYKhExCUzjBBJPjAax+5je+K8HSQ9T8vb9cE5Nu+MA9k6chxFo3MoxZte9B7bmNWeTNd99Nc4Iy4CkUDv6IMNinKka0h92Wzxp2gKbp2eP/DAxsPf7+OJ/k6a0fcJ/yjsClPuQozf4RdwZmeXgqN5FKTDP/UV2jTDM6QdTMMmEsvgi8k=", "shanef": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCykKL31U8+XMxaIZV/FpkHmJCUBXIialBrHcFAKTR/MK1nv4bs43hmJFgeO/t4eWyaRrS1PGu3NaxfnYdEAKTWDEUKG29vi4IdAeW08ECDOxZ0lszG6qel3P2hVS3njkgimwJmM/4vWYSoVf0NwRrOJVuvriZQ9oao0CCVvI7sIjE15yE4edFOzvoGfAM3sQJMI+XYwFTraNMGLxZhAdJ5U2o4huY2ZzJY+2pb6JkOX3eWJoL/MaotcwcVTTrtG9y5PHbVNjMJQJCSO71yy5TzElm4EWYS/Y4ZBSndE0uxA/dMfCtZnhereNXDvQtZcAXj4VxDtbpAKy1asw2pIa8BcTCOegaI7h1GNjBPXa7GPLfFwFmtGnVNBpVrIRaRkeI5Bd6JbhgkKUln9CgQLvoAEGwChPy+gjecgSFqE8Bplp7/CF35KkmPwlEGdBmQqHd5CBnyO3a/Paah/j4qGpHO9jFd5OzqF8B5lt437IJSSY/dT1mLszYm1RWXR1tKZjUtd+OyqoTPSG+lVQGJCid6HyPK+sYQr055Zc0DcsAHc79RR4rBR+Oe9yTm5WwvD8s52yWVBII/xqxaG8INW9PBfrkl0pGQ3aViP0Cj+9dmk6buKdtJX3P8Ca4eiRAp0KgiO3BIy8c8zf0s6+ZF8yTWtbIroWc7EOVixs4cjEzWBw== shane.forde@vesion1.com", - "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==" + "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==", + "luigid": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDED0d5x/+qAvao8fXW0fJVaF4b2WnOCisvNV8W5ua3brwh8WjOwKvLlZIVip9es9Q3KVk/bo67rRBoFYlODdoZHvH39ZcUHCZs9h7vv5PoDySXcp6UBMMUzgkO3aU2Y0aw2mwG1fTXUwuaINbkXGd/xYbD/lRYxCBbXWbKp4DwzfmQWE5nmny1RAMLDk8ZU7d2WFA2U3Kt2UAdRC6wi/luK3pQr4vOuAYaTS9PxkLArbPNsEPAcsaV8SEec0zLLBQLyIeCykcMB+8LaWmQPYdpJj50M6g5i4p7S/97ImyJE1MMXdtA0I+7stg8BaR7KqIbYE6h19OBx2aefnSDtLnTjveoQp7CvikViL4Yi8wYbZdTsNOQ6DfHfDQsO4iopi/w8z4rJqUzfOas0OaQO+oHZ69PtysJKo4pBGBY5ixpU8DrMtHZCAvm4sVLu6RqWmEU2FcoGB+fmTZvsy1fsxAKrz3OC6/AMrKQEpIxqkyU9mltfo5MgZdRWsHom9YahE8= luigi.difraia@MJ004442" }, "preproduction": { "gary": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCcsCSyHNsxAJmn6WbqeXC1DpD10CIiB2/rigClJ/wf+8bh+Q1SvYqU5N707gIlFOSSHyUiu25qcevyOItrLXemCkGTaCQ69qS5un3sB1ujDfU+2gk+z6ySL2UBGihr0hs2wQUsOhO3+v9AXjSbE11EGS0S6gM+yT43WkBTptMltpjOpC77pvi/b9Q9eEHjTGjtqbjYsUVxPCLrMwGcLQRfquLT5NAJL5vGmo2KvTTBs8qGTgwNWBkC4gTwoMHGQj71haChOiSNQpnHb1LjZPtMHmLHjrFmZsIHU6U/MlCtRwMYe08O7Men7BhMCfmEQ90dL+PPKVoEhFOILsSCBJ7jZpCKg+/1DF22WtZoDBt2b8eIxMj+V5NkN792nbWfrhZ0NUVbKChv9dW8c64ummhrjFqLi1hUEKRNGGM10hD7qgIfs64ke5TVu/pa2K2+6kjfEa8qMlMXY3EWvr1cPPKNzCzzeu233UfajqDrFhlgsB66T8kPBv2VfXF6c84sNpk= gary.grant@L0852", @@ -24,7 +25,8 @@ "tanya": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDiKUF/kiJR2ZbxB8drb0NLuHVsFV+fczWxM8eiYEUNBB2296jhf3p8KD4ffpArXW/xXhMBFPZddN/lOUGQz+GJCh3C10mi2VgzuW9x7hnSWryub3NBHguJKBIHd5zkavVYEe30d2OdpCSDbcYdNNgd9pB34K51HTDG1jBcl6VDY1g9BDrqwTBNA8l+01M+n3ev1xGgSTQdbMSY2ZApgehk4s8q1qvYtSDm8YZGO4DHLkfDy5qh+rPxFU3ghj11MY0C4sJ/ij9miGtPcNpvez/PuUQacKT3dQt7F/S59TG5KboQ7A8jnDYBAbqD6d28BLsTla9NFW5CP+E+j6B33Q8Usw96cOZ6vPaU1z4pJ6zRucd0OIJx90TvDx+ylYeX7zwJyHUxUogrUk3YXyKr/yPMSOUEnKJiHhXWr3Vgcf97zp9/gx0pHDDZZNxDlDzVJPWqfCLb5kctqOCLSzeAFfCxJcT+FqwBJ3awiI6APo2SFC5qsUJQZgeyOwFQVqN9EiM= tanya.moeller@MJ003982", "matteo": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCjBpFFRlhouHQKfiJcVmnymt4NGfUv32r0vlb2YHkj5NZMr5WP94oPO4TRAYkuoItpsVY/7KYzeB8j6YfDyzlQOaV+leopq1oal//RUIBiRcDlHU3RVpyA/+aZCeFUUFxMT0eaRirL/uqdpRhWEmga76KglUGk1toiebZHZeMGRfP96/W5rGAczMdVSXHr2fC2rvf+KRYAc6R898IMPLZQJznNoz0JLhKPB7I3NLhME5c+kPUGmuWO9G2Fvd/zbrPQoE75ZP7isDvfpqkfFndZrCYKBIjZup7Du/KIx6ISvtsRTChhU1fLGbDMIjdfAqdp5Ziaxf2sN2H2jTx68Rgg9bX6z2iZRoi5bX9Adz6SjGgEXLD+xo4nAkQqiTrC7Pj3HUKVXbqtf68B7+Yi9yb8clkpraiVruAPEsrqb9hczpMvPzdMbtBukdqZ6NSs6rPMWEJ6cdNjEEYpmc8b3lHq1Pg66ZrNOVlAUwB2mPPm7vyJ9pN3sOFLnDvRU49QXY0= matteo.pecorelli@L1464", "garthj": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCr5r6h19aPB7FUSreTO2557YBXm+LTE1i0GF7+3ktSRxuiaUvwR4XLXtoFNjMXVG5gsEgWsHph2GsKjKgOgCdbxc+06d0apSYkfu/qau8dFvFkqwpcOxR6eBsPvQoGSKsLP0oKq/P2gmy9szbV53/wD3Zt3XinQxyETlxVgFH+pcat6T5j8HUj34O3D3wYR7vBMrZPgWZJxm4iufnL56Ze/JBqZv+772Q29pV8VhGHBJuvXppUgAP1Ag/MdUtYdGvWl9M94AeVygJ64GE446+Ptc3qBMetSCNbHGLofuHokLJqBW5W1S9se7lVWVMvU2cWdos95AOlGNDXlTKGgdjxURPdItpwQjL5eh3MtzQYCeT0mVnLL6fO6pmNgHc1V5yr7gqTTbg8F8gdEliiQrZypq4KizNDEYM/zWQUXGh5Aguon3EzRKVViOzLf4sn0H5NnchO8IsvfSNvd22QFWHb6LShBr9hCmcqUqxAJWA7/P1KGDm0PyMXcw4SIn6bkXk= garthjackson@FVFGP0AAQ05P", - "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==" + "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==", + "luigid": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDED0d5x/+qAvao8fXW0fJVaF4b2WnOCisvNV8W5ua3brwh8WjOwKvLlZIVip9es9Q3KVk/bo67rRBoFYlODdoZHvH39ZcUHCZs9h7vv5PoDySXcp6UBMMUzgkO3aU2Y0aw2mwG1fTXUwuaINbkXGd/xYbD/lRYxCBbXWbKp4DwzfmQWE5nmny1RAMLDk8ZU7d2WFA2U3Kt2UAdRC6wi/luK3pQr4vOuAYaTS9PxkLArbPNsEPAcsaV8SEec0zLLBQLyIeCykcMB+8LaWmQPYdpJj50M6g5i4p7S/97ImyJE1MMXdtA0I+7stg8BaR7KqIbYE6h19OBx2aefnSDtLnTjveoQp7CvikViL4Yi8wYbZdTsNOQ6DfHfDQsO4iopi/w8z4rJqUzfOas0OaQO+oHZ69PtysJKo4pBGBY5ixpU8DrMtHZCAvm4sVLu6RqWmEU2FcoGB+fmTZvsy1fsxAKrz3OC6/AMrKQEpIxqkyU9mltfo5MgZdRWsHom9YahE8= luigi.difraia@MJ004442" }, "production": { "gary": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCcsCSyHNsxAJmn6WbqeXC1DpD10CIiB2/rigClJ/wf+8bh+Q1SvYqU5N707gIlFOSSHyUiu25qcevyOItrLXemCkGTaCQ69qS5un3sB1ujDfU+2gk+z6ySL2UBGihr0hs2wQUsOhO3+v9AXjSbE11EGS0S6gM+yT43WkBTptMltpjOpC77pvi/b9Q9eEHjTGjtqbjYsUVxPCLrMwGcLQRfquLT5NAJL5vGmo2KvTTBs8qGTgwNWBkC4gTwoMHGQj71haChOiSNQpnHb1LjZPtMHmLHjrFmZsIHU6U/MlCtRwMYe08O7Men7BhMCfmEQ90dL+PPKVoEhFOILsSCBJ7jZpCKg+/1DF22WtZoDBt2b8eIxMj+V5NkN792nbWfrhZ0NUVbKChv9dW8c64ummhrjFqLi1hUEKRNGGM10hD7qgIfs64ke5TVu/pa2K2+6kjfEa8qMlMXY3EWvr1cPPKNzCzzeu233UfajqDrFhlgsB66T8kPBv2VfXF6c84sNpk= gary.grant@L0852", @@ -34,7 +36,8 @@ "tanya": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDiKUF/kiJR2ZbxB8drb0NLuHVsFV+fczWxM8eiYEUNBB2296jhf3p8KD4ffpArXW/xXhMBFPZddN/lOUGQz+GJCh3C10mi2VgzuW9x7hnSWryub3NBHguJKBIHd5zkavVYEe30d2OdpCSDbcYdNNgd9pB34K51HTDG1jBcl6VDY1g9BDrqwTBNA8l+01M+n3ev1xGgSTQdbMSY2ZApgehk4s8q1qvYtSDm8YZGO4DHLkfDy5qh+rPxFU3ghj11MY0C4sJ/ij9miGtPcNpvez/PuUQacKT3dQt7F/S59TG5KboQ7A8jnDYBAbqD6d28BLsTla9NFW5CP+E+j6B33Q8Usw96cOZ6vPaU1z4pJ6zRucd0OIJx90TvDx+ylYeX7zwJyHUxUogrUk3YXyKr/yPMSOUEnKJiHhXWr3Vgcf97zp9/gx0pHDDZZNxDlDzVJPWqfCLb5kctqOCLSzeAFfCxJcT+FqwBJ3awiI6APo2SFC5qsUJQZgeyOwFQVqN9EiM= tanya.moeller@MJ003982", "matteo": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCjBpFFRlhouHQKfiJcVmnymt4NGfUv32r0vlb2YHkj5NZMr5WP94oPO4TRAYkuoItpsVY/7KYzeB8j6YfDyzlQOaV+leopq1oal//RUIBiRcDlHU3RVpyA/+aZCeFUUFxMT0eaRirL/uqdpRhWEmga76KglUGk1toiebZHZeMGRfP96/W5rGAczMdVSXHr2fC2rvf+KRYAc6R898IMPLZQJznNoz0JLhKPB7I3NLhME5c+kPUGmuWO9G2Fvd/zbrPQoE75ZP7isDvfpqkfFndZrCYKBIjZup7Du/KIx6ISvtsRTChhU1fLGbDMIjdfAqdp5Ziaxf2sN2H2jTx68Rgg9bX6z2iZRoi5bX9Adz6SjGgEXLD+xo4nAkQqiTrC7Pj3HUKVXbqtf68B7+Yi9yb8clkpraiVruAPEsrqb9hczpMvPzdMbtBukdqZ6NSs6rPMWEJ6cdNjEEYpmc8b3lHq1Pg66ZrNOVlAUwB2mPPm7vyJ9pN3sOFLnDvRU49QXY0= matteo.pecorelli@L1464", "garthj": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCr5r6h19aPB7FUSreTO2557YBXm+LTE1i0GF7+3ktSRxuiaUvwR4XLXtoFNjMXVG5gsEgWsHph2GsKjKgOgCdbxc+06d0apSYkfu/qau8dFvFkqwpcOxR6eBsPvQoGSKsLP0oKq/P2gmy9szbV53/wD3Zt3XinQxyETlxVgFH+pcat6T5j8HUj34O3D3wYR7vBMrZPgWZJxm4iufnL56Ze/JBqZv+772Q29pV8VhGHBJuvXppUgAP1Ag/MdUtYdGvWl9M94AeVygJ64GE446+Ptc3qBMetSCNbHGLofuHokLJqBW5W1S9se7lVWVMvU2cWdos95AOlGNDXlTKGgdjxURPdItpwQjL5eh3MtzQYCeT0mVnLL6fO6pmNgHc1V5yr7gqTTbg8F8gdEliiQrZypq4KizNDEYM/zWQUXGh5Aguon3EzRKVViOzLf4sn0H5NnchO8IsvfSNvd22QFWHb6LShBr9hCmcqUqxAJWA7/P1KGDm0PyMXcw4SIn6bkXk= garthjackson@FVFGP0AAQ05P", - "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==" + "zoltanp": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKtvsQ949K34yIp50dVyc/jAK/WlX1uuwYKPKBWybioBcuC5L+YcMc/uuZRMUFQlPxMdsWKzzQ8vaIzo05n+3Wx/TvzW/FAR8T0hI6IkkPUcv0p0lbjbFyJO9SdN2Goem8ujRkFBykON9zEfLHzFMaEmk/d8QkkIEr6sglnSr56igBWVGKkeZq74R+RyRmV0WThxq4BptfP7v2NDl8XjqdNZ5jYOT/FayqlS1Qxmsd9VjPj3BtTpf2KeOP9grsPGDTM9O4+EVSOtr/cXvJ9ELfbUj6JGtBZVG3jv+6QMfRHn66gyknzkAsyv8s6b2JY7rUuLRyxA8z+DuRiRL+K4HLvcvYdMoYaYjSU1gyPPZEoUiwSP62fBoCZr2ZibCPjkKbpBKFUgCTNsC598p9Pb5ucnnAGiKiyTyyH6xRuxpSW1Kzhby1PJ8LYJbH/Zl+083XG8HqSQONcM+eho5k6FO+8zLOWGhpByVwpsIlHHs9189YGhvbLhs+KDtYiRl2Rbryz7Oxx8/TFN6Ml1tBKcTFSIXcNhzy5yCf9nFeIS5FH/Qf/6ARJEkNGA+KEGrxlE6zvJrCnMGNoTWpV/fhZcSMhh8KEmWge2VOLl5UQ69QFgQHboj4pR+TFAwndMA7E4fBKiVgfvfhsd1KxUMvNLRaLGiYTOfOP5brNNNuiZmmmQ==", + "luigid": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDED0d5x/+qAvao8fXW0fJVaF4b2WnOCisvNV8W5ua3brwh8WjOwKvLlZIVip9es9Q3KVk/bo67rRBoFYlODdoZHvH39ZcUHCZs9h7vv5PoDySXcp6UBMMUzgkO3aU2Y0aw2mwG1fTXUwuaINbkXGd/xYbD/lRYxCBbXWbKp4DwzfmQWE5nmny1RAMLDk8ZU7d2WFA2U3Kt2UAdRC6wi/luK3pQr4vOuAYaTS9PxkLArbPNsEPAcsaV8SEec0zLLBQLyIeCykcMB+8LaWmQPYdpJj50M6g5i4p7S/97ImyJE1MMXdtA0I+7stg8BaR7KqIbYE6h19OBx2aefnSDtLnTjveoQp7CvikViL4Yi8wYbZdTsNOQ6DfHfDQsO4iopi/w8z4rJqUzfOas0OaQO+oHZ69PtysJKo4pBGBY5ixpU8DrMtHZCAvm4sVLu6RqWmEU2FcoGB+fmTZvsy1fsxAKrz3OC6/AMrKQEpIxqkyU9mltfo5MgZdRWsHom9YahE8= luigi.difraia@MJ004442" }, "default": {} } diff --git a/terraform/environments/xhibit-portal/lambda/delete_old_ami.zip b/terraform/environments/xhibit-portal/lambda/delete_old_ami.zip index b855778bf87..cf75e6c2d27 100644 Binary files a/terraform/environments/xhibit-portal/lambda/delete_old_ami.zip and b/terraform/environments/xhibit-portal/lambda/delete_old_ami.zip differ diff --git a/terraform/environments/xhibit-portal/lambda/lambda_function.zip b/terraform/environments/xhibit-portal/lambda/lambda_function.zip index ad0c1082eac..8a7ef687bd6 100644 Binary files a/terraform/environments/xhibit-portal/lambda/lambda_function.zip and b/terraform/environments/xhibit-portal/lambda/lambda_function.zip differ diff --git a/terraform/environments/xhibit-portal/shield.tf b/terraform/environments/xhibit-portal/shield.tf new file mode 100644 index 00000000000..64a20a743ad --- /dev/null +++ b/terraform/environments/xhibit-portal/shield.tf @@ -0,0 +1,27 @@ +module "shield" { + source = "../../modules/shield_advanced" + for_each = local.is-production ? { "build" = true } : {} + providers = { + aws.modernisation-platform = aws.modernisation-platform + } + application_name = local.application_name + excluded_protections = ["aec0eb6a-62b1-4433-a854-77fb8b275db5"] + resources = { + prtg_lb = { + action = "block" + arn = aws_lb.prtg_lb.arn + } + waf_lb = { + action = "block" + arn = aws_lb.waf_lb.arn + } + } + waf_acl_rules = { + example = { + "action" = "block", + "name" = "Shield-Block", + "priority" = 0, + "threshold" = "1000" + } + } +}