From 5266f2bcd2baac083fca15b4158c51e2d414c734 Mon Sep 17 00:00:00 2001 From: NogaNHS Date: Thu, 3 Oct 2024 12:31:28 +0100 Subject: [PATCH] PRMP-935 new lambda-generate-stitch-record.tf --- infrastructure/README.md | 8 +- infrastructure/dynamo_db.tf | 31 +++++ .../lambda-generate-stitch-record.tf | 125 ++++++++++++++++++ .../lambda-lloyd-george-record-stitch.tf | 6 +- infrastructure/variable.tf | 5 + 5 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 infrastructure/lambda-generate-stitch-record.tf diff --git a/infrastructure/README.md b/infrastructure/README.md index 6a7baa73..2090bb1d 100644 --- a/infrastructure/README.md +++ b/infrastructure/README.md @@ -8,7 +8,7 @@ | Name | Version | |------|---------| -| [aws](#provider\_aws) | 5.57.0 | +| [aws](#provider\_aws) | 5.66.0 | ## Modules @@ -67,6 +67,9 @@ | [generate-document-manifest-alarm](#module\_generate-document-manifest-alarm) | ./modules/lambda_alarms | n/a | | [generate-document-manifest-alarm-topic](#module\_generate-document-manifest-alarm-topic) | ./modules/sns | n/a | | [generate-document-manifest-lambda](#module\_generate-document-manifest-lambda) | ./modules/lambda | n/a | +| [generate-stitch-record-alarm](#module\_generate-stitch-record-alarm) | ./modules/lambda_alarms | n/a | +| [generate-stitch-record-alarm-topic](#module\_generate-stitch-record-alarm-topic) | ./modules/sns | n/a | +| [generate-stitch-record-lambda](#module\_generate-stitch-record-lambda) | ./modules/lambda | n/a | | [lambda-layer-core](#module\_lambda-layer-core) | ./modules/lambda_layers | n/a | | [lambda-layer-data](#module\_lambda-layer-data) | ./modules/lambda_layers | n/a | | [lloyd-george-stitch-gateway](#module\_lloyd-george-stitch-gateway) | ./modules/gateway | n/a | @@ -120,6 +123,7 @@ | [statistical-report-lambda](#module\_statistical-report-lambda) | ./modules/lambda | n/a | | [statistical-reports-store](#module\_statistical-reports-store) | ./modules/s3/ | n/a | | [statistics\_dynamodb\_table](#module\_statistics\_dynamodb\_table) | ./modules/dynamo_db | n/a | +| [stitch\_store\_reference\_dynamodb\_table](#module\_stitch\_store\_reference\_dynamodb\_table) | ./modules/dynamo_db | n/a | | [update-upload-state-gateway](#module\_update-upload-state-gateway) | ./modules/gateway | n/a | | [update-upload-state-lambda](#module\_update-upload-state-lambda) | ./modules/lambda | n/a | | [update\_upload\_state\_alarm](#module\_update\_upload\_state\_alarm) | ./modules/lambda_alarms | n/a | @@ -205,6 +209,7 @@ | [aws_iam_role_policy_attachment.policy_audit_search-patient-details-lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.policy_audit_token_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.policy_generate_manifest_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.policy_generate_stitch_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.policy_manifest_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.restore_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.s3_backup_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | @@ -302,6 +307,7 @@ | [standalone\_vpc\_tag](#input\_standalone\_vpc\_tag) | This is the tag assigned to the standalone vpc that should be created manaully before the first run of the infrastructure | `string` | n/a | yes | | [statistical\_reports\_bucket\_name](#input\_statistical\_reports\_bucket\_name) | The name of S3 bucket to store weekly generated statistical reports | `string` | `"statistical-reports"` | no | | [statistics\_dynamodb\_table\_name](#input\_statistics\_dynamodb\_table\_name) | The name of dynamodb table to store application statistics | `string` | `"ApplicationStatistics"` | no | +| [stitch\_store\_dynamodb\_table\_name](#input\_stitch\_store\_dynamodb\_table\_name) | n/a | `string` | `"StitchStoreReferenceMetadata"` | no | | [zip\_store\_bucket\_name](#input\_zip\_store\_bucket\_name) | n/a | `string` | `"zip-request-store"` | no | | [zip\_store\_dynamodb\_table\_name](#input\_zip\_store\_dynamodb\_table\_name) | n/a | `string` | `"ZipStoreReferenceMetadata"` | no | diff --git a/infrastructure/dynamo_db.tf b/infrastructure/dynamo_db.tf index 87625927..6d0db7b3 100644 --- a/infrastructure/dynamo_db.tf +++ b/infrastructure/dynamo_db.tf @@ -134,6 +134,37 @@ module "zip_store_reference_dynamodb_table" { owner = var.owner } +module "stitch_store_reference_dynamodb_table" { + source = "./modules/dynamo_db" + table_name = var.stitch_store_dynamodb_table_name + hash_key = "ID" + deletion_protection_enabled = false + stream_enabled = true + ttl_enabled = false + + attributes = [ + { + name = "ID" + type = "S" + }, + { + name = "JobId" + type = "S" + } + ] + + global_secondary_indexes = [ + { + name = "JobIdIndex" + hash_key = "JobId" + projection_type = "ALL" + } + ] + + environment = var.environment + owner = var.owner +} + module "auth_state_dynamodb_table" { source = "./modules/dynamo_db" table_name = var.auth_state_dynamodb_table_name diff --git a/infrastructure/lambda-generate-stitch-record.tf b/infrastructure/lambda-generate-stitch-record.tf new file mode 100644 index 00000000..23d44773 --- /dev/null +++ b/infrastructure/lambda-generate-stitch-record.tf @@ -0,0 +1,125 @@ +module "generate-stitch-record-alarm" { + source = "./modules/lambda_alarms" + lambda_function_name = module.generate-stitch-record-lambda.function_name + lambda_timeout = module.generate-stitch-record-lambda.timeout + lambda_name = "generate_stitch_record_handler" + namespace = "AWS/Lambda" + alarm_actions = [module.generate-stitch-record-alarm-topic.arn] + ok_actions = [module.generate-stitch-record-alarm-topic.arn] + depends_on = [module.generate-stitch-record-lambda, module.generate-stitch-record-alarm-topic] +} + +module "generate-stitch-record-alarm-topic" { + source = "./modules/sns" + sns_encryption_key_id = module.sns_encryption_key.id + current_account_id = data.aws_caller_identity.current.account_id + topic_name = "generate-stitch-record-topic" + topic_protocol = "lambda" + topic_endpoint = module.generate-stitch-record-lambda.lambda_arn + delivery_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Principal" : { + "Service" : "cloudwatch.amazonaws.com" + }, + "Action" : [ + "SNS:Publish", + ], + "Condition" : { + "ArnLike" : { + "aws:SourceArn" : "arn:aws:cloudwatch:eu-west-2:${data.aws_caller_identity.current.account_id}:alarm:*" + } + } + "Resource" : "*" + } + ] + }) + + depends_on = [module.generate-stitch-record-lambda, module.sns_encryption_key] +} + +module "generate-stitch-record-lambda" { + source = "./modules/lambda" + name = "GenerateStitchRecord" + handler = "handlers.generate_stitch_record_handler.lambda_handler" + lambda_timeout = 900 + lambda_ephemeral_storage = 512 + memory_size = 512 + iam_role_policies = [ + module.ndr-document-store.s3_object_access_policy, + module.ndr-lloyd-george-store.s3_object_access_policy, + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy", + module.ndr-app-config.app_config_policy_arn, + aws_iam_policy.dynamodb_stream_policy.arn + ] + rest_api_id = null + api_execution_arn = null + lambda_environment_variables = { + APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id + APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id + APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id + SPLUNK_SQS_QUEUE_URL = try(module.sqs-splunk-queue[0].sqs_url, null) + STITCH_STORE_DYNAMODB_NAME = "${terraform.workspace}_${var.stitch_store_dynamodb_table_name}" + WORKSPACE = terraform.workspace + PRESIGNED_ASSUME_ROLE = aws_iam_role.stitch_presign_url_role.arn + } + is_gateway_integration_needed = false + is_invoked_from_gateway = false + + depends_on = [ + aws_iam_policy.lambda_audit_splunk_sqs_queue_send_policy[0], + module.ndr-app-config, + module.ndr-document-store, + module.ndr-lloyd-george-store, + ] +} + +resource "aws_iam_policy" "dynamodb_stream_policy" { + name = "${terraform.workspace}_dynamodb_stream_to_stitch_policy" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = ["dynamodb:GetRecords", "dynamodb:GetShardIterator", "dynamodb:DescribeStream", "dynamodb:ListStreams"] + Effect = "Allow" + Resource = module.stitch_store_reference_dynamodb_table.dynamodb_stream_arn + }, + ] + }) +} + +resource "aws_iam_role_policy_attachment" "policy_generate_stitch_lambda" { + count = local.is_sandbox ? 0 : 1 + role = module.generate-stitch-record-lambda.lambda_execution_role_name + policy_arn = try(aws_iam_policy.lambda_audit_splunk_sqs_queue_send_policy[0].arn, null) +} + +resource "aws_lambda_event_source_mapping" "dynamodb_stream_event_mapping" { + event_source_arn = module.stitch_store_reference_dynamodb_table.dynamodb_stream_arn + function_name = module.generate-stitch-record-lambda.lambda_arn + batch_size = 1 + starting_position = "TRIM_HORIZON" + + filter_criteria { + filter { + pattern = jsonencode({ + "eventName" : [ + "INSERT" + ], + "dynamodb" : { + "NewImage" : { + "JobStatus" : { + "S" : [ + "Pending" + ] + } + } + } + }) + } + } +} \ No newline at end of file diff --git a/infrastructure/lambda-lloyd-george-record-stitch.tf b/infrastructure/lambda-lloyd-george-record-stitch.tf index 0c8c935f..b30cc3f6 100644 --- a/infrastructure/lambda-lloyd-george-record-stitch.tf +++ b/infrastructure/lambda-lloyd-george-record-stitch.tf @@ -3,7 +3,7 @@ module "lloyd-george-stitch-gateway" { source = "./modules/gateway" api_gateway_id = aws_api_gateway_rest_api.ndr_doc_store_api.id parent_id = aws_api_gateway_rest_api.ndr_doc_store_api.root_resource_id - http_methods = ["GET"] + http_methods = ["GET", "POST"] authorization = "CUSTOM" gateway_path = "LloydGeorgeStitch" authorizer_id = aws_api_gateway_authorizer.repo_authoriser.id @@ -64,7 +64,7 @@ module "lloyd-george-stitch_topic" { module "lloyd-george-stitch-lambda" { source = "./modules/lambda" - name = "LloydGeorgeStitchLambda" + name = "LloydGeorgeStitch" handler = "handlers.lloyd_george_record_stitch_handler.lambda_handler" iam_role_policies = [ module.lloyd_george_reference_dynamodb_table.dynamodb_policy, @@ -75,7 +75,7 @@ module "lloyd-george-stitch-lambda" { ] rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api.id resource_id = module.lloyd-george-stitch-gateway.gateway_resource_id - http_methods = ["GET"] + http_methods = ["GET", "POST"] api_execution_arn = aws_api_gateway_rest_api.ndr_doc_store_api.execution_arn memory_size = 512 lambda_timeout = 450 diff --git a/infrastructure/variable.tf b/infrastructure/variable.tf index abd31fa5..fcabce83 100644 --- a/infrastructure/variable.tf +++ b/infrastructure/variable.tf @@ -71,6 +71,11 @@ variable "zip_store_dynamodb_table_name" { default = "ZipStoreReferenceMetadata" } +variable "stitch_store_dynamodb_table_name" { + type = string + default = "StitchStoreReferenceMetadata" +} + variable "auth_state_dynamodb_table_name" { type = string description = "The name of dynamodb table to store the state values (for CIS2 authorisation)"