From 8a56077ae2b9647ef03bafcebb8cd99da3c01bb6 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 15:08:49 +0000 Subject: [PATCH 01/24] Create mock mock lambda artifact --- .github/workflows/preview-env.yaml | 13 +++++++-- .../environments/preview/handler.py | 28 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 infrastructure/environments/preview/handler.py diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 7ec65e3..32a3e0e 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -16,6 +16,7 @@ permissions: env: AWS_REGION: eu-west-2 PREVIEW_PREFIX: pr- + MOCK_PREFIX: mock- PYTHON_VERSION: 3.14 LAMBDA_RUNTIME: python3.14 LAMBDA_HANDLER: lambda_handler.handler @@ -50,6 +51,14 @@ jobs: run: | make build + # Place holder mock artifact packaging to allow testing of mock API in preview environment; + # can be extended to build a real mock Lambda if needed + - name: Package mock artifact + run: | + cd infrastructure/environments/preview + rm -f mock_artifact.zip + zip -r mock_artifact.zip . + - name: Select AWS role inputs id: role-select env: @@ -220,7 +229,7 @@ jobs: with: mtls-secret-name: ${{ env.MTLS_SECRET_NAME }} target-url: ${{ steps.names.outputs.preview_url }} - proxy-base-path: '${{ env.PROXYGEN_API_NAME }}-pr-${{ github.event.pull_request.number }}' + proxy-base-path: "${{ env.PROXYGEN_API_NAME }}-pr-${{ github.event.pull_request.number }}" proxygen-key-secret: ${{ env._cds_pathology_dev_proxygen_proxygen_key_secret }} proxygen-key-id: ${{ env.PROXYGEN_KEY_ID }} proxygen-client-id: ${{ env.PROXYGEN_CLIENT_ID }} @@ -230,7 +239,7 @@ jobs: if: github.event.action == 'closed' uses: ./.github/actions/proxy/tear-down-proxy with: - proxy-base-path: '${{ env.PROXYGEN_API_NAME }}-pr-${{ github.event.pull_request.number }}' + proxy-base-path: "${{ env.PROXYGEN_API_NAME }}-pr-${{ github.event.pull_request.number }}" proxygen-key-secret: ${{ env._cds_pathology_dev_proxygen_proxygen_key_secret }} proxygen-key-id: ${{ env.PROXYGEN_KEY_ID }} proxygen-client-id: ${{ env.PROXYGEN_CLIENT_ID }} diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py new file mode 100644 index 0000000..bf432f9 --- /dev/null +++ b/infrastructure/environments/preview/handler.py @@ -0,0 +1,28 @@ +import json +import logging +from typing import Any + +logger = logging.getLogger() +logger.setLevel(logging.INFO) + + +def handler(event: dict[str, Any], context): + headers = event.get("headers", {}) or {} + + # Log headers to CloudWatch + logger.info("Incoming request headers:") + for k, v in headers.items(): + logger.info("%s: %s", k, v) + + response_body = { + "message": "ok", + "headers": headers, + "requestContext": event.get("requestContext", {}), + } + + return { + "statusCode": 200, + "headers": {"content-type": "application/json"}, + "body": json.dumps(response_body, indent=2), + "isBase64Encoded": False, + } From 7b91fd6805cfd99e9f3e08cda23df7548a938edb Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 15:57:08 +0000 Subject: [PATCH 02/24] Setup mock endpoints --- .github/workflows/preview-env.yaml | 57 +++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 32a3e0e..83323bf 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -20,6 +20,7 @@ env: PYTHON_VERSION: 3.14 LAMBDA_RUNTIME: python3.14 LAMBDA_HANDLER: lambda_handler.handler + MOCK_LAMBDA_HANDLER: handler.handler MTLS_SECRET_NAME: ${{ vars.PREVIEW_ENV_MTLS_SECRET_NAME }} PROXYGEN_KEY_ID: ${{ vars.PREVIEW_ENV_PROXYGEN_KEY_ID }} PROXYGEN_CLIENT_ID: ${{ vars.PREVIEW_ENV_PROXYGEN_CLIENT_ID }} @@ -97,16 +98,22 @@ jobs: run: | SAFE=${{ steps.branch.outputs.safe }} PREFIX=${{ env.PREVIEW_PREFIX }} - MAX_FN_LEN=64 + MOCK_PREFIX=${{ env.MOCK_PREFIX }} + MAX_FN_LEN=62 MAX_SAFE_LEN=$((MAX_FN_LEN - ${#PREFIX})) if [ ${#SAFE} -gt "$MAX_SAFE_LEN" ]; then SAFE=${SAFE:0:MAX_SAFE_LEN} fi FN="${PREFIX}${SAFE}" + MFN="${MOCK_PREFIX}${SAFE}" echo "function_name=$FN" >> "$GITHUB_OUTPUT" + echo "mock_function_name=$MFN" >> "$GITHUB_OUTPUT" URL="https://${SAFE}.dev.endpoints.${{ env.PROXYGEN_API_NAME }}.national.nhs.uk" + MOCK_URL="https://${MFN}.m.dev.endpoints.${{ env.PROXYGEN_API_NAME }}.national.nhs.uk" echo "preview_url=$URL" >> "$GITHUB_OUTPUT" + echo "mock_preview_url=$MOCK_URL" >> "$GITHUB_OUTPUT" + # ---------- Handle application ---------- - name: Create or update preview Lambda (on open/sync/reopen) if: github.event.action != 'closed' run: | @@ -154,6 +161,54 @@ jobs: echo "function = ${{ steps.names.outputs.function_name }}" echo "url = ${{ steps.names.outputs.preview_url }}" + # ---------- Handle mock endpoints ---------- + - name: Create or update mock Lambda (on open/sync/reopen) + if: github.event.action != 'closed' + run: | + cd infrastructure/environments/preview + MFN="${{ steps.names.outputs.mock_function_name }}" + echo "Deploying mock function: $MFN" + wait_for_lambda_ready() { + while true; do + status=$(aws lambda get-function-configuration --function-name "$MFN" --query 'LastUpdateStatus' --output text 2>/dev/null || echo "Unknown") + if [ "$status" = "Successful" ] || [ "$status" = "Unknown" ]; then + break + fi + if [ "$status" = "Failed" ]; then + echo "Lambda is in Failed state; check logs." >&2 + exit 1 + fi + echo "Lambda update status: $status — waiting..." + sleep 5 + done + } + if aws lambda get-function --function-name "$MFN" >/dev/null 2>&1; then + wait_for_lambda_ready + aws lambda update-function-configuration --function-name "$MFN" --handler "${{ env.LAMBDA_HANDLER }}" || true + wait_for_lambda_ready + aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://artifact.zip" --publish + else + aws lambda create-function --function-name "$MFN" \ + --runtime "${{ env.LAMBDA_RUNTIME }}" \ + --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ + --zip-file "fileb://artifact.zip" \ + --role "${{ steps.role-select.outputs.lambda_role }}" \ + --publish + wait_for_lambda_ready + fi + + - name: Delete mock Lambda (on PR closed) + if: github.event.action == 'closed' + run: | + MFN="${{ steps.names.outputs.mock_function_name }}" + echo "Deleting mock function: $MFN" + aws lambda delete-function --function-name "$MFN" || true + + - name: Output mock function name + run: | + echo "mock_function = ${{ steps.names.outputs.mock_function_name }}" + echo "mock_url = ${{ steps.names.outputs.mock_preview_url }}" + # ---------- Wait on AWS tasks and notify ---------- - name: Get mTLS certs for testing if: github.event.action != 'closed' From fc50e2de96f8f074892c3b3df8dae236c0fb3fdb Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 15:59:24 +0000 Subject: [PATCH 03/24] Update mock Lambda artifact filename in preview environment workflow --- .github/workflows/preview-env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 83323bf..4d6f1de 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -191,7 +191,7 @@ jobs: aws lambda create-function --function-name "$MFN" \ --runtime "${{ env.LAMBDA_RUNTIME }}" \ --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ - --zip-file "fileb://artifact.zip" \ + --zip-file "fileb://mock_artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ --publish wait_for_lambda_ready From 2b4c30bc48aecadd34f785fbcba5d4bcbfbe2d08 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 16:19:25 +0000 Subject: [PATCH 04/24] Fix mock URL generation in preview environment workflow --- .github/workflows/preview-env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 4d6f1de..997d966 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -109,7 +109,7 @@ jobs: echo "function_name=$FN" >> "$GITHUB_OUTPUT" echo "mock_function_name=$MFN" >> "$GITHUB_OUTPUT" URL="https://${SAFE}.dev.endpoints.${{ env.PROXYGEN_API_NAME }}.national.nhs.uk" - MOCK_URL="https://${MFN}.m.dev.endpoints.${{ env.PROXYGEN_API_NAME }}.national.nhs.uk" + MOCK_URL="https://${SAFE}.m.dev.endpoints.${{ env.PROXYGEN_API_NAME }}.national.nhs.uk" echo "preview_url=$URL" >> "$GITHUB_OUTPUT" echo "mock_preview_url=$MOCK_URL" >> "$GITHUB_OUTPUT" From 006ec1566bcb9c4d7a2952bbe4d4585afebe0299 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 16:33:48 +0000 Subject: [PATCH 05/24] Log Lambda context in handler function --- infrastructure/environments/preview/handler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index bf432f9..fca2f24 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -7,6 +7,7 @@ def handler(event: dict[str, Any], context): + logger.info("Lambda context: %s", context) headers = event.get("headers", {}) or {} # Log headers to CloudWatch From 16dbd4706fc8e6f51f63f976484d09c77ab271a0 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 16:37:08 +0000 Subject: [PATCH 06/24] Update mock Lambda artifact filename in preview environment workflow --- .github/workflows/preview-env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 997d966..7de50d5 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -186,7 +186,7 @@ jobs: wait_for_lambda_ready aws lambda update-function-configuration --function-name "$MFN" --handler "${{ env.LAMBDA_HANDLER }}" || true wait_for_lambda_ready - aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://artifact.zip" --publish + aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish else aws lambda create-function --function-name "$MFN" \ --runtime "${{ env.LAMBDA_RUNTIME }}" \ From 5a29aca6421cc17a766c9abf9e504e7c7af60dbd Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 16:45:06 +0000 Subject: [PATCH 07/24] Add smoke test for mock URL and update deployment comments --- .github/workflows/preview-env.yaml | 62 +++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 7de50d5..23221de 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -271,6 +271,57 @@ jobs: echo "http_result=unexpected-status" >> "$GITHUB_OUTPUT" exit 0 + - name: Smoke test mock URL + if: github.event.action != 'closed' + id: smoke-mock + env: + PREVIEW_URL: ${{ steps.names.outputs.mock_preview_url }} + run: | + if [ -z "$PREVIEW_URL" ] || [ "$PREVIEW_URL" = "null" ]; then + echo "Mock URL missing" + echo "http_status=missing" >> "$GITHUB_OUTPUT" + echo "http_result=missing-url" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Reachability check: allow 404 (app routes might not exist yet) but fail otherwise + printf '%s' "$_cds_pathology_dev_mtls_client1_key_secret" > /tmp/client1-key.pem + printf '%s' "$_cds_pathology_dev_mtls_client1_key_public" > /tmp/client1-cert.pem + STATUS=$(curl \ + --cert /tmp/client1-cert.pem \ + --key /tmp/client1-key.pem \ + --silent \ + --output /tmp/preview.headers \ + --write-out '%{http_code}' \ + --head \ + --max-time 30 \ + -X GET "$PREVIEW_URL"/_status || true) + rm -f /tmp/client1-key.pem + rm -f /tmp/client1-cert.pem + + if [ "$STATUS" = "404" ]; then + echo "Mock responded with expected 404" + echo "http_status=404" >> "$GITHUB_OUTPUT" + echo "http_result=allowed-404" >> "$GITHUB_OUTPUT" + exit 0 + fi + + if [[ "$STATUS" =~ ^[0-9]{3}$ ]] && [ "$STATUS" -ge 200 ] && [ "$STATUS" -lt 400 ]; then + echo "Mock responded with status $STATUS" + echo "http_status=$STATUS" >> "$GITHUB_OUTPUT" + echo "http_result=success" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "Mock responded with unexpected status $STATUS" + if [ -f /tmp/preview.headers ]; then + echo "Response headers:" + cat /tmp/preview.headers + fi + echo "http_status=$STATUS" >> "$GITHUB_OUTPUT" + echo "http_result=unexpected-status" >> "$GITHUB_OUTPUT" + exit 0 + - name: Get proxygen machine user details id: proxygen-machine-user uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 @@ -306,13 +357,17 @@ jobs: with: script: | const fn = '${{ steps.names.outputs.function_name }}'; + const mock_fn = '${{ steps.names.outputs.mock_function_name }}'; const url = '${{ steps.names.outputs.preview_url }}'; + const mock_url = '${{ steps.names.outputs.mock_preview_url }}'; const proxy_url = 'https://internal-dev.api.service.nhs.uk/${{ env.PROXYGEN_API_NAME }}-pr-${{ github.event.pull_request.number }}'; const owner = context.repo.owner; const repo = context.repo.repo; const issueNumber = context.issue.number; const smokeStatus = '${{ steps.smoke-test.outputs.http_status }}' || 'n/a'; const smokeResult = '${{ steps.smoke-test.outputs.http_result }}' || 'not-run'; + const smokeMockStatus = '${{ steps.smoke-mock.outputs.http_status }}' || 'n/a'; + const smokeMockResult = '${{ steps.smoke-mock.outputs.http_result }}' || 'not-run'; const smokeLabels = { success: ':white_check_mark: Passed', @@ -322,7 +377,7 @@ jobs: }; const smokeReadable = smokeLabels[smokeResult] ?? smokeResult; - + const smokeMockReadable = smokeLabels[smokeMockResult] ?? smokeMockResult; const { data: comments } = await github.rest.issues.listComments({ owner, repo, @@ -346,9 +401,12 @@ jobs: const lines = [ '**Deployment Complete**', `- Preview URL: [${url}](${url}) — [Status endpoint](${url}/_status)`, - `- Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, + `-- Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, + `- Mock URL: [${mock_url}](${mock_url})`, + `-- Smoke Mock Test: ${smokeMockReadable} (HTTP ${smokeMockStatus})`, `- Proxy URL: [${proxy_url}](${proxy_url})`, `- Lambda Function: ${fn}`, + `- Mock Lambda Function: ${mock_fn}`, ]; await github.rest.issues.createComment({ From aada71f31bfd8929a062c9d11f1d5c418097a3af Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 16:54:10 +0000 Subject: [PATCH 08/24] Update Lambda handler to use mock handler and refine deployment status message --- .github/workflows/preview-env.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 23221de..9b7aa75 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -184,7 +184,7 @@ jobs: } if aws lambda get-function --function-name "$MFN" >/dev/null 2>&1; then wait_for_lambda_ready - aws lambda update-function-configuration --function-name "$MFN" --handler "${{ env.LAMBDA_HANDLER }}" || true + aws lambda update-function-configuration --function-name "$MFN" --handler "${{ env.MOCK_LAMBDA_HANDLER }}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish else @@ -400,7 +400,7 @@ jobs: const lines = [ '**Deployment Complete**', - `- Preview URL: [${url}](${url}) — [Status endpoint](${url}/_status)`, + `- Preview URL: [${url}](${url}) — [Status](${url}/_status)`, `-- Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, `- Mock URL: [${mock_url}](${mock_url})`, `-- Smoke Mock Test: ${smokeMockReadable} (HTTP ${smokeMockStatus})`, From 777ad8c76ce57086cb87b53143d2c2dfaeadfd9c Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Mon, 16 Feb 2026 17:05:04 +0000 Subject: [PATCH 09/24] Format deployment status message for better readability in preview environment --- .github/workflows/preview-env.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 9b7aa75..7750188 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -401,9 +401,9 @@ jobs: const lines = [ '**Deployment Complete**', `- Preview URL: [${url}](${url}) — [Status](${url}/_status)`, - `-- Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, + ` - Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, `- Mock URL: [${mock_url}](${mock_url})`, - `-- Smoke Mock Test: ${smokeMockReadable} (HTTP ${smokeMockStatus})`, + ` - Smoke Mock Test: ${smokeMockReadable} (HTTP ${smokeMockStatus})`, `- Proxy URL: [${proxy_url}](${proxy_url})`, `- Lambda Function: ${fn}`, `- Mock Lambda Function: ${mock_fn}`, From 012b56a7d4fbf9855d70b190be40ce3629b07588 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 09:51:27 +0000 Subject: [PATCH 10/24] Enhance Lambda function environment variables handling for mock deployment --- .github/workflows/preview-env.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 7750188..7debe72 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -100,7 +100,11 @@ jobs: PREFIX=${{ env.PREVIEW_PREFIX }} MOCK_PREFIX=${{ env.MOCK_PREFIX }} MAX_FN_LEN=62 - MAX_SAFE_LEN=$((MAX_FN_LEN - ${#PREFIX})) + MAX_PREFIX_LEN=${#PREFIX} + if [ ${#MOCK_PREFIX} -gt "$MAX_PREFIX_LEN" ]; then + MAX_PREFIX_LEN=${#MOCK_PREFIX} + fi + MAX_SAFE_LEN=$((MAX_FN_LEN - MAX_PREFIX_LEN)) if [ ${#SAFE} -gt "$MAX_SAFE_LEN" ]; then SAFE=${SAFE:0:MAX_SAFE_LEN} fi @@ -193,6 +197,8 @@ jobs: --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ --zip-file "fileb://mock_artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ + --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ + CLIENT_PRIVATE_KEY_ARN=mock}" \ --publish wait_for_lambda_ready fi From 990e332505e753ed8191c70cc10753bb00f6476e Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 10:06:00 +0000 Subject: [PATCH 11/24] Update mock Lambda configuration to include environment variables --- .github/workflows/preview-env.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 7debe72..748a6eb 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -188,7 +188,10 @@ jobs: } if aws lambda get-function --function-name "$MFN" >/dev/null 2>&1; then wait_for_lambda_ready - aws lambda update-function-configuration --function-name "$MFN" --handler "${{ env.MOCK_LAMBDA_HANDLER }}" || true + aws lambda update-function-configuration --function-name "$MFN" \ + --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ + --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ + CLIENT_PRIVATE_KEY_ARN=mock}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish else From 6147b9a3e1c54e082e79553774227ac88a72b35d Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 10:21:55 +0000 Subject: [PATCH 12/24] Add environment variables to Lambda configuration --- .github/workflows/preview-env.yaml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 748a6eb..abb9255 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -140,7 +140,16 @@ jobs: } if aws lambda get-function --function-name "$FN" >/dev/null 2>&1; then wait_for_lambda_ready - aws lambda update-function-configuration --function-name "$FN" --handler "${{ env.LAMBDA_HANDLER }}" || true + aws lambda update-function-configuration --function-name "$FN" \ + --handler "${{ env.LAMBDA_HANDLER }}" \ + --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=mock, \ + APIM_PRIVATE_KEY_ARN=mock, \ + APIM_API_KEY_ARN=mock, \ + APIM_MTLS_CERT_ARN=mock, \ + APIM_MTLS_KEY_ARN=mock, \ + APIM_TOKEN_URL=mock, \ + PDM_BUNDLE_URL=mock, \ + MNS_EVENT_URL=mock}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$FN" --zip-file "fileb://artifact.zip" --publish else @@ -149,6 +158,14 @@ jobs: --handler "${{ env.LAMBDA_HANDLER }}" \ --zip-file "fileb://artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ + --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=mock, \ + APIM_PRIVATE_KEY_ARN=mock, \ + APIM_API_KEY_ARN=mock, \ + APIM_MTLS_CERT_ARN=mock, \ + APIM_MTLS_KEY_ARN=mock, \ + APIM_TOKEN_URL=mock, \ + PDM_BUNDLE_URL=mock, \ + MNS_EVENT_URL=mock}" \ --publish wait_for_lambda_ready fi @@ -191,7 +208,7 @@ jobs: aws lambda update-function-configuration --function-name "$MFN" \ --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ - CLIENT_PRIVATE_KEY_ARN=mock}" || true + INDEX_TAG=mock}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish else @@ -201,7 +218,7 @@ jobs: --zip-file "fileb://mock_artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ - CLIENT_PRIVATE_KEY_ARN=mock}" \ + INDEX_TAG=mock}" \ --publish wait_for_lambda_ready fi From 07756492c03f4123fc42c430f677dc22811fa928 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 10:29:52 +0000 Subject: [PATCH 13/24] Add safe branch output to mock Lambda deployment configuration --- .github/workflows/preview-env.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index abb9255..1755bb5 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -188,6 +188,7 @@ jobs: run: | cd infrastructure/environments/preview MFN="${{ steps.names.outputs.mock_function_name }}" + SAFE="${{ steps.branch.outputs.safe }}" echo "Deploying mock function: $MFN" wait_for_lambda_ready() { while true; do @@ -208,7 +209,7 @@ jobs: aws lambda update-function-configuration --function-name "$MFN" \ --handler "${{ env.MOCK_LAMBDA_HANDLER }}" \ --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ - INDEX_TAG=mock}" || true + DDB_INDEX_TAG=$SAFE}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish else @@ -218,7 +219,7 @@ jobs: --zip-file "fileb://mock_artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ --environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \ - INDEX_TAG=mock}" \ + DDB_INDEX_TAG=$SAFE}" \ --publish wait_for_lambda_ready fi From 5dbaba2b9a1a7d0e13ce14038ab8d03eb88e305c Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 11:36:54 +0000 Subject: [PATCH 14/24] Update Lambda configuration to use dynamic URLs and token expiry threshold --- .github/workflows/preview-env.yaml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 1755bb5..d35d9ce 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -120,13 +120,18 @@ jobs: # ---------- Handle application ---------- - name: Create or update preview Lambda (on open/sync/reopen) if: github.event.action != 'closed' + env: + MOCK_URL: ${{ steps.names.outputs.mock_preview_url }} run: | cd pathology-api/target/ FN="${{ steps.names.outputs.function_name }}" + EXPIRY_THRESHOLD="${TOKEN_EXPIRY_THRESHOLD:-840s}" echo "Deploying preview function: $FN" wait_for_lambda_ready() { while true; do - status=$(aws lambda get-function-configuration --function-name "$FN" --query 'LastUpdateStatus' --output text 2>/dev/null || echo "Unknown") + status=$(aws lambda get-function-configuration --function-name "$FN" \ + --query 'LastUpdateStatus' \ + --output text 2>/dev/null || echo "Unknown") if [ "$status" = "Successful" ] || [ "$status" = "Unknown" ]; then break fi @@ -142,30 +147,32 @@ jobs: wait_for_lambda_ready aws lambda update-function-configuration --function-name "$FN" \ --handler "${{ env.LAMBDA_HANDLER }}" \ - --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=mock, \ + --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=$EXPIRY_THRESHOLD, \ APIM_PRIVATE_KEY_ARN=mock, \ APIM_API_KEY_ARN=mock, \ APIM_MTLS_CERT_ARN=mock, \ APIM_MTLS_KEY_ARN=mock, \ - APIM_TOKEN_URL=mock, \ - PDM_BUNDLE_URL=mock, \ - MNS_EVENT_URL=mock}" || true + APIM_TOKEN_URL=$MOCK_URL, \ + PDM_BUNDLE_URL=$MOCK_URL, \ + MNS_EVENT_URL=$MOCK_URL}" || true wait_for_lambda_ready - aws lambda update-function-code --function-name "$FN" --zip-file "fileb://artifact.zip" --publish + aws lambda update-function-code --function-name "$FN" \ + --zip-file "fileb://artifact.zip" \ + --publish else aws lambda create-function --function-name "$FN" \ --runtime "${{ env.LAMBDA_RUNTIME }}" \ --handler "${{ env.LAMBDA_HANDLER }}" \ --zip-file "fileb://artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ - --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=mock, \ + --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=$EXPIRY_THRESHOLD, \ APIM_PRIVATE_KEY_ARN=mock, \ APIM_API_KEY_ARN=mock, \ APIM_MTLS_CERT_ARN=mock, \ APIM_MTLS_KEY_ARN=mock, \ - APIM_TOKEN_URL=mock, \ - PDM_BUNDLE_URL=mock, \ - MNS_EVENT_URL=mock}" \ + APIM_TOKEN_URL=$MOCK_URL, \ + PDM_BUNDLE_URL=$MOCK_URL, \ + MNS_EVENT_URL=$MOCK_URL}" \ --publish wait_for_lambda_ready fi From 94431e9267edc62dabfa28d2c3ae3d4d18ba6fe7 Mon Sep 17 00:00:00 2001 From: Jack Wainwright <79214177+nhsd-jack-wainwright@users.noreply.github.com> Date: Fri, 13 Feb 2026 17:54:29 +0000 Subject: [PATCH 15/24] [CDAPI-95]: Removed terraform lint from pre-commit and GitHub Actions. Removed terraform lint from the codebase as no terraform is currently included as part of this repository. --- .github/actions/lint-terraform/action.yaml | 20 -------- .github/workflows/stage-1-commit.yaml | 9 ---- .tool-versions | 2 - scripts/config/pre-commit.yaml | 5 -- scripts/githooks/check-terraform-format.sh | 56 ---------------------- 5 files changed, 92 deletions(-) delete mode 100644 .github/actions/lint-terraform/action.yaml delete mode 100755 scripts/githooks/check-terraform-format.sh diff --git a/.github/actions/lint-terraform/action.yaml b/.github/actions/lint-terraform/action.yaml deleted file mode 100644 index d5dfe35..0000000 --- a/.github/actions/lint-terraform/action.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: "Lint Terraform" -description: "Lint Terraform" -inputs: - root-modules: - description: "Comma separated list of root module directories to validate, content of the 'infrastructure/environments' is checked by default" - required: false -runs: - using: "composite" - steps: - - name: "Check Terraform format" - shell: bash - run: | - check_only=true scripts/githooks/check-terraform-format.sh - - name: "Validate Terraform" - shell: bash - run: | - stacks=${{ inputs.root-modules }} - for dir in $(find infrastructure/environments -maxdepth 1 -mindepth 1 -type d; echo ${stacks//,/$'\n'}); do - dir=$dir make terraform-validate - done diff --git a/.github/workflows/stage-1-commit.yaml b/.github/workflows/stage-1-commit.yaml index e1ba638..0088a63 100644 --- a/.github/workflows/stage-1-commit.yaml +++ b/.github/workflows/stage-1-commit.yaml @@ -88,15 +88,6 @@ jobs: fetch-depth: 0 # Full history is needed to compare branches - name: "Check English usage" uses: ./.github/actions/check-english-usage - lint-terraform: - name: "Lint Terraform" - runs-on: ubuntu-latest - timeout-minutes: 2 - steps: - - name: "Checkout code" - uses: actions/checkout@v6 - - name: "Lint Terraform" - uses: ./.github/actions/lint-terraform count-lines-of-code: name: "Count lines of code" runs-on: ubuntu-latest diff --git a/.tool-versions b/.tool-versions index ac5171c..052bb56 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,6 +1,5 @@ # This file is for you! Please, updated to the versions agreed by your team. -terraform 1.7.0 pre-commit 3.6.0 gitleaks 8.18.4 @@ -15,7 +14,6 @@ gitleaks 8.18.4 # docker/ghcr.io/make-ops-tools/gocloc latest@sha256:6888e62e9ae693c4ebcfed9f1d86c70fd083868acb8815fe44b561b9a73b5032 # SEE: https://github.com/make-ops-tools/gocloc/pkgs/container/gocloc # docker/ghcr.io/nhs-england-tools/github-runner-image 20230909-321fd1e-rt@sha256:ce4fd6035dc450a50d3cbafb4986d60e77cb49a71ab60a053bb1b9518139a646 # SEE: https://github.com/nhs-england-tools/github-runner-image/pkgs/container/github-runner-image # docker/hadolint/hadolint 2.12.0-alpine@sha256:7dba9a9f1a0350f6d021fb2f6f88900998a4fb0aaf8e4330aa8c38544f04db42 # SEE: https://hub.docker.com/r/hadolint/hadolint/tags -# docker/hashicorp/terraform 1.12.2@sha256:b3d13c9037d2bd858fe10060999aa7ca56d30daafe067d7715b29b3d4f5b162f # SEE: https://hub.docker.com/r/hashicorp/terraform/tags # docker/koalaman/shellcheck latest@sha256:e40388688bae0fcffdddb7e4dea49b900c18933b452add0930654b2dea3e7d5c # SEE: https://hub.docker.com/r/koalaman/shellcheck/tags # docker/mstruebing/editorconfig-checker 2.7.1@sha256:dd3ca9ea50ef4518efe9be018d669ef9cf937f6bb5cfe2ef84ff2a620b5ddc24 # SEE: https://hub.docker.com/r/mstruebing/editorconfig-checker/tags # docker/sonarsource/sonar-scanner-cli 10.0@sha256:0bc49076468d2955948867620b2d98d67f0d59c0fd4a5ef1f0afc55cf86f2079 # SEE: https://hub.docker.com/r/sonarsource/sonar-scanner-cli/tags diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index e63b58d..0cc37cd 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -25,11 +25,6 @@ repos: args: ["-c", "check=staged-changes ./scripts/githooks/check-english-usage.sh"] language: system pass_filenames: false - - id: lint-terraform - name: Lint Terraform - entry: ./scripts/githooks/check-terraform-format.sh - language: script - pass_filenames: false - id: python-linting-and-formatting name: Python linting and formatting entry: ./scripts/githooks/python-lint-and-format.sh diff --git a/scripts/githooks/check-terraform-format.sh b/scripts/githooks/check-terraform-format.sh deleted file mode 100755 index 7255e51..0000000 --- a/scripts/githooks/check-terraform-format.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -# WARNING: Please DO NOT edit this file! It is maintained in the Repository Template (https://github.com/nhs-england-tools/repository-template). Raise a PR instead. - -set -euo pipefail - -# Pre-commit git hook to check format Terraform code. -# -# Usage: -# $ [options] ./check-terraform-format.sh -# -# Options: -# check_only=true # Do not format, run check only, default is 'false' -# FORCE_USE_DOCKER=true # If set to true the command is run in a Docker container, default is 'false' -# VERBOSE=true # Show all the executed commands, default is 'false' - -# ============================================================================== - -function main() { - - cd "$(git rev-parse --show-toplevel)" - - local check_only=${check_only:-false} - check_only=$check_only terraform-fmt -} - -# Format Terraform files. -# Arguments (provided as environment variables): -# check_only=[do not format, run check only] -function terraform-fmt() { - - local opts= - if is-arg-true "$check_only"; then - opts="-check" - fi - opts=$opts make terraform-fmt -} - -# ============================================================================== - -function is-arg-true() { - - if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then - return 0 - else - return 1 - fi -} - -# ============================================================================== - -is-arg-true "${VERBOSE:-false}" && set -x - -main "$@" - -exit 0 From 0bfea19133615997258c2e1ce20398ccb0eca547 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 11:41:52 +0000 Subject: [PATCH 16/24] Update mock URLs in Lambda configuration for APIM, PDM, and MNS endpoints --- .github/workflows/preview-env.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index d35d9ce..67fd7b6 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -152,9 +152,9 @@ jobs: APIM_API_KEY_ARN=mock, \ APIM_MTLS_CERT_ARN=mock, \ APIM_MTLS_KEY_ARN=mock, \ - APIM_TOKEN_URL=$MOCK_URL, \ - PDM_BUNDLE_URL=$MOCK_URL, \ - MNS_EVENT_URL=$MOCK_URL}" || true + APIM_TOKEN_URL=$MOCK_URL/apim, \ + PDM_BUNDLE_URL=$MOCK_URL/pdm, \ + MNS_EVENT_URL=$MOCK_URL/mns}" || true wait_for_lambda_ready aws lambda update-function-code --function-name "$FN" \ --zip-file "fileb://artifact.zip" \ @@ -170,9 +170,9 @@ jobs: APIM_API_KEY_ARN=mock, \ APIM_MTLS_CERT_ARN=mock, \ APIM_MTLS_KEY_ARN=mock, \ - APIM_TOKEN_URL=$MOCK_URL, \ - PDM_BUNDLE_URL=$MOCK_URL, \ - MNS_EVENT_URL=$MOCK_URL}" \ + APIM_TOKEN_URL=$MOCK_URL/apim, \ + PDM_BUNDLE_URL=$MOCK_URL/pdm, \ + MNS_EVENT_URL=$MOCK_URL/mns}" \ --publish wait_for_lambda_ready fi From 24a9de018fec0bbbadb9bb89ee6c267c528a158c Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 11:55:58 +0000 Subject: [PATCH 17/24] Add pragma directive to skip coverage for incoming request headers log --- infrastructure/environments/preview/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index fca2f24..a4bbc4a 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -11,7 +11,7 @@ def handler(event: dict[str, Any], context): headers = event.get("headers", {}) or {} # Log headers to CloudWatch - logger.info("Incoming request headers:") + logger.info("Incoming request headers:") # pragma: no cover for k, v in headers.items(): logger.info("%s: %s", k, v) From 5bacdcbd182e58526e2060b8ea79b24a300737de Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 12:00:23 +0000 Subject: [PATCH 18/24] Fix formatting of log header comment in handler function --- infrastructure/environments/preview/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index a4bbc4a..e595d07 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -11,7 +11,7 @@ def handler(event: dict[str, Any], context): headers = event.get("headers", {}) or {} # Log headers to CloudWatch - logger.info("Incoming request headers:") # pragma: no cover + logger.info("Incoming request headers:") # pragma: no cover for k, v in headers.items(): logger.info("%s: %s", k, v) From 063f54f90d18d9f5760904b871a7f18ac1f0741e Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 13:39:17 +0000 Subject: [PATCH 19/24] Enhance handler function documentation and update coverage exclusions for preview environment --- infrastructure/environments/preview/handler.py | 15 +++++++++++++-- sonar-project.properties | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index e595d07..49aad56 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -6,12 +6,23 @@ logger.setLevel(logging.INFO) -def handler(event: dict[str, Any], context): +def handler(event: dict[str, Any], context: Any): + """Handler for the preview environment. This simply returns a 200 response with + the request headers, which can be used to verify and debug how the environment + is working and to inspect the incoming request. + + Args: + event (dict[str, Any]): The event dictionary containing request data from API Gateway. + context (Any): AWS lambda context object (what the lambda is running in) + + Returns: + dict: Diagnostic 200 response with request headers. + """ logger.info("Lambda context: %s", context) headers = event.get("headers", {}) or {} # Log headers to CloudWatch - logger.info("Incoming request headers:") # pragma: no cover + logger.info("Incoming request headers:") for k, v in headers.items(): logger.info("%s: %s", k, v) diff --git a/sonar-project.properties b/sonar-project.properties index def2564..897538e 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -13,6 +13,6 @@ sonar.exclusions=docs/**,pathology-api/test-artefacts/**,pathology-api/coverage- sonar.tests=pathology-api sonar.test.inclusions=pathology-api/**/test_*.py, pathology-api/tests/** -sonar.coverage.exclusions=**/tests/**,**/features/**,**/test_*.py,infrastructure/images/api-gateway-mock/resources/** +sonar.coverage.exclusions=**/tests/**,**/features/**,**/test_*.py,infrastructure/images/api-gateway-mock/resources/**,**/infrastructure/environments/preview/** # Set Python version for more precise analysis sonar.python.version=3.14 From ac8d9f1c6edb609830aa28c4afd862ee766f79d6 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 13:41:29 +0000 Subject: [PATCH 20/24] Fix formatting of docstring in handler function for improved readability --- infrastructure/environments/preview/handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index 49aad56..02a4990 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -8,8 +8,8 @@ def handler(event: dict[str, Any], context: Any): """Handler for the preview environment. This simply returns a 200 response with - the request headers, which can be used to verify and debug how the environment - is working and to inspect the incoming request. + the request headers, which can be used to verify and debug how the environment + is working and to inspect the incoming request. Args: event (dict[str, Any]): The event dictionary containing request data from API Gateway. From 6329d648b2c6a6bce475748e66216b382e88a331 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 13:42:09 +0000 Subject: [PATCH 21/24] Fix formatting of docstring in handler function for consistency --- infrastructure/environments/preview/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index 02a4990..043b6bd 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -8,7 +8,7 @@ def handler(event: dict[str, Any], context: Any): """Handler for the preview environment. This simply returns a 200 response with - the request headers, which can be used to verify and debug how the environment + the request headers, which can be used to verify and debug how the environment is working and to inspect the incoming request. Args: From f392ce4cebfac0eade1f9d7b0948cc965de5f9a6 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 13:44:47 +0000 Subject: [PATCH 22/24] Fix docstring formatting in handler function for clarity --- infrastructure/environments/preview/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/environments/preview/handler.py b/infrastructure/environments/preview/handler.py index 043b6bd..5ca294e 100644 --- a/infrastructure/environments/preview/handler.py +++ b/infrastructure/environments/preview/handler.py @@ -12,7 +12,7 @@ def handler(event: dict[str, Any], context: Any): is working and to inspect the incoming request. Args: - event (dict[str, Any]): The event dictionary containing request data from API Gateway. + event (dict[str, Any]): Dictionary containing request data from API Gateway. context (Any): AWS lambda context object (what the lambda is running in) Returns: From 4b7d1c81c9d7fbe1d56a15faa5f2a0642911ad09 Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 14:13:27 +0000 Subject: [PATCH 23/24] Add environment variables for APIM integration in preview workflow --- .github/workflows/preview-env.yaml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index 67fd7b6..ca8896d 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -126,6 +126,10 @@ jobs: cd pathology-api/target/ FN="${{ steps.names.outputs.function_name }}" EXPIRY_THRESHOLD="${TOKEN_EXPIRY_THRESHOLD:-840s}" + PRIVATE_KEY="${APIM_PRIVATE_KEY:-/cds/pathology/dev/apim/private-key}" + API_KEY="${APIM_APIKEY:-/cds/pathology/dev/apim/api-key}" + MTLS_CERT="${API_MTLS_CERT:-/cds/pathology/dev/mtls/client1-key-public}" + MTLS_KEY="${API_MTLS_KEY:-/cds/pathology/dev/mtls/client1-key-secret}" echo "Deploying preview function: $FN" wait_for_lambda_ready() { while true; do @@ -148,10 +152,10 @@ jobs: aws lambda update-function-configuration --function-name "$FN" \ --handler "${{ env.LAMBDA_HANDLER }}" \ --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=$EXPIRY_THRESHOLD, \ - APIM_PRIVATE_KEY_ARN=mock, \ - APIM_API_KEY_ARN=mock, \ - APIM_MTLS_CERT_ARN=mock, \ - APIM_MTLS_KEY_ARN=mock, \ + APIM_PRIVATE_KEY_NAME=$PRIVATE_KEY, \ + APIM_API_KEY_NAME=$API_KEY, \ + APIM_MTLS_CERT_NAME=$MTLS_CERT, \ + APIM_MTLS_KEY_NAME=$MTLS_KEY, \ APIM_TOKEN_URL=$MOCK_URL/apim, \ PDM_BUNDLE_URL=$MOCK_URL/pdm, \ MNS_EVENT_URL=$MOCK_URL/mns}" || true @@ -166,10 +170,10 @@ jobs: --zip-file "fileb://artifact.zip" \ --role "${{ steps.role-select.outputs.lambda_role }}" \ --environment "Variables={APIM_TOKEN_EXPIRY_THRESHOLD=$EXPIRY_THRESHOLD, \ - APIM_PRIVATE_KEY_ARN=mock, \ - APIM_API_KEY_ARN=mock, \ - APIM_MTLS_CERT_ARN=mock, \ - APIM_MTLS_KEY_ARN=mock, \ + APIM_PRIVATE_KEY_NAME=$PRIVATE_KEY, \ + APIM_API_KEY_NAME=$API_KEY, \ + APIM_MTLS_CERT_NAME=$MTLS_CERT, \ + APIM_MTLS_KEY_NAME=$MTLS_KEY, \ APIM_TOKEN_URL=$MOCK_URL/apim, \ PDM_BUNDLE_URL=$MOCK_URL/pdm, \ MNS_EVENT_URL=$MOCK_URL/mns}" \ From df69cc13817a97af1fd77095b89500d2764fc6cb Mon Sep 17 00:00:00 2001 From: neil-sproston Date: Tue, 17 Feb 2026 14:15:51 +0000 Subject: [PATCH 24/24] Add APIM secrets to preview environment for enhanced security --- .github/workflows/preview-env.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/preview-env.yaml b/.github/workflows/preview-env.yaml index ca8896d..ec06cbf 100644 --- a/.github/workflows/preview-env.yaml +++ b/.github/workflows/preview-env.yaml @@ -122,6 +122,11 @@ jobs: if: github.event.action != 'closed' env: MOCK_URL: ${{ steps.names.outputs.mock_preview_url }} + EXPIRY_THRESHOLD: ${{ secrets.APIM_TOKEN_EXPIRY_THRESHOLD }} + APIM_PRIVATE_KEY: ${{ secrets.APIM_PRIVATE_KEY }} + APIM_APIKEY: ${{ secrets.APIM_APIKEY }} + API_MTLS_CERT: ${{ secrets.API_MTLS_CERT }} + API_MTLS_KEY: ${{ secrets.API_MTLS_KEY }} run: | cd pathology-api/target/ FN="${{ steps.names.outputs.function_name }}"