diff --git a/modules/postgres-restore/download_sg.tf b/modules/postgres-restore/download_sg.tf new file mode 100644 index 00000000..efcca3df --- /dev/null +++ b/modules/postgres-restore/download_sg.tf @@ -0,0 +1,20 @@ +resource "aws_security_group" "migrate_download_task" { + name = "${var.resource_name_prefixes.normal}:PGRESTORE:${upper(var.restore_name)}:ECSTASK:DOWNLOAD" + description = "Restore Download task" + vpc_id = var.vpc_id + + tags = { + Name = "${var.resource_name_prefixes.normal}:PGRESTORE:${upper(var.restore_name)}:ECSTASK:DOWNLOAD" + } +} + +resource "aws_security_group_rule" "migrate_download_task_https_out_anywhere" { + cidr_blocks = ["0.0.0.0/0"] + description = "Allow https out from download task to anywhere" + from_port = 443 + protocol = "tcp" + security_group_id = aws_security_group.migrate_download_task.id + to_port = 443 + type = "egress" +} + diff --git a/modules/postgres-restore/download_task.tf b/modules/postgres-restore/download_task.tf new file mode 100644 index 00000000..7a959ba7 --- /dev/null +++ b/modules/postgres-restore/download_task.tf @@ -0,0 +1,49 @@ +module "download_task" { + source = "../../resource-groups/ecs-fargate-task-definition" + + aws_account_id = var.aws_account_id + aws_region = var.aws_region + container_definitions = { + pg_dump = { + cpu = var.download_task_cpu + environment_variables = [] + essential = true + healthcheck_command = null + image = var.cf_config.cf_cli_docker_image + memory = var.download_task_memory + mounts = [ + { + mount_point = "/mnt/efs0" + read_only = false + volume_name = "efs0" + } + ] + # N.B. $DUMP_FILENAME is injected by the Step Function task + override_command = [ + "sh", "-c", + "apk update && apk add --no-cache postgresql-client && cf install-plugin -f conduit && rm -rf $DUMP_FILENAME && cf login -a ${var.cf_config.api_endpoint} -u $CF_USERNAME -p $CF_PASSWORD -o ${var.cf_config.org} -s ${var.cf_config.space} && cf conduit --app-name ccs-${var.restore_name}-migration-pg-dump-$RANDOM ${var.cf_config.db_service_instance} -- pg_dump -j ${var.download_task_pgdump_workers} -Fd --file $DUMP_FILENAME --no-acl --no-owner" + ] + port = null + # ECS Execution role will need access to these - see aws_iam_role_policy.ecs_execution_role__read_cf_creds_ssm + secret_environment_variables = [ + { "name" : "CF_PASSWORD", "valueFrom" : aws_ssm_parameter.cf_password.arn }, + { "name" : "CF_USERNAME", "valueFrom" : aws_ssm_parameter.cf_username.arn } + ] + } + } + ecs_execution_role_arn = var.ecs_execution_role.arn + family_name = "pg_migrate_${var.restore_name}_download" + task_cpu = var.download_task_cpu + task_memory = var.download_task_memory + volumes = [ + { + access_point_id = aws_efs_access_point.db_dump.id + file_system_id = aws_efs_file_system.db_dump.id + volume_name = "efs0" + } + ] + + depends_on = [ + aws_efs_mount_target.db_dump + ] +} diff --git a/modules/postgres-restore/ecs_execution_role_policies.tf b/modules/postgres-restore/ecs_execution_role_policies.tf new file mode 100644 index 00000000..f03c724b --- /dev/null +++ b/modules/postgres-restore/ecs_execution_role_policies.tf @@ -0,0 +1,18 @@ +# Permissions which need to be granted to the main project's ECS Execution role +# +data "aws_iam_policy_document" "restore_policy" { + version = "2012-10-17" + # We are expecting repeated Sids of "DescribeAllLogGroups", hence `overwrite` rather than `source` + override_policy_documents = [ + # Main ECS execution role needs access to decrypt and inject SSM params as env vars + # module.table_rows_target.write_task_logs_policy_document_json, + module.download_task.write_task_logs_policy_document_json, + module.restore_task.write_task_logs_policy_document_json, + ] +} + +resource "aws_iam_role_policy" "ecs_execution_role__restore_policy" { + name = "${var.restore_name}-restore-policy" + role = var.ecs_execution_role.name + policy = data.aws_iam_policy_document.restore_policy.json +} diff --git a/modules/postgres-restore/efs.tf b/modules/postgres-restore/efs.tf new file mode 100644 index 00000000..023eed52 --- /dev/null +++ b/modules/postgres-restore/efs.tf @@ -0,0 +1,109 @@ +resource "aws_efs_file_system" "db_restore" { + encrypted = true + + tags = { + "Name" = "${var.resource_name_prefixes.normal}:PGRESTORE:${upper(var.restore_name)}" + "TYPE" = "EFS" + } + + throughput_mode = "elastic" +} + +resource "aws_efs_access_point" "db_restore" { + file_system_id = aws_efs_file_system.db_restore.id + + posix_user { + gid = 0 + uid = 0 + } + + root_directory { + creation_info { + owner_gid = 0 + owner_uid = 0 + permissions = "700" + } + path = "/pgmigrate" + } + + tags = { + "Name" = "${var.resource_name_prefixes.normal}:PGRESTORE:${upper(var.restore_name)}" + } +} + +resource "aws_efs_file_system_policy" "db_restore" { + file_system_id = aws_efs_file_system.db_restore.id + + policy = <