Skip to content
Open
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
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ nodejs 24.14.1
pnpm 10.33.0
pre-commit 3.6.0
ruby 3.3.6
terraform 1.10.1
terraform 1.14.3
terraform-docs 0.19.0
#trivy 0.61.0 - TODO - Re-visit Trivy usage https://nhsd-jira.digital.nhs.uk/browse/CCM-15549
vale 3.6.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform 1.14.3
29 changes: 29 additions & 0 deletions infrastructure/terraform/components/callback-clients/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!-- BEGIN_TF_DOCS -->
<!-- markdownlint-disable -->
<!-- vale off -->

## Requirements

No requirements.
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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_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_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
| <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_log_retention_in_days"></a> [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite | `number` | `0` | no |
| <a name="input_parent_callbacks_environment"></a> [parent\_callbacks\_environment](#input\_parent\_callbacks\_environment) | The name of the environment which deployed the parent Amplify resource. Used to identify the appropriate state file. | `string` | `"main"` | no |
| <a name="input_project"></a> [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | The AWS Region | `string` | n/a | yes |
## Modules

No modules.
## Outputs

No outputs.
<!-- vale on -->
<!-- markdownlint-enable -->
<!-- END_TF_DOCS -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource "aws_cloudwatch_event_rule" "main" {
name = "${local.csi}-callback-rule"
event_bus_name = local.callbacks.eventbus_name.name # Reference the event bus from callbacks component

event_pattern = jsonencode({
source = [{ prefix = "" }] # Your event pattern here this is effectively "*"
})
}

# resource "aws_cloudwatch_event_target" "main" {
# rule = aws_cloudwatch_event_rule.main.name
# event_bus_name = local.callbacks.eventbus_name.name # Same event bus reference
# target_id = "callback-target"
# arn = # Your target ARN (Lambda, SNS, etc.)
# # Additional target configuration...
# }
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
locals {
callbacks = data.terraform_remote_state.callbacks.outputs
}

data "terraform_remote_state" "callbacks" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/callbacks.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
var.parent_callbacks_environment
)

region = "eu-west-2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
locals {
component = "cbc"

terraform_state_bucket = format(
"%s-tfscaffold-%s-%s",
var.project,
var.aws_account_id,
var.region,
)

csi = replace(
format(
"%s-%s-%s",
var.project,
var.environment,
local.component,
),
"_",
"",
)

# CSI for use in resources with a global namespace, i.e. S3 Buckets
csi_global = replace(
format(
"%s-%s-%s-%s-%s",
var.project,
var.aws_account_id,
var.region,
var.environment,
local.component,
),
"_",
"",
)

default_tags = merge(
var.default_tags,
{
Project = var.project
Environment = var.environment
Component = local.component
Group = var.group
Name = local.csi
},
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Define the outputs for the component. The outputs may well be referenced by other component in the same or different environments using terraform_remote_state data sources...
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash

## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## This script is currently disabled (renamed to pre.sh.disabled) as it is only needed for
## Terraform components that need build and publish container images or lambda packageses.
##
## It is left in place for reference and future use when adding new components that require this functionality.
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##


# This script is run before Terraform executable commands.
# It ensures all Node.js dependencies are installed, generates any required dependencies,
# and builds all Lambda functions in the workspace before Terraform provisions infrastructure.
# pre.sh runs in the same shell as terraform.sh, not in a subshell

: "${PROJECT:?PROJECT is required}"
: "${REGION:?REGION is required}"
: "${COMPONENT:?COMPONENT is required}"
: "${ENVIRONMENT:?ENVIRONMENT is required}"
: "${AWS_ACCOUNT_ID:?AWS_ACCOUNT_ID is required}"
: "${ACTION:?ACTION is required}"

echo "Running app pre.sh"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"
echo "PROJECT=$PROJECT"
echo "COMPONENT=$COMPONENT"
echo "AWS_REGION=$REGION"
echo "AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID"

# Calculate container image prefix from PROJECT, ENVIRONMENT, COMPONENT
CONTAINER_IMAGE_PREFIX="${PROJECT}-${ENVIRONMENT}-${COMPONENT}"
echo "CONTAINER_IMAGE_PREFIX: ${CONTAINER_IMAGE_PREFIX}"

# Translate ACTION to PUBLISH_CONTAINER_IMAGE (build)
if [ "${ACTION}" = "plan" ]; then
PUBLISH_CONTAINER_IMAGE="false"
else
PUBLISH_CONTAINER_IMAGE="true"
fi

# Helper function for error handling
run_or_fail() {
"$@"
if [ $? -ne 0 ]; then
echo "$* failed!" >&2
exit 1
fi
}

# Switch to repo root
pushd "$(git rev-parse --show-toplevel)" || exit 1

# Calculate git-based version suffix
SHORT_SHA="$(git rev-parse --short HEAD)"
GIT_TAG="$(git describe --tags --exact-match 2>/dev/null || true)"

if [ -n "${GIT_TAG}" ]; then
RELEASE_VERSION="${GIT_TAG#v}"
CONTAINER_IMAGE_SUFFIX="release-${RELEASE_VERSION}-${SHORT_SHA}"
echo "On tag: $GIT_TAG, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
else
CONTAINER_IMAGE_SUFFIX="sha-${SHORT_SHA}"
echo "Not on a tag, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
fi

# Export for Terraform
export TF_VAR_container_image_tag_suffix="${CONTAINER_IMAGE_SUFFIX}"

run_or_fail pnpm install --frozen-lockfile
run_or_fail pnpm -r run --if-present generate-dependencies
run_or_fail pnpm -r run --if-present build:archive
run_or_fail env \
CONTAINER_IMAGE_PREFIX="${CONTAINER_IMAGE_PREFIX}" \
CONTAINER_IMAGE_SUFFIX="${CONTAINER_IMAGE_SUFFIX}" \
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID}" \
AWS_REGION="${REGION}" \
PUBLISH_CONTAINER_IMAGE="${PUBLISH_CONTAINER_IMAGE}" \
pnpm -r run --if-present build:container

popd || exit 1 # Return to working directory
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
##
# Basic Required Variables for tfscaffold Components
##

variable "project" {
type = string
description = "The name of the tfscaffold project"
}

variable "environment" {
type = string
description = "The name of the tfscaffold environment"
}

variable "aws_account_id" {
type = string
description = "The AWS Account ID (numeric)"
}

variable "region" {
type = string
description = "The AWS Region"
}

variable "group" {
type = string
description = "The group variables are being inherited from (often synonmous with account short-name)"
}

##
# tfscaffold variables specific to this component
##

# This is the only primary variable to have its value defined as
# a default within its declaration in this file, because the variables
# purpose is as an identifier unique to this component, rather
# then to the environment from where all other variables come.

variable "default_tags" {
type = map(string)
description = "A map of default tags to apply to all taggable resources within the component"
default = {}
}

##
# Variables specific to the component
##

variable "log_retention_in_days" {
type = number
description = "The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite"
default = 0
}

variable "force_lambda_code_deploy" {
type = bool
description = "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"
default = false
}

variable "parent_callbacks_environment" {
type = string
description = "The name of the environment which deployed the parent Amplify resource. Used to identify the appropriate state file."
default = "main"
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
terraform 1.10.1
terraform 1.14.3
2 changes: 1 addition & 1 deletion infrastructure/terraform/components/callbacks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
|------|-------------|------|---------|:--------:|
| <a name="input_applications_map_parameter_name"></a> [applications\_map\_parameter\_name](#input\_applications\_map\_parameter\_name) | SSM Parameter Store path for the clientId-to-applicationData map, where applicationData is currently only the applicationId | `string` | `null` | 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` | `"callbacks"` | 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_deploy_mock_clients"></a> [deploy\_mock\_clients](#input\_deploy\_mock\_clients) | Flag to deploy mock webhook lambda for integration testing (test/dev environments only) | `bool` | `false` | no |
| <a name="input_enable_event_anomaly_detection"></a> [enable\_event\_anomaly\_detection](#input\_enable\_event\_anomaly\_detection) | Enable CloudWatch anomaly detection alarm for inbound event queue message reception | `bool` | `true` | no |
Expand Down Expand Up @@ -55,6 +54,7 @@
| Name | Description |
|------|-------------|
| <a name="output_deployment"></a> [deployment](#output\_deployment) | Deployment details used for post-deployment scripts |
| <a name="output_eventbus_name"></a> [eventbus\_name](#output\_eventbus\_name) | Name of the EventBridge event bus for callback events |
| <a name="output_mock_webhook_lambda_log_group_name"></a> [mock\_webhook\_lambda\_log\_group\_name](#output\_mock\_webhook\_lambda\_log\_group\_name) | CloudWatch log group name for mock webhook lambda (for integration test queries) |
<!-- vale on -->
<!-- markdownlint-enable -->
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/terraform/components/callbacks/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ locals {
}
]...)

applications_map_parameter_name = coalesce(var.applications_map_parameter_name, "/${var.project}/${var.environment}/${var.component}/applications-map")
applications_map_parameter_name = coalesce(var.applications_map_parameter_name, "/${var.project}/${var.environment}/${local.component}/applications-map")
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
locals {
component = "cb"

terraform_state_bucket = format(
"%s-tfscaffold-%s-%s",
var.project,
Expand All @@ -11,7 +13,7 @@ locals {
"%s-%s-%s",
var.project,
var.environment,
var.component,
local.component,
),
"_",
"",
Expand All @@ -25,7 +27,7 @@ locals {
var.aws_account_id,
var.region,
var.environment,
var.component,
local.component,
),
"_",
"",
Expand All @@ -36,7 +38,7 @@ locals {
{
Project = var.project
Environment = var.environment
Component = var.component
Component = local.component
Group = var.group
Name = local.csi
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module "client_destination" {
project = var.project
aws_account_id = var.aws_account_id
region = var.region
component = var.component
component = local.component
environment = var.environment
client_bus_name = aws_cloudwatch_event_bus.main.name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module "kms" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/3.0.7/terraform-kms.zip"

aws_account_id = var.aws_account_id
component = var.component
component = local.component
environment = var.environment
project = var.project
region = var.region
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module "mock_webhook_lambda" {
description = "Mock webhook endpoint for integration testing - logs received callbacks to CloudWatch"

aws_account_id = var.aws_account_id
component = var.component
component = local.component
environment = var.environment
project = var.project
region = var.region
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module "sqs_inbound_event" {
source = "https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/3.0.7/terraform-sqs.zip"

aws_account_id = var.aws_account_id
component = var.component
component = local.component
environment = var.environment
project = var.project
region = var.region
Expand Down Expand Up @@ -33,7 +33,7 @@ data "aws_iam_policy_document" "sqs_inbound_event" {
]

resources = [
"arn:aws:sqs:${var.region}:${var.aws_account_id}:${var.project}-${var.environment}-${var.component}-inbound-event-queue"
"arn:aws:sqs:${var.region}:${var.aws_account_id}:${var.project}-${var.environment}-${local.component}-inbound-event-queue"
]

condition {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module "client_transform_filter_lambda" {
description = "Lambda function that transforms and filters events coming to through the eventpipe"

aws_account_id = var.aws_account_id
component = var.component
component = local.component
environment = var.environment
project = var.project
region = var.region
Expand Down
Loading
Loading