Skip to content

Commit eab32a5

Browse files
CCM-8861: SFTP poll (#419)
1 parent e22fb61 commit eab32a5

25 files changed

+648
-47
lines changed

infrastructure/terraform/modules/backend-api/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ No requirements.
4242
| <a name="module_lambda_delete_failed_scanned_object"></a> [lambda\_delete\_failed\_scanned\_object](#module\_lambda\_delete\_failed\_scanned\_object) | ../lambda-function | n/a |
4343
| <a name="module_lambda_send_letter_proof"></a> [lambda\_send\_letter\_proof](#module\_lambda\_send\_letter\_proof) | ../lambda-function | n/a |
4444
| <a name="module_lambda_set_file_virus_scan_status"></a> [lambda\_set\_file\_virus\_scan\_status](#module\_lambda\_set\_file\_virus\_scan\_status) | ../lambda-function | n/a |
45+
| <a name="module_lambda_sftp_poll"></a> [lambda\_sftp\_poll](#module\_lambda\_sftp\_poll) | ../lambda-function | n/a |
4546
| <a name="module_lambda_validate_letter_template_files"></a> [lambda\_validate\_letter\_template\_files](#module\_lambda\_validate\_letter\_template\_files) | ../lambda-function | n/a |
4647
| <a name="module_list_template_lambda"></a> [list\_template\_lambda](#module\_list\_template\_lambda) | ../lambda-function | n/a |
4748
| <a name="module_s3bucket_internal"></a> [s3bucket\_internal](#module\_s3bucket\_internal) | git::https://github.com/NHSDigital/nhs-notify-shared-modules.git//infrastructure/modules/s3bucket | v1.0.8 |

infrastructure/terraform/modules/backend-api/api_gateway_rest_api_main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ resource "aws_api_gateway_rest_api" "main" {
44
description = "Templates API"
55
disable_execute_api_endpoint = false
66

7-
binary_media_types = [ "multipart/form-data" ]
7+
binary_media_types = ["multipart/form-data"]
88
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
resource "aws_cloudwatch_event_rule" "sftp_poll" {
2+
for_each = var.letter_suppliers
3+
4+
name = "${local.csi}-sftp-poll-${lower(each.key)}"
5+
schedule_expression = "rate(1 hour)" # Runs at the top of every hour
6+
7+
state = each.value.enable_polling ? "ENABLED" : "DISABLED"
8+
}
9+
10+
resource "aws_cloudwatch_event_target" "sftp_poll" {
11+
for_each = var.letter_suppliers
12+
rule = aws_cloudwatch_event_rule.sftp_poll[each.key].name
13+
arn = module.lambda_sftp_poll.function_arn
14+
15+
input = jsonencode({
16+
supplier : each.key
17+
})
18+
}
19+
20+
resource "aws_lambda_permission" "allow_cloudwatch" {
21+
for_each = var.letter_suppliers
22+
statement_id = "AllowExecutionFromCloudWatch${each.key}"
23+
action = "lambda:InvokeFunction"
24+
function_name = module.lambda_sftp_poll.function_name
25+
principal = "events.amazonaws.com"
26+
source_arn = aws_cloudwatch_event_rule.sftp_poll[each.key].arn
27+
}

infrastructure/terraform/modules/backend-api/guardduty_malware_protection_plan_quarantine.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ resource "aws_guardduty_malware_protection_plan" "quarantine" {
44
protected_resource {
55
s3_bucket {
66
bucket_name = module.s3bucket_quarantine.id
7-
object_prefixes = ["pdf-template/", "test-data/"]
7+
object_prefixes = ["pdf-template/", "test-data/", "proofs/"]
88
}
99
}
1010

infrastructure/terraform/modules/backend-api/module_build_sftp_letters_lambdas.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ module "build_sftp_letters_lambdas" {
55

66
entrypoints = [
77
"src/send-proof.ts",
8+
"src/sftp-poll.ts",
89
]
910
}

infrastructure/terraform/modules/backend-api/module_lambda_send_letter_proof.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ module "lambda_send_letter_proof" {
1717
environment_variables = {
1818
CREDENTIALS_TTL_SECONDS = 900
1919
CSI = local.csi
20-
ENVIRONMENT = var.environment
2120
INTERNAL_BUCKET_NAME = module.s3bucket_internal.id
2221
NODE_OPTIONS = "--enable-source-maps",
2322
REGION = var.region
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
module "lambda_sftp_poll" {
2+
source = "../lambda-function"
3+
description = "Lambda to poll the SFTP suppliers and copy proofs to the quarantine bucket"
4+
5+
function_name = "${local.csi}-sftp-poll"
6+
filename = module.build_sftp_letters_lambdas.zips["src/sftp-poll.ts"].path
7+
source_code_hash = module.build_sftp_letters_lambdas.zips["src/sftp-poll.ts"].base64sha256
8+
handler = "sftp-poll.handler"
9+
10+
log_retention_in_days = var.log_retention_in_days
11+
12+
execution_role_policy_document = data.aws_iam_policy_document.sftp_poll.json
13+
14+
environment_variables = {
15+
CREDENTIALS_TTL_SECONDS = 900
16+
CSI = local.csi
17+
QUARANTINE_BUCKET_NAME = module.s3bucket_quarantine.id
18+
NODE_OPTIONS = "--enable-source-maps",
19+
REGION = var.region
20+
SFTP_ENVIRONMENT = local.sftp_environment
21+
}
22+
23+
timeout = 60 * 10
24+
memory_size = 2048
25+
}
26+
27+
data "aws_iam_policy_document" "sftp_poll" {
28+
29+
statement {
30+
sid = "AllowS3"
31+
effect = "Allow"
32+
33+
actions = [
34+
"s3:PutObject",
35+
]
36+
37+
resources = ["${module.s3bucket_quarantine.arn}/*"]
38+
}
39+
40+
statement {
41+
sid = "AllowSSMParameterRead"
42+
effect = "Allow"
43+
actions = [
44+
"ssm:GetParameter",
45+
]
46+
resources = [
47+
"arn:aws:ssm:${var.region}:${var.aws_account_id}:parameter/${local.csi}/sftp-config/*",
48+
]
49+
}
50+
51+
statement {
52+
sid = "AllowKMSAccess"
53+
effect = "Allow"
54+
55+
actions = [
56+
"kms:Decrypt",
57+
"kms:DescribeKey",
58+
"kms:Encrypt",
59+
"kms:GenerateDataKey*",
60+
"kms:ReEncrypt*",
61+
]
62+
63+
resources = [
64+
var.kms_key_arn
65+
]
66+
}
67+
}

infrastructure/terraform/modules/lambda-function/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ No modules.
3232
| Name | Description |
3333
|------|-------------|
3434
| <a name="output_function_arn"></a> [function\_arn](#output\_function\_arn) | n/a |
35+
| <a name="output_function_name"></a> [function\_name](#output\_function\_name) | n/a |
3536
<!-- vale on -->
3637
<!-- markdownlint-enable -->
3738
<!-- END_TF_DOCS -->
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
output "function_arn" {
22
value = aws_lambda_function.main.arn
33
}
4+
output "function_name" {
5+
value = aws_lambda_function.main.function_name
6+
}

lambdas/sftp-letters/package.json

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
{
2-
"name": "nhs-notify-sftp-letters-lambdas",
3-
"version": "0.0.1",
4-
"private": true,
5-
"scripts": {
6-
"test:unit": "jest",
7-
"lint": "eslint .",
8-
"lint:fix": "eslint . --fix",
9-
"typecheck": "tsc --noEmit"
2+
"dependencies": {
3+
"@aws-sdk/client-dynamodb": "3.775.0",
4+
"@aws-sdk/client-s3": "3.775.0",
5+
"@aws-sdk/client-ssm": "3.775.0",
6+
"@aws-sdk/lib-dynamodb": "3.775.0",
7+
"csv-parse": "^5.6.0",
8+
"csv-stringify": "^6.4.4",
9+
"date-fns": "^4.1.0",
10+
"ksuid": "^3.0.0",
11+
"nhs-notify-entity-update-command-builder": "*",
12+
"nhs-notify-web-template-management-utils": "*",
13+
"node-cache": "^5.1.2",
14+
"ssh2-sftp-client": "^9.1.0",
15+
"zod": "^3.24.2"
1016
},
1117
"devDependencies": {
1218
"@swc/core": "^1.11.3",
@@ -20,24 +26,18 @@
2026
"esbuild": "^0.24.0",
2127
"jest": "^29.7.0",
2228
"jest-mock-extended": "^3.0.7",
29+
"nhs-notify-web-template-management-test-helper-utils": "*",
2330
"ts-jest": "^29.3.0",
2431
"ts-node": "^10.9.2",
2532
"typescript": "^5.8.2"
2633
},
27-
"dependencies": {
28-
"@aws-sdk/client-dynamodb": "3.775.0",
29-
"@aws-sdk/client-s3": "3.775.0",
30-
"@aws-sdk/client-ssm": "3.775.0",
31-
"@aws-sdk/lib-dynamodb": "3.775.0",
32-
"csv-parse": "^5.6.0",
33-
"csv-stringify": "^6.4.4",
34-
"date-fns": "^4.1.0",
35-
"ksuid": "^3.0.0",
36-
"nhs-notify-entity-update-command-builder": "*",
37-
"nhs-notify-web-template-management-test-helper-utils": "*",
38-
"nhs-notify-web-template-management-utils": "*",
39-
"node-cache": "^5.1.2",
40-
"ssh2-sftp-client": "^9.1.0",
41-
"zod": "^3.24.2"
42-
}
34+
"name": "nhs-notify-sftp-letters-lambdas",
35+
"private": true,
36+
"scripts": {
37+
"lint": "eslint .",
38+
"lint:fix": "eslint . --fix",
39+
"test:unit": "jest",
40+
"typecheck": "tsc --noEmit"
41+
},
42+
"version": "0.0.1"
4343
}

0 commit comments

Comments
 (0)