Skip to content

Commit e3e35dd

Browse files
CCM-12607 add letter pdf TTL functionality (#67)
* CCM-12607: add ttl-poll-lambda code and utils * CCM-12607: add ttl-create-lambda code * CCM-12607: ttl-poll-lambda linted * CCM-12607: terraform bits * CCM-12607: remove write shards from poller * CCM-12607: move ttl terraform into dl * CCM-12607: enable point in time recovery for the table * CCM-12607: sonar config tweaks * CCM-12607: rename test folders * CCM-12607: sonar config tweaks * CCM-12607: sonar config tweaks * CCM-12607: sonar config tweaks * CCM-12607: correction for log streaming destination address * CCM-12607: Devcontainer tweaks * CCM-12607: Enable typecheck and linting in CI workflow * CCM-12607: Fix linting errors * CCM-12607: Address TF review comments * CCM-12607: Address ttl-create-lambda review comments * CCM-12607: Update ttl-create-lambda package name * CCM-12607: ttl-poll-lambda review changes * CCM-12607: Added additional unit tests * CCM-12607: Address Sonar issues * CCM-12607: Fix one more Sonar issue * CCM-12607: Tweak ttl-expiry-service test --------- Co-authored-by: Gareth Allan <[email protected]>
1 parent fd19c47 commit e3e35dd

File tree

108 files changed

+15759
-4404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+15759
-4404
lines changed

.devcontainer/old/devcontainer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"github.remotehub",
2424
"github.vscode-github-actions",
2525
"github.vscode-pull-request-github",
26+
"hashicorp.terraform",
2627
"hediet.vscode-drawio",
2728
"johnpapa.vscode-peacock",
2829
"joshx.workspace-terminals",
@@ -91,6 +92,7 @@
9192
"mounts": [
9293
"source=${localEnv:HOME}/.gnupg,target=/home/vscode/.gnupg,type=bind,consistency=cached",
9394
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached",
95+
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,consistency=cached",
9496
"source=/usr/local/share/ca-certificates,target=/home/ca-certificates,type=bind,consistency=cached"
9597
],
9698
"name": "NHS Notify Digital Letters",

eslint.config.mjs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ export default defineConfig([
7777
'import-x/resolver-next': [
7878
eslintImportResolverTypescript.createTypeScriptImportResolver({
7979
project: [
80-
'frontend/tsconfig.json',
8180
'lambdas/*/tsconfig.json',
8281
'tests/test-team/tsconfig.json',
8382
'utils/*/tsconfig.json',
@@ -140,7 +139,7 @@ export default defineConfig([
140139

141140
// prettier
142141
prettierRecommended,
143-
{ rules: { ...prettierConfigRules, 'prettier/prettier': 2 } },
142+
{ rules: { ...prettierConfigRules, 'prettier/prettier': ['error', { singleQuote: true }] } },
144143

145144
// jsxA11y
146145
{
@@ -169,20 +168,6 @@ export default defineConfig([
169168
plugins: { html },
170169
},
171170

172-
// Next.js
173-
...compat.config({
174-
extends: ['next', 'next/core-web-vitals', 'next/typescript'],
175-
settings: {
176-
next: {
177-
rootDir: 'frontend',
178-
},
179-
},
180-
rules: {
181-
// needed because next lint rules look for a pages directory
182-
'@next/next/no-html-link-for-pages': 0,
183-
},
184-
}),
185-
186171
// json
187172
{
188173
files: ['**/*.json'],
@@ -243,6 +228,12 @@ export default defineConfig([
243228
'no-relative-import-paths/no-relative-import-paths': 2,
244229
},
245230
},
231+
{
232+
files: ['utils/**'],
233+
rules: {
234+
'no-relative-import-paths/no-relative-import-paths': 0,
235+
},
236+
},
246237
{
247238
files: ['scripts/**'],
248239
rules: {

infrastructure/terraform/components/.gitkeep

Whitespace-only changes.

infrastructure/terraform/components/dl/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ No requirements.
1111
|------|-------------|------|---------|:--------:|
1212
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
1313
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no |
14+
| <a name="input_enable_dynamodb_delete_protection"></a> [enable\_dynamodb\_delete\_protection](#input\_enable\_dynamodb\_delete\_protection) | Enable DynamoDB Delete Protection on all Tables | `bool` | `true` | no |
1415
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
1516
| <a name="input_force_lambda_code_deploy"></a> [force\_lambda\_code\_deploy](#input\_force\_lambda\_code\_deploy) | If the lambda package in s3 has the same commit id tag as the terraform build branch, the lambda will not update automatically. Set to True if making changes to Lambda code from on the same commit for example during development | `bool` | `false` | no |
1617
| <a name="input_group"></a> [group](#input\_group) | The group variables are being inherited from (often synonmous with account short-name) | `string` | n/a | yes |
@@ -20,14 +21,21 @@ No requirements.
2021
| <a name="input_mesh_poll_schedule"></a> [mesh\_poll\_schedule](#input\_mesh\_poll\_schedule) | Schedule to poll MESH for messages | `string` | `"cron(0,30 8-16 ? * MON-FRI *)"` | no |
2122
| <a name="input_parent_acct_environment"></a> [parent\_acct\_environment](#input\_parent\_acct\_environment) | Name of the environment responsible for the acct resources used, affects things like DNS zone. Useful for named dev environments | `string` | `"main"` | no |
2223
| <a name="input_project"></a> [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes |
24+
| <a name="input_queue_batch_size"></a> [queue\_batch\_size](#input\_queue\_batch\_size) | maximum number of queue items to process | `number` | `10` | no |
25+
| <a name="input_queue_batch_window_seconds"></a> [queue\_batch\_window\_seconds](#input\_queue\_batch\_window\_seconds) | maximum time in seconds between processing events | `number` | `10` | no |
2326
| <a name="input_region"></a> [region](#input\_region) | The AWS Region | `string` | n/a | yes |
27+
| <a name="input_shared_infra_account_id"></a> [shared\_infra\_account\_id](#input\_shared\_infra\_account\_id) | The AWS Shared Infra Account ID (numeric) | `string` | n/a | yes |
28+
| <a name="input_ttl_poll_schedule"></a> [ttl\_poll\_schedule](#input\_ttl\_poll\_schedule) | Schedule to poll for any overdue TTL records | `string` | `"rate(10 minutes)"` | no |
2429
## Modules
2530

2631
| Name | Source | Version |
2732
|------|--------|---------|
28-
| <a name="module_kms"></a> [kms](#module\_kms) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.20/terraform-kms.zip | n/a |
33+
| <a name="module_kms"></a> [kms](#module\_kms) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-kms.zip | n/a |
2934
| <a name="module_mesh_poll"></a> [mesh\_poll](#module\_mesh\_poll) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
3035
| <a name="module_s3bucket_letters"></a> [s3bucket\_letters](#module\_s3bucket\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-s3bucket.zip | n/a |
36+
| <a name="module_sqs_ttl"></a> [sqs\_ttl](#module\_sqs\_ttl) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
37+
| <a name="module_ttl_create"></a> [ttl\_create](#module\_ttl\_create) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
38+
| <a name="module_ttl_poll"></a> [ttl\_poll](#module\_ttl\_poll) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
3139
## Outputs
3240

3341
No outputs.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
resource "aws_dynamodb_table" "ttl" {
2+
name = "${local.csi}-ttl"
3+
billing_mode = "PAY_PER_REQUEST"
4+
hash_key = "PK"
5+
range_key = "SK"
6+
7+
deletion_protection_enabled = var.enable_dynamodb_delete_protection
8+
9+
attribute {
10+
name = "PK"
11+
type = "S"
12+
}
13+
14+
attribute {
15+
name = "SK"
16+
type = "S"
17+
}
18+
19+
attribute {
20+
name = "dateOfExpiry"
21+
type = "S"
22+
}
23+
24+
attribute {
25+
name = "ttl"
26+
type = "N"
27+
}
28+
29+
ttl {
30+
enabled = true
31+
attribute_name = "ttl"
32+
}
33+
34+
point_in_time_recovery {
35+
enabled = true
36+
}
37+
38+
global_secondary_index {
39+
name = "dateOfExpiryIndex"
40+
hash_key = "dateOfExpiry"
41+
projection_type = "ALL"
42+
range_key = "ttl"
43+
}
44+
45+
server_side_encryption {
46+
enabled = true
47+
kms_key_arn = module.kms.key_arn
48+
}
49+
50+
stream_enabled = true
51+
stream_view_type = "OLD_IMAGE"
52+
53+
tags = local.default_tags
54+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "aws_lambda_event_source_mapping" "ttl_create_lambda" {
2+
event_source_arn = module.sqs_ttl.sqs_queue_arn
3+
function_name = module.ttl_create.function_name
4+
batch_size = var.queue_batch_size
5+
maximum_batching_window_in_seconds = var.queue_batch_window_seconds
6+
function_response_types = [
7+
"ReportBatchItemFailures"
8+
]
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
locals {
22
aws_lambda_functions_dir_path = "../../../../lambdas"
3+
log_destination_arn = "arn:aws:logs:${var.region}:${var.shared_infra_account_id}:destination:nhs-main-obs-firehose-logs"
4+
5+
ttl_shard_count = 3
36
}

infrastructure/terraform/components/dl/module_kms.tf

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module "kms" {
2-
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.20/terraform-kms.zip"
2+
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-kms.zip"
33

44

55
providers = {
@@ -70,10 +70,12 @@ data "aws_iam_policy_document" "kms" {
7070
test = "ArnLike"
7171
variable = "kms:EncryptionContext:aws:sqs:arn"
7272
values = [
73-
"arn:aws:sqs:${var.region}:${var.aws_account_id}:${var.project}-${var.environment}-*",
73+
"arn:aws:sqs:${var.region}:${var.aws_account_id}:${var.project}-${var.environment}-ttl-queue",
74+
"arn:aws:sqs:${var.region}:${var.aws_account_id}:${var.project}-${var.environment}-ttl-dlq",
7475
]
7576
}
7677
}
78+
7779
statement {
7880
sid = "AllowCloudWatchLogsEncrypt"
7981
effect = "Allow"
@@ -97,4 +99,24 @@ data "aws_iam_policy_document" "kms" {
9799
"*",
98100
]
99101
}
102+
103+
statement {
104+
sid = "AllowDynamoDBEncryption"
105+
effect = "Allow"
106+
107+
principals {
108+
type = "Service"
109+
identifiers = ["dynamodb.amazonaws.com"]
110+
}
111+
112+
actions = [
113+
"kms:Encrypt",
114+
"kms:Decrypt",
115+
"kms:ReEncrypt*",
116+
"kms:GenerateDataKey*",
117+
"kms:Describe*"
118+
]
119+
120+
resources = ["*"]
121+
}
100122
}

infrastructure/terraform/components/dl/module_lambda_mesh_poll.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ module "mesh_poll" {
3232
force_lambda_code_deploy = var.force_lambda_code_deploy
3333
enable_lambda_insights = false
3434

35+
send_to_firehose = true
36+
log_destination_arn = local.log_destination_arn
37+
log_subscription_role_arn = local.acct.log_subscription_role_arn
38+
3539
lambda_env_vars = {
3640
}
3741
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
module "ttl_create" {
2+
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip"
3+
4+
function_name = "ttl-create"
5+
description = "A function for creating TTL records"
6+
7+
aws_account_id = var.aws_account_id
8+
component = local.component
9+
environment = var.environment
10+
project = var.project
11+
region = var.region
12+
group = var.group
13+
14+
log_retention_in_days = var.log_retention_in_days
15+
kms_key_arn = module.kms.key_arn
16+
17+
iam_policy_document = {
18+
body = data.aws_iam_policy_document.ttl_create_lambda.json
19+
}
20+
21+
function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
22+
function_code_base_path = local.aws_lambda_functions_dir_path
23+
function_code_dir = "ttl-create-lambda/dist"
24+
function_include_common = true
25+
handler_function_name = "handler"
26+
runtime = "nodejs22.x"
27+
memory = 128
28+
timeout = 60
29+
log_level = var.log_level
30+
31+
force_lambda_code_deploy = var.force_lambda_code_deploy
32+
enable_lambda_insights = false
33+
34+
send_to_firehose = true
35+
log_destination_arn = local.log_destination_arn
36+
log_subscription_role_arn = local.acct.log_subscription_role_arn
37+
38+
lambda_env_vars = {
39+
"TTL_TABLE_NAME" = aws_dynamodb_table.ttl.name
40+
"TTL_WAIT_TIME_HOURS" = 24
41+
"TTL_SHARD_COUNT" = local.ttl_shard_count
42+
}
43+
}
44+
45+
data "aws_iam_policy_document" "ttl_create_lambda" {
46+
statement {
47+
sid = "AllowTtlDynamoAccess"
48+
effect = "Allow"
49+
50+
actions = [
51+
"dynamodb:PutItem",
52+
]
53+
54+
resources = [
55+
aws_dynamodb_table.ttl.arn,
56+
]
57+
}
58+
59+
statement {
60+
sid = "KMSPermissions"
61+
effect = "Allow"
62+
63+
actions = [
64+
"kms:Decrypt",
65+
"kms:GenerateDataKey",
66+
]
67+
68+
resources = [
69+
module.kms.key_arn,
70+
]
71+
}
72+
73+
statement {
74+
sid = "SQSPermissionsTtlQueue"
75+
effect = "Allow"
76+
77+
actions = [
78+
"sqs:ReceiveMessage",
79+
"sqs:DeleteMessage",
80+
"sqs:GetQueueAttributes",
81+
"sqs:GetQueueUrl"
82+
]
83+
84+
resources = [
85+
module.sqs_ttl.sqs_queue_arn,
86+
]
87+
}
88+
}

0 commit comments

Comments
 (0)