diff --git a/terraform/environments/analytical-platform-ingestion/data.tf b/terraform/environments/analytical-platform-ingestion/data.tf index 91807c696ae..6784374d91b 100644 --- a/terraform/environments/analytical-platform-ingestion/data.tf +++ b/terraform/environments/analytical-platform-ingestion/data.tf @@ -21,3 +21,15 @@ data "aws_secretsmanager_secret_version" "govuk_notify_templates" { data "aws_ssm_parameter" "datasync_ami" { name = "/aws/service/datasync/ami" } + +data "external" "external_ip" { + program = ["bash", "${path.module}/scripts/get-ip-address.sh"] +} + +data "dns_a_record_set" "datasync_activation_nlb" { + host = module.datasync_activation_nlb.dns_name +} + +data "aws_network_interface" "datasync_vpc_endpoint" { + id = tolist(module.connected_vpc_endpoints.endpoints["datasync"].network_interface_ids)[0] +} diff --git a/terraform/environments/analytical-platform-ingestion/datasync-agents.tf b/terraform/environments/analytical-platform-ingestion/datasync-agents.tf index d5b70ef1b8a..8c0b289ea59 100644 --- a/terraform/environments/analytical-platform-ingestion/datasync-agents.tf +++ b/terraform/environments/analytical-platform-ingestion/datasync-agents.tf @@ -1,8 +1,16 @@ -# resource "aws_datasync_agent" "main" { -# name = "${local.application_name}-${local.environment}-datasync" -# ip_address = module.datasync_instance.private_ip +resource "aws_datasync_agent" "main" { + name = "${local.application_name}-${local.environment}-datasync" + ip_address = data.dns_a_record_set.datasync_activation_nlb.addrs[0] -# tags = local.tags + subnet_arns = [module.connected_vpc.private_subnet_arns[0]] + vpc_endpoint_id = module.connected_vpc_endpoints.endpoints["datasync"].id + security_group_arns = [module.datasync_task_eni_security_group.security_group_arn] + private_link_endpoint = data.aws_network_interface.datasync_vpc_endpoint.private_ip -# depends_on = [module.datasync_instance] -# } + tags = local.tags + + depends_on = [ + module.datasync_instance, + module.datasync_activation_nlb_security_group + ] +} diff --git a/terraform/environments/analytical-platform-ingestion/ec2-instances.tf b/terraform/environments/analytical-platform-ingestion/ec2-instances.tf index 4b40b45d9fc..794181c6d31 100644 --- a/terraform/environments/analytical-platform-ingestion/ec2-instances.tf +++ b/terraform/environments/analytical-platform-ingestion/ec2-instances.tf @@ -8,8 +8,8 @@ module "datasync_instance" { ami = data.aws_ssm_parameter.datasync_ami.value instance_type = "m5.2xlarge" subnet_id = element(module.connected_vpc.private_subnets, 0) - vpc_security_group_ids = [module.datasync_security_group.security_group_id] - + vpc_security_group_ids = [module.datasync_instance_security_group.security_group_id] + private_ip = local.environment_configuration.datasync_instance_private_ip metadata_options = { http_endpoint = "enabled" @@ -18,17 +18,25 @@ module "datasync_instance" { instance_metadata_tags = "enabled" } + enable_volume_tags = false root_block_device = [ { encrypted = true kms_key_id = module.ec2_ebs_kms.key_arn volume_type = "gp2" - volume_size = 80 + volume_size = 200 + tags = merge( + local.tags, + { Name = "${local.application_name}-${local.environment}-datasync-root" } + ) } ] tags = merge( local.tags, - { Name = "${local.application_name}-${local.environment}-datasync" } + { + Name = "${local.application_name}-${local.environment}-datasync" + instance-scheduling = "skip-scheduling" # TEMPORARY + } ) } diff --git a/terraform/environments/analytical-platform-ingestion/environment-configuration.tf b/terraform/environments/analytical-platform-ingestion/environment-configuration.tf index 255f6ae1150..6e93a64c0a6 100644 --- a/terraform/environments/analytical-platform-ingestion/environment-configuration.tf +++ b/terraform/environments/analytical-platform-ingestion/environment-configuration.tf @@ -35,6 +35,9 @@ locals { egress_bucket_kms_key = module.s3_bold_egress_kms.key_arn } } + + /* DataSync */ + datasync_instance_private_ip = "10.26.128.5" } production = { /* VPC */ @@ -70,6 +73,9 @@ locals { egress_bucket_kms_key = module.s3_bold_egress_kms.key_arn } } + + /* DataSync */ + datasync_instance_private_ip = "10.27.128.5" } } } diff --git a/terraform/environments/analytical-platform-ingestion/network-load-balancers.tf b/terraform/environments/analytical-platform-ingestion/network-load-balancers.tf new file mode 100644 index 00000000000..a74d488cebd --- /dev/null +++ b/terraform/environments/analytical-platform-ingestion/network-load-balancers.tf @@ -0,0 +1,37 @@ +module "datasync_activation_nlb" { + #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions + + source = "terraform-aws-modules/alb/aws" + version = "9.11.0" + + name = "datasync-activation" + + load_balancer_type = "network" + vpc_id = module.connected_vpc.vpc_id + subnets = [module.connected_vpc.public_subnets[0]] + create_security_group = false + security_groups = [module.datasync_activation_nlb_security_group.security_group_id] + + target_groups = { + datasync = { + name_prefix = "ds-" + protocol = "TCP" + port = 80 + target_type = "ip" + target_id = local.environment_configuration.datasync_instance_private_ip + deregistration_delay = 10 + } + } + + listeners = { + datasync = { + port = 80 + protocol = "TCP" + forward = { + target_group_key = "datasync" + } + } + } + + tags = local.tags +} diff --git a/terraform/environments/analytical-platform-ingestion/platform_versions.tf b/terraform/environments/analytical-platform-ingestion/platform_versions.tf index 6161ef3bc02..e0be94cf750 100644 --- a/terraform/environments/analytical-platform-ingestion/platform_versions.tf +++ b/terraform/environments/analytical-platform-ingestion/platform_versions.tf @@ -4,6 +4,14 @@ terraform { version = "~> 5.0" source = "hashicorp/aws" } + dns = { + version = "~> 3.0" + source = "hashicorp/dns" + } + external = { + version = "~> 2.0" + source = "hashicorp/external" + } http = { version = "~> 3.0" source = "hashicorp/http" diff --git a/terraform/environments/analytical-platform-ingestion/scripts/get-ip-address.sh b/terraform/environments/analytical-platform-ingestion/scripts/get-ip-address.sh new file mode 100644 index 00000000000..be7f4dc2478 --- /dev/null +++ b/terraform/environments/analytical-platform-ingestion/scripts/get-ip-address.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# Get IP address via Cloudflare +ip="$(curl --silent https://cloudflare.com/cdn-cgi/trace | awk -F= '/ip=/{print $2}')" + +# Return it as a JSON object +echo "{\"ip\": \"${ip}\"}" \ No newline at end of file diff --git a/terraform/environments/analytical-platform-ingestion/security-groups.tf b/terraform/environments/analytical-platform-ingestion/security-groups.tf index b4d9ad5d1b4..ae976987b0c 100644 --- a/terraform/environments/analytical-platform-ingestion/security-groups.tf +++ b/terraform/environments/analytical-platform-ingestion/security-groups.tf @@ -20,6 +20,7 @@ resource "aws_security_group" "transfer_server" { description = "Security Group for Transfer Server" name = "transfer-server" vpc_id = module.isolated_vpc.vpc_id + tags = local.tags } #tfsec:ignore:avd-aws-0104 - The security group is attached to the resource @@ -77,25 +78,113 @@ module "scan_lambda_security_group" { tags = local.tags } -module "datasync_security_group" { +module "datasync_activation_nlb_security_group" { + #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions + + source = "terraform-aws-modules/security-group/aws" + version = "5.2.0" + + name = "${local.application_name}-${local.environment}-datasync-activation-nlb" + description = "Security Group for DataSync Activation NLB" + + vpc_id = module.connected_vpc.vpc_id + + egress_cidr_blocks = ["${local.environment_configuration.datasync_instance_private_ip}/32"] + egress_rules = ["http-80-tcp",] + + ingress_cidr_blocks = ["${data.external.external_ip.result["ip"]}/32"] + ingress_rules = ["http-80-tcp"] + + tags = local.tags +} + +module "datasync_vpc_endpoint_security_group" { #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions source = "terraform-aws-modules/security-group/aws" version = "5.2.0" - name = "${local.application_name}-${local.environment}-datasync" + name = "${local.application_name}-${local.environment}-datasync-vpc-endpoint" + description = "Security Group for DataSync VPC Endpoint" + + vpc_id = module.connected_vpc.vpc_id + + ingress_with_cidr_blocks = [ + { + from_port = 1024 + to_port = 1064 + protocol = "tcp" + description = "DataSync Control Plane" + cidr_blocks = module.connected_vpc.vpc_cidr_block + } + ] + + tags = local.tags +} + +module "datasync_task_eni_security_group" { + #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions + + source = "terraform-aws-modules/security-group/aws" + version = "5.2.0" + + name = "${local.application_name}-${local.environment}-datasync-task-eni" + description = "Security Group for DataSync Task ENIs" + + vpc_id = module.connected_vpc.vpc_id + + ingress_with_cidr_blocks = [ + { + from_port = 443 + to_port = 443 + protocol = "tcp" + description = "DataSync Data Plane" + cidr_blocks = module.connected_vpc.vpc_cidr_block + } + ] + + tags = local.tags +} + +module "datasync_instance_security_group" { + #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions + + source = "terraform-aws-modules/security-group/aws" + version = "5.2.0" + + name = "${local.application_name}-${local.environment}-datasync-instance" description = "Security Group for DataSync Instance" vpc_id = module.connected_vpc.vpc_id - egress_cidr_blocks = [module.connected_vpc.vpc_cidr_block] - egress_rules = ["https-443-tcp"] + egress_with_source_security_group_id = [ + { + from_port = 1024 + to_port = 1064 + protocol = "tcp" + description = "DataSync Control Plane" + source_security_group_id = module.datasync_vpc_endpoint_security_group.security_group_id + }, + { + from_port = 443 + to_port = 443 + protocol = "tcp" + description = "DataSync Data Plane" + source_security_group_id = module.datasync_task_eni_security_group.security_group_id + } + ] - ingress_cidr_blocks = [module.connected_vpc.vpc_cidr_block] - ingress_rules = [ - "http-80-tcp", - "https-443-tcp" + ingress_with_source_security_group_id = [ + { + rule = "http-80-tcp" + source_security_group_id = module.datasync_activation_nlb_security_group.security_group_id + } ] tags = local.tags } + +moved { + from = module.datasync_security_group + to = module.datasync_instance_security_group +} diff --git a/terraform/environments/analytical-platform-ingestion/vpc-endpoints.tf b/terraform/environments/analytical-platform-ingestion/vpc-endpoints.tf index 21a6db8ebff..1fe203fce84 100644 --- a/terraform/environments/analytical-platform-ingestion/vpc-endpoints.tf +++ b/terraform/environments/analytical-platform-ingestion/vpc-endpoints.tf @@ -4,15 +4,19 @@ module "connected_vpc_endpoints" { source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints" version = "5.13.0" - vpc_id = module.connected_vpc.vpc_id - subnet_ids = module.connected_vpc.private_subnets - security_group_ids = [aws_security_group.connected_vpc_endpoints.id] + vpc_id = module.connected_vpc.vpc_id + subnet_ids = module.connected_vpc.private_subnets + # security_group_ids = [aws_security_group.connected_vpc_endpoints.id] endpoints = { datasync = { service = "datasync" service_type = "Interface" private_dns_enabled = true + security_group_ids = [ + module.datasync_vpc_endpoint_security_group.security_group_id, + module.datasync_task_eni_security_group.security_group_id + ] tags = merge( local.tags, { Name = format("%s-datasync", "${local.application_name}-${local.environment}-connected") }