Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generatio
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:23
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:30
f8546e35b77b69ba7b15dbe3174d2d7e375200ef:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:46
39af95d4a48f3f2f4e5404da6cfe4a1350f25abe:utils/utils/src/__tests__/key-generation/validate-private-key.test.ts:private-key:7
39af95d4a48f3f2f4e5404da6cfe4a1350f25abe:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:23
39af95d4a48f3f2f4e5404da6cfe4a1350f25abe:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:30
39af95d4a48f3f2f4e5404da6cfe4a1350f25abe:utils/utils/src/__tests__/key-generation/get-private-key.test.ts:private-key:46
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export default defineConfig([
'no-await-in-loop': 0,
'no-plusplus': [2, { allowForLoopAfterthoughts: true }],
'unicorn/prefer-top-level-await': 0, // top level await is not available in commonjs
'import-x/prefer-default-export': "off"
},
},
]);
9 changes: 9 additions & 0 deletions infrastructure/terraform/components/dl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ No requirements.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_apim_auth_token_schedule"></a> [apim\_auth\_token\_schedule](#input\_apim\_auth\_token\_schedule) | Schedule to renew the APIM auth token | `string` | `"rate(9 minutes)"` | no |
| <a name="input_apim_auth_token_url"></a> [apim\_auth\_token\_url](#input\_apim\_auth\_token\_url) | URL to generate an APIM auth token | `string` | `"https://int.api.service.nhs.uk/oauth2/token"` | no |
| <a name="input_apim_base_url"></a> [apim\_base\_url](#input\_apim\_base\_url) | The URL used to send requests to Notify and PDM | `string` | `"https://sandbox.api.service.nhs.uk"` | no |
| <a name="input_apim_keygen_schedule"></a> [apim\_keygen\_schedule](#input\_apim\_keygen\_schedule) | Schedule to refresh key pairs if necessary | `string` | `"cron(0 14 * * ? *)"` | no |
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
| <a name="input_component"></a> [component](#input\_component) | The variable encapsulating the name of this component | `string` | `"dl"` | no |
| <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 |
| <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 |
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | Flag to force deletion of S3 buckets | `bool` | `false` | no |
| <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 |
| <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 |
| <a name="input_kms_deletion_window"></a> [kms\_deletion\_window](#input\_kms\_deletion\_window) | When a kms key is deleted, how long should it wait in the pending deletion state? | `string` | `"30"` | no |
Expand All @@ -32,8 +37,12 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
| <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 |
| <a name="module_lambda_apim_key_generation"></a> [lambda\_apim\_key\_generation](#module\_lambda\_apim\_key\_generation) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <a name="module_lambda_lambda_apim_refresh_token"></a> [lambda\_lambda\_apim\_refresh\_token](#module\_lambda\_lambda\_apim\_refresh\_token) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <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 |
| <a name="module_s3bucket_cf_logs"></a> [s3bucket\_cf\_logs](#module\_s3bucket\_cf\_logs) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-s3bucket.zip | n/a |
| <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 |
| <a name="module_s3bucket_static_assets"></a> [s3bucket\_static\_assets](#module\_s3bucket\_static\_assets) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-s3bucket.zip | n/a |
| <a name="module_sqs_event_publisher_errors"></a> [sqs\_event\_publisher\_errors](#module\_sqs\_event\_publisher\_errors) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
| <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 |
| <a name="module_sqs_ttl_handle_expiry_errors"></a> [sqs\_ttl\_handle\_expiry\_errors](#module\_sqs\_ttl\_handle\_expiry\_errors) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "aws_acm_certificate" "static_assets_hosting" {
provider = aws.us-east-1
domain_name = local.root_domain_name
validation_method = "DNS"

lifecycle {
create_before_destroy = true
}
}

resource "aws_acm_certificate_validation" "static_assets_hosting" {
provider = aws.us-east-1
certificate_arn = aws_acm_certificate.static_assets_hosting.arn
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
resource "aws_cloudfront_distribution" "static_assets_hosting" {
enabled = true
is_ipv6_enabled = true
comment = "Static asset hosting for Digital Letters"
price_class = "PriceClass_100"

restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = ["GB"]
}
}

aliases = [local.root_domain_name]

viewer_certificate {
cloudfront_default_certificate = false
acm_certificate_arn = aws_acm_certificate.static_assets_hosting.arn
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}

logging_config {
include_cookies = false
bucket = module.s3bucket_cf_logs.bucket_regional_domain_name
}

origin {
domain_name = module.s3bucket_static_assets.bucket_regional_domain_name
origin_id = "${local.csi}-origin-static-assets"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.static_assets.cloudfront_access_identity_path
}
}

default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${local.csi}-origin-static-assets"

forwarded_values {
query_string = false
headers = ["Origin"]
cookies {
forward = "none"
}
}

viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 0
max_ttl = 86400
compress = true
}
}
7 changes: 6 additions & 1 deletion infrastructure/terraform/components/dl/locals.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
locals {
aws_lambda_functions_dir_path = "../../../../lambdas"
log_destination_arn = "arn:aws:logs:${var.region}:${var.shared_infra_account_id}:destination:nhs-main-obs-firehose-logs"

apim_access_token_ssm_parameter_name = "/${var.component}/${var.environment}/apim/access_token"
apim_api_key_ssm_parameter_name = "/${var.component}/${var.environment}/apim/api_key"
apim_private_key_ssm_parameter_name = "/${var.component}/${var.environment}/apim/private_key"
apim_keystore_s3_bucket = "nhs-${var.aws_account_id}-${var.region}-${var.environment}-${var.component}-static-assets"
root_domain_name = "${var.environment}.${local.acct.route53_zone_names["digital-letters"]}"
root_domain_id = local.acct.route53_zone_ids["digital-letters"]
ttl_shard_count = 3
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module "lambda_apim_key_generation" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip"

function_name = "apim-key-generation"
description = "A function to generate APIM public and private keys"

aws_account_id = var.aws_account_id
component = var.component
environment = var.environment
project = var.project
region = var.region
group = var.group

log_retention_in_days = var.log_retention_in_days
kms_key_arn = module.kms.key_arn

iam_policy_document = {
body = data.aws_iam_policy_document.lambda_apim_key_generation.json
}

function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
function_code_base_path = local.aws_lambda_functions_dir_path
function_code_dir = "key-generation/dist"
function_include_common = true
function_module_name = "lambda"
handler_function_name = "handler"
runtime = "nodejs22.x"
memory = 512
timeout = 300
log_level = var.log_level
schedule = var.apim_keygen_schedule

force_lambda_code_deploy = var.force_lambda_code_deploy
enable_lambda_insights = false

send_to_firehose = true
log_destination_arn = local.log_destination_arn
log_subscription_role_arn = local.acct.log_subscription_role_arn

lambda_env_vars = {
SSM_PRIVATE_KEY_PARAMETER_NAME = local.apim_private_key_ssm_parameter_name
KEYSTORE_S3_BUCKET = local.apim_keystore_s3_bucket
ENVIRONMENT = var.environment
}
}

data "aws_iam_policy_document" "lambda_apim_key_generation" {
statement {
sid = "AllowS3List"
effect = "Allow"

actions = [
"s3:ListBucket",
"s3:PutObject"
]

resources = [
"arn:aws:s3:::${local.apim_keystore_s3_bucket}/*"
]
}

statement {
sid = "AllowSSMParam"
effect = "Allow"

actions = [
"ssm:DeleteParameter",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"ssm:PutParameter",
]

resources = [
"arn:aws:ssm:${var.region}:${var.aws_account_id}:parameter/${var.component}/${var.environment}/apim/*"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module "lambda_lambda_apim_refresh_token" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip"

function_name = "apim-refresh-token"
description = "A function to generate APIM access tokens"

aws_account_id = var.aws_account_id
component = var.component
environment = var.environment
project = var.project
region = var.region
group = var.group

log_retention_in_days = var.log_retention_in_days
kms_key_arn = module.kms.key_arn

iam_policy_document = {
body = data.aws_iam_policy_document.lambda_apim_refresh_token.json
}

function_s3_bucket = local.acct.s3_buckets["lambda_function_artefacts"]["id"]
function_code_base_path = local.aws_lambda_functions_dir_path
function_code_dir = "refresh-apim-access-token/dist"
function_include_common = true
handler_function_name = "handler"
runtime = "nodejs22.x"
memory = 128
timeout = 5
log_level = var.log_level
schedule = var.apim_auth_token_schedule

force_lambda_code_deploy = var.force_lambda_code_deploy
enable_lambda_insights = false

send_to_firehose = true
log_destination_arn = local.log_destination_arn
log_subscription_role_arn = local.acct.log_subscription_role_arn

lambda_env_vars = {
NHS_AUTH_SERVER_TOKEN_ENDPOINT = var.apim_auth_token_url
SSM_ACCESS_TOKEN_PARAMETER_NAME = local.apim_access_token_ssm_parameter_name
SSM_API_KEY_PARAMETER_NAME = local.apim_api_key_ssm_parameter_name
SSM_PRIVATE_KEY_PARAMETER_NAME = local.apim_private_key_ssm_parameter_name
ENVIRONMENT = var.environment
}
}

data "aws_iam_policy_document" "lambda_apim_refresh_token" {
statement {
sid = "AllowSSMParam"
effect = "Allow"

actions = [
"ssm:DeleteParameter",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"ssm:PutParameter",
]

resources = [
"arn:aws:ssm:${var.region}:${var.aws_account_id}:parameter/${var.component}/${var.environment}/apim/*"
]
}
}
Loading
Loading