From c37dcedc2b4f4de0636b5494df73a09c4a2218c4 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 5 Sep 2025 16:33:40 +0100 Subject: [PATCH 01/44] feat: code deploy setup --- infra/modules/aws/lambda/data.tf | 37 +++++++++++++++++++++++ infra/modules/aws/lambda/main.tf | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/infra/modules/aws/lambda/data.tf b/infra/modules/aws/lambda/data.tf index 688a97e..3ad5f04 100644 --- a/infra/modules/aws/lambda/data.tf +++ b/infra/modules/aws/lambda/data.tf @@ -14,3 +14,40 @@ data "aws_iam_policy_document" "assume_role" { actions = ["sts:AssumeRole"] } } + +data "aws_iam_policy_document" "code_deploy_assume" { + statement { + actions = ["sts:AssumeRole"] + principals { + type = "Service" + identifiers = ["codedeploy.amazonaws.com"] + } + } +} + +data "aws_iam_policy_document" "codedeploy_lambda" { + statement { + sid = "LambdaControl" + effect = "Allow" + actions = [ + "lambda:GetFunction", + "lambda:PublishVersion", + "lambda:GetAlias", + "lambda:CreateAlias", + "lambda:UpdateAlias", + "lambda:ListAliases", + "lambda:ListVersionsByFunction", + ] + resources = [ + aws_lambda_function.fn.arn, + "${aws_lambda_function.fn.arn}:*", + ] + } + + statement { + sid = "DescribeAlarms" + effect = "Allow" + actions = ["cloudwatch:DescribeAlarms"] + resources = ["*"] + } +} diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index f61d1d7..f0f88b5 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -11,4 +11,55 @@ resource "aws_lambda_function" "lambda" { s3_bucket = data.aws_s3_bucket.lambda_code.bucket s3_key = local.lambda_code_zip_key + + # publish ONE immutable version so we can create an alias + publish = true + + lifecycle { + # Do not update on changes to the initial s3 file version + ignore_changes = [ + s3_bucket, + s3_key, + s3_object_version, + ] + } +} + +resource "aws_lambda_alias" "live" { + name = var.environment + function_name = aws_lambda_function.lambda.arn + function_version = aws_lambda_function.lambda.version + + # CodeDeploy will repoint this alias → ignore drift + lifecycle { + ignore_changes = [function_version, routing_config] + } +} + +resource "aws_codedeploy_app" "app" { + name = "${local.lambda_name}-app" + compute_platform = "Lambda" +} + +resource "aws_iam_role" "cd_role" { + name = "${local.lambda_name}-codedeploy-role" + assume_role_policy = data.aws_iam_policy_document.code_deploy_assume.json +} + +resource "aws_iam_role_policy" "cd_lambda" { + name = "${local.lambda_name}-codedeploy-lambda" + role = aws_iam_role.cd_role.id + policy = data.aws_iam_policy_document.codedeploy_lambda.json +} + +resource "aws_codedeploy_deployment_group" "dg" { + app_name = aws_codedeploy_app.app.name + deployment_group_name = "${local.lambda_name}-dg" + service_role_arn = aws_iam_role.cd_role.arn + deployment_config_name = "CodeDeployDefault.LambdaCanary10Percent5Minutes" + + auto_rollback_configuration { + enabled = true + events = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"] + } } \ No newline at end of file From 9df4c764225840700123db19b39f94df0fe5e6e5 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 5 Sep 2025 16:42:01 +0100 Subject: [PATCH 02/44] chore: allow lambda to log to cloudwatch --- infra/modules/aws/lambda/data.tf | 22 ++++++++++++++++++++-- infra/modules/aws/lambda/main.tf | 7 ++++++- infra/modules/aws/lambda/outputs.tf | 6 +++++- infra/modules/aws/lambda/variables.tf | 7 +++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/infra/modules/aws/lambda/data.tf b/infra/modules/aws/lambda/data.tf index 3ad5f04..4a1c017 100644 --- a/infra/modules/aws/lambda/data.tf +++ b/infra/modules/aws/lambda/data.tf @@ -39,8 +39,8 @@ data "aws_iam_policy_document" "codedeploy_lambda" { "lambda:ListVersionsByFunction", ] resources = [ - aws_lambda_function.fn.arn, - "${aws_lambda_function.fn.arn}:*", + aws_lambda_function.lambda.arn, + "${aws_lambda_function.lambda.arn}:*", ] } @@ -51,3 +51,21 @@ data "aws_iam_policy_document" "codedeploy_lambda" { resources = ["*"] } } + +data "aws_iam_policy_document" "lambda_iam_policy" { + statement { + sid = "AllowLambdaCloudwatchLogGroupPut" + + actions = [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + + effect = "Allow" + + resources = [ + "${aws_cloudwatch_log_group.lambda_cloudwatch_group.arn}", + "${aws_cloudwatch_log_group.lambda_cloudwatch_group.arn}:*" + ] + } +} \ No newline at end of file diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index f0f88b5..7db22a8 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -25,6 +25,11 @@ resource "aws_lambda_function" "lambda" { } } +resource "aws_cloudwatch_log_group" "lambda_cloudwatch_group" { + name = "/aws/lambda/${local.lambda_name}" + retention_in_days = var.log_retention_days +} + resource "aws_lambda_alias" "live" { name = var.environment function_name = aws_lambda_function.lambda.arn @@ -62,4 +67,4 @@ resource "aws_codedeploy_deployment_group" "dg" { enabled = true events = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"] } -} \ No newline at end of file +} diff --git a/infra/modules/aws/lambda/outputs.tf b/infra/modules/aws/lambda/outputs.tf index 4fa3ebb..599d82a 100644 --- a/infra/modules/aws/lambda/outputs.tf +++ b/infra/modules/aws/lambda/outputs.tf @@ -4,4 +4,8 @@ output "name" { output "arn" { value = aws_lambda_function.lambda.arn -} \ No newline at end of file +} + +output "cloudwatch_log_group" { + value = aws_cloudwatch_log_group.lambda_cloudwatch_group.name +} diff --git a/infra/modules/aws/lambda/variables.tf b/infra/modules/aws/lambda/variables.tf index 8fb1602..b0ce6ee 100644 --- a/infra/modules/aws/lambda/variables.tf +++ b/infra/modules/aws/lambda/variables.tf @@ -27,3 +27,10 @@ variable "lambda_version" { description = "Lambda code version to be deployed. Used in locating zip file keys" } ### end of dynamic vars required for resources ### + + +variable "log_retention_days" { + type = number + description = "Number of days to hold logs" + default = 1 +} \ No newline at end of file From 9766b389344908112b9e881ce9ddd6993c62c125 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 5 Sep 2025 16:46:05 +0100 Subject: [PATCH 03/44] fix: fmt --- infra/modules/aws/lambda/variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/modules/aws/lambda/variables.tf b/infra/modules/aws/lambda/variables.tf index b0ce6ee..49fce64 100644 --- a/infra/modules/aws/lambda/variables.tf +++ b/infra/modules/aws/lambda/variables.tf @@ -32,5 +32,5 @@ variable "lambda_version" { variable "log_retention_days" { type = number description = "Number of days to hold logs" - default = 1 + default = 1 } \ No newline at end of file From cacb3de53140e7f36eed8d61a298b606dd838daa Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:01:01 +0100 Subject: [PATCH 04/44] chore: rename resource --- infra/modules/aws/lambda/main.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index 7db22a8..7692219 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -46,21 +46,21 @@ resource "aws_codedeploy_app" "app" { compute_platform = "Lambda" } -resource "aws_iam_role" "cd_role" { +resource "aws_iam_role" "code_deploy_role" { name = "${local.lambda_name}-codedeploy-role" assume_role_policy = data.aws_iam_policy_document.code_deploy_assume.json } resource "aws_iam_role_policy" "cd_lambda" { name = "${local.lambda_name}-codedeploy-lambda" - role = aws_iam_role.cd_role.id + role = aws_iam_role.code_deploy_role.id policy = data.aws_iam_policy_document.codedeploy_lambda.json } resource "aws_codedeploy_deployment_group" "dg" { app_name = aws_codedeploy_app.app.name deployment_group_name = "${local.lambda_name}-dg" - service_role_arn = aws_iam_role.cd_role.arn + service_role_arn = aws_iam_role.code_deploy_role.arn deployment_config_name = "CodeDeployDefault.LambdaCanary10Percent5Minutes" auto_rollback_configuration { From db1cf545ecd8ea2ed1d453521fa2d7285dfa6d3f Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:01:16 +0100 Subject: [PATCH 05/44] chore: s3 delete old files --- infra/modules/aws/code_bucket/main.tf | 15 +++++++++++++++ infra/modules/aws/code_bucket/variables.tf | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/infra/modules/aws/code_bucket/main.tf b/infra/modules/aws/code_bucket/main.tf index 01c049c..f7b85f7 100644 --- a/infra/modules/aws/code_bucket/main.tf +++ b/infra/modules/aws/code_bucket/main.tf @@ -10,3 +10,18 @@ resource "aws_s3_bucket_ownership_controls" "lambda" { object_ownership = "BucketOwnerEnforced" } } + +resource "aws_s3_bucket_lifecycle_configuration" "delete_old_files" { + count = var.s3_expiration_days > 0 ? 1 : 0 + + bucket = aws_s3_bucket.lambda.id + + rule { + id = "delete-expired-objects" + status = "Enabled" + + expiration { + days = var.s3_expiration_days + } + } +} diff --git a/infra/modules/aws/code_bucket/variables.tf b/infra/modules/aws/code_bucket/variables.tf index ab4c7c7..ff218ad 100644 --- a/infra/modules/aws/code_bucket/variables.tf +++ b/infra/modules/aws/code_bucket/variables.tf @@ -1,4 +1,13 @@ +### start of static vars set in root.hcl ### variable "lambda_bucket" { description = "S3 bucket to host lambda code files" type = string } +### end of static vars set in root.hcl ### + + +variable "s3_expiration_days" { + description = "Number of days before objects are deleted (set to 0 to disable)" + type = number + default = 0 +} From 48e78a5edeac09173edbde0c13828ae54c8a13ba Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:15:48 +0100 Subject: [PATCH 06/44] chore: outputs for code deploy --- infra/modules/aws/lambda/outputs.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/infra/modules/aws/lambda/outputs.tf b/infra/modules/aws/lambda/outputs.tf index 599d82a..59ae105 100644 --- a/infra/modules/aws/lambda/outputs.tf +++ b/infra/modules/aws/lambda/outputs.tf @@ -9,3 +9,11 @@ output "arn" { output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.lambda_cloudwatch_group.name } + +output "code_deploy_app_name" { + value = aws_codedeploy_app.app.name +} + +output "code_deploy_group_name" { + value = aws_codedeploy_deployment_group.dg.deployment_group_name +} From fde4398606a8532622a9b0cd7e8c9dde76c88671 Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:49:52 +0100 Subject: [PATCH 07/44] chore: lambda deploy flow --- .github/workflows/deploy.yml | 30 ++++++++++++----------- infra/modules/aws/api/outputs.tf | 16 +++++++++++++ infra/modules/aws/lambda/outputs.tf | 4 ++++ justfile | 37 +++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f900fe8..c9d7e2b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ env: AWS_OIDC_ROLE_ARN: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/aws-serverless-github-deploy-${{ inputs.environment }}-github-oidc-role jobs: - oidc: + setup: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -44,16 +44,7 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} tg_directory: infra/live/${{ inputs.environment }}/aws/oidc - backend: - needs: - - oidc - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ inputs.infra_version }} - - - name: check Lambda vars + - name: check Lambda version uses: chrispsheehan/just-aws-oidc-action@0.1.1 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} @@ -63,16 +54,27 @@ jobs: just_action: check-version api: - needs: - - oidc + needs: setup runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: ${{ inputs.infra_version }} - - name: Deploy API + - name: deploy api + id: deploy-api uses: chrispsheehan/terragrunt-aws-oidc-action@0.4.0 with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} tg_directory: infra/live/${{ inputs.environment }}/aws/api + + - name: check lambda version + uses: chrispsheehan/just-aws-oidc-action@0.1.1 + env: + BUCKET_NAME: ${{ inputs.lambda_bucket }} + LAMBDA_ZIP_KEY: ${{ steps.deploy-api.outputs.lambda_zip_key }} + CODE_DEPLOY_APP_NAME: ${{ steps.deploy-api.outputs.code_deploy_app_name }} + CODE_DEPLOY_GROUP_NAME: ${{ steps.deploy-api.outputs.code_deploy_group_name }} + with: + aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} + just_action: lambda-deploy diff --git a/infra/modules/aws/api/outputs.tf b/infra/modules/aws/api/outputs.tf index 67d5fa6..dcd2240 100644 --- a/infra/modules/aws/api/outputs.tf +++ b/infra/modules/aws/api/outputs.tf @@ -1,3 +1,19 @@ output "invoke_url" { value = aws_apigatewayv2_api.http_api.api_endpoint } + +output "cloudwatch_log_group" { + value = module.lambda_api.cloudwatch_log_group +} + +output "lambda_zip_key" { + value = module.lambda_api.lambda_zip_key +} + +output "code_deploy_app_name" { + value = module.lambda_api.code_deploy_app_name +} + +output "code_deploy_group_name" { + value = module.lambda_api.code_deploy_group_name +} diff --git a/infra/modules/aws/lambda/outputs.tf b/infra/modules/aws/lambda/outputs.tf index 59ae105..0e153bb 100644 --- a/infra/modules/aws/lambda/outputs.tf +++ b/infra/modules/aws/lambda/outputs.tf @@ -10,6 +10,10 @@ output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.lambda_cloudwatch_group.name } +output "lambda_zip_key" { + value = local.lambda_code_zip_key +} + output "code_deploy_app_name" { value = aws_codedeploy_app.app.name } diff --git a/justfile b/justfile index 11a3ebd..e4141af 100644 --- a/justfile +++ b/justfile @@ -147,3 +147,40 @@ backend-build: ) echo "✅ Done: backend/$app_name.zip" done + +lambda-deploy: + #!/usr/bin/env bash + DEPLOYMENT_ID=$(aws deploy create-deployment \ + --application-name $CODE_DEPLOY_APP_NAME \ + --deployment-group-name $CODE_DEPLOY_GROUP_NAME \ + --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes \ + --s3-location bucket=$BUCKET_NAME,key=$LAMBDA_ZIP_KEY,bundleType=zip \ + --query "deploymentId" --output text) + + MAX_ATTEMPTS=40 # ~10 minutes at 15s interval + SLEEP_INTERVAL=15 # seconds + + echo "🚀 Started deployment: $DEPLOYMENT_ID" + + for ((i=1; i<=MAX_ATTEMPTS; i++)); do + STATUS=$(aws deploy get-deployment \ + --deployment-id "$DEPLOYMENT_ID" \ + --query "deploymentInfo.status" \ + --output text) + + echo "Attempt $i: Deployment status is $STATUS" + + if [[ "$STATUS" == "Succeeded" ]]; then + echo "✅ Deployment $DEPLOYMENT_ID completed successfully." + exit 0 + elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then + echo "❌ Deployment $DEPLOYMENT_ID failed or was stopped." + exit 1 + fi + + sleep "$SLEEP_INTERVAL" + done + + echo "❌ Deployment $DEPLOYMENT_ID did not complete within expected time." + exit 1 + From 0ca891642c657edad3ebad5afa6651de7120d8f0 Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:52:22 +0100 Subject: [PATCH 08/44] fix: rm format-frontend --- .github/workflows/pull_request.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9c3f991..0ac7591 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -76,19 +76,6 @@ jobs: run: terragrunt hclfmt --terragrunt-check working-directory: infra - format-frontend: - needs: check - runs-on: ubuntu-latest - if: ${{ needs.check.outputs.frontend == 'true' }} - name: Run astro formatting checks - timeout-minutes: 2 - steps: - - uses: actions/checkout@v4 - - name: Run prettier checks - run: | - npm install --prefix frontend - npm run format:check --prefix frontend - build-backend: needs: check runs-on: ubuntu-latest From d5b1df4f67bdbf2e60f6b464aee79b61e017f474 Mon Sep 17 00:00:00 2001 From: Chris Sheehan Date: Sat, 6 Sep 2025 20:58:49 +0100 Subject: [PATCH 09/44] chore: oidc iam codedeploy --- infra/live/global_vars.hcl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/infra/live/global_vars.hcl b/infra/live/global_vars.hcl index 528669e..4baff4a 100644 --- a/infra/live/global_vars.hcl +++ b/infra/live/global_vars.hcl @@ -5,7 +5,8 @@ locals { "iam:*", "lambda:*", "logs:*", - "apigateway:*" + "apigateway:*", + "codedeploy:*" ] } From c96c8155404ad60267d626ed44de47266bb80310 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 10:15:09 +0100 Subject: [PATCH 10/44] fix: use blue green deployment group --- infra/modules/aws/lambda/main.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index 7692219..2a803e6 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -61,6 +61,12 @@ resource "aws_codedeploy_deployment_group" "dg" { app_name = aws_codedeploy_app.app.name deployment_group_name = "${local.lambda_name}-dg" service_role_arn = aws_iam_role.code_deploy_role.arn + + deployment_style { + deployment_type = "BLUE_GREEN" + deployment_option = "WITH_TRAFFIC_CONTROL" + } + deployment_config_name = "CodeDeployDefault.LambdaCanary10Percent5Minutes" auto_rollback_configuration { From f28a557e58087f74aa76b7c14332f209d5ce4415 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 10:27:57 +0100 Subject: [PATCH 11/44] fix: failsafe check in deploy script + fix --- .github/workflows/deploy.yml | 15 ++++++++++++--- justfile | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c9d7e2b..45ae085 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -68,13 +68,22 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} tg_directory: infra/live/${{ inputs.environment }}/aws/api + - name: get api variables + id: get-api-vars + env: + TG_OUTPUTS: ${{ steps.deploy-api.outputs.tg_outputs }} + run: | + echo "lambda_zip_key=$(echo $TG_OUTPUTS | jq -r '.lambda_zip_key.value')" >> $GITHUB_OUTPUT + echo "code_deploy_app_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_app_name.value')" >> $GITHUB_OUTPUT + echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT + - name: check lambda version uses: chrispsheehan/just-aws-oidc-action@0.1.1 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} - LAMBDA_ZIP_KEY: ${{ steps.deploy-api.outputs.lambda_zip_key }} - CODE_DEPLOY_APP_NAME: ${{ steps.deploy-api.outputs.code_deploy_app_name }} - CODE_DEPLOY_GROUP_NAME: ${{ steps.deploy-api.outputs.code_deploy_group_name }} + LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} + CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} + CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-deploy diff --git a/justfile b/justfile index e4141af..99f4b19 100644 --- a/justfile +++ b/justfile @@ -157,6 +157,11 @@ lambda-deploy: --s3-location bucket=$BUCKET_NAME,key=$LAMBDA_ZIP_KEY,bundleType=zip \ --query "deploymentId" --output text) + if [[ -z "$DEPLOYMENT_ID" || "$DEPLOYMENT_ID" == "None" ]]; then + echo "❌ Failed to create deployment — no deployment ID returned." + exit 1 + fi + MAX_ATTEMPTS=40 # ~10 minutes at 15s interval SLEEP_INTERVAL=15 # seconds From c380f59dde4798f8ee11f4d5214a0b76edc4b1ad Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 10:54:11 +0100 Subject: [PATCH 12/44] debug: try passing region to just script --- .github/just/action.yml | 52 ++++++++++++++++++++++++++++++++++++ .github/workflows/deploy.yml | 2 +- justfile | 5 ++-- 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 .github/just/action.yml diff --git a/.github/just/action.yml b/.github/just/action.yml new file mode 100644 index 0000000..584fd1d --- /dev/null +++ b/.github/just/action.yml @@ -0,0 +1,52 @@ +name: "Execute Just command with AWS OIDC" +description: "Sets up Just, configures AWS OIDC authentication and runs just action" + +inputs: + just_version: + description: "Version of Just to install" + required: false + default: "1.0.0" + aws_region: + description: "AWS Region" + default: "eu-west-2" + aws_oidc_role_arn: + description: "AWS iam role arn" + required: true + just_action: + description: "Just command (recipe) to execute" + required: true + +outputs: + just_outputs: + description: "Output from the just script" + value: ${{ steps.capture.outputs.result }} + +runs: + using: "composite" + steps: + - name: Install Just + uses: extractions/setup-just@v2 + with: + just-version: ${{ inputs.just_version }} + + - name: Configure AWS OIDC Authentication + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.aws_oidc_role_arn }} + aws-region: ${{ inputs.aws_region }} + + - name: Run just action and capture output + id: capture + shell: bash + env: + AWS_REGION: ${{ inputs.aws_region }} + AWS_DEFAULT_REGION: ${{ inputs.aws_region }} + run: | + set -euo pipefail + set -o pipefail + + echo "📦 Running just command: ${{ inputs.just_action }}" + + result=$(just ${{ inputs.just_action }} | tail -n 1 | tr -d '\r') + echo "Result: $result" + echo "result=$result" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 45ae085..6de88cb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -78,7 +78,7 @@ jobs: echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT - name: check lambda version - uses: chrispsheehan/just-aws-oidc-action@0.1.1 + uses: ./.github/just env: BUCKET_NAME: ${{ inputs.lambda_bucket }} LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} diff --git a/justfile b/justfile index 99f4b19..3f2e1b3 100644 --- a/justfile +++ b/justfile @@ -151,12 +151,15 @@ backend-build: lambda-deploy: #!/usr/bin/env bash DEPLOYMENT_ID=$(aws deploy create-deployment \ + --region "$AWS_REGION" \ --application-name $CODE_DEPLOY_APP_NAME \ --deployment-group-name $CODE_DEPLOY_GROUP_NAME \ --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes \ --s3-location bucket=$BUCKET_NAME,key=$LAMBDA_ZIP_KEY,bundleType=zip \ --query "deploymentId" --output text) + echo "🚀 Started deployment: $DEPLOYMENT_ID" + if [[ -z "$DEPLOYMENT_ID" || "$DEPLOYMENT_ID" == "None" ]]; then echo "❌ Failed to create deployment — no deployment ID returned." exit 1 @@ -165,8 +168,6 @@ lambda-deploy: MAX_ATTEMPTS=40 # ~10 minutes at 15s interval SLEEP_INTERVAL=15 # seconds - echo "🚀 Started deployment: $DEPLOYMENT_ID" - for ((i=1; i<=MAX_ATTEMPTS; i++)); do STATUS=$(aws deploy get-deployment \ --deployment-id "$DEPLOYMENT_ID" \ From ba7f5d06db82c60dfb1ec53ad9d86b1c7f9c0a02 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 11:08:02 +0100 Subject: [PATCH 13/44] fix: rm defined region from script --- justfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 3f2e1b3..4d7a6f3 100644 --- a/justfile +++ b/justfile @@ -151,9 +151,8 @@ backend-build: lambda-deploy: #!/usr/bin/env bash DEPLOYMENT_ID=$(aws deploy create-deployment \ - --region "$AWS_REGION" \ - --application-name $CODE_DEPLOY_APP_NAME \ - --deployment-group-name $CODE_DEPLOY_GROUP_NAME \ + --application-name "$CODE_DEPLOY_APP_NAME" \ + --deployment-group-name "$CODE_DEPLOY_GROUP_NAME" \ --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes \ --s3-location bucket=$BUCKET_NAME,key=$LAMBDA_ZIP_KEY,bundleType=zip \ --query "deploymentId" --output text) From 80ada7a807a3d5fe33709457b9c873507e04fceb Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 12:01:12 +0100 Subject: [PATCH 14/44] debug: output just action errors --- .github/just/action.yml | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/just/action.yml b/.github/just/action.yml index 584fd1d..41b6fea 100644 --- a/.github/just/action.yml +++ b/.github/just/action.yml @@ -42,11 +42,28 @@ runs: AWS_REGION: ${{ inputs.aws_region }} AWS_DEFAULT_REGION: ${{ inputs.aws_region }} run: | - set -euo pipefail - set -o pipefail + set -uo pipefail # don't use -e; we want to inspect the exit code ourselves echo "📦 Running just command: ${{ inputs.just_action }}" - - result=$(just ${{ inputs.just_action }} | tail -n 1 | tr -d '\r') - echo "Result: $result" - echo "result=$result" >> "$GITHUB_OUTPUT" + + echo "::group::just output" + output="$({ just ${{ inputs.just_action }}; } 2>&1)" + status=$? + echo "$output" + echo "::endgroup::" + + if [[ $status -ne 0 ]]; then + echo "::error::Just command exited with status $status" + { + echo "### ❌ Just command failed" + echo "**Command:** \`just ${{ inputs.just_action }}\`" + echo "**Exit code:** $status" + echo "
Output (last 200 lines)" + printf '%s\n' "$output" | tail -n 200 + echo "
" + } >> "$GITHUB_STEP_SUMMARY" + exit "$status" + fi + + result="$(printf '%s\n' "$output" | awk 'NF{last=$0} END{print last}' | tr -d '\r')" + printf 'result=%s\n' "$result" >> "$GITHUB_OUTPUT" From 751c80ec1832988f6e7c81260e7d2013aa50e73a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 15:10:35 +0100 Subject: [PATCH 15/44] debug: use try catch in just runner --- .github/just/action.yml | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/.github/just/action.yml b/.github/just/action.yml index 41b6fea..b541445 100644 --- a/.github/just/action.yml +++ b/.github/just/action.yml @@ -35,35 +35,24 @@ runs: role-to-assume: ${{ inputs.aws_oidc_role_arn }} aws-region: ${{ inputs.aws_region }} - - name: Run just action and capture output + - name: Run just action (try/catch + capture) id: capture shell: bash env: AWS_REGION: ${{ inputs.aws_region }} AWS_DEFAULT_REGION: ${{ inputs.aws_region }} run: | - set -uo pipefail # don't use -e; we want to inspect the exit code ourselves - - echo "📦 Running just command: ${{ inputs.just_action }}" - - echo "::group::just output" - output="$({ just ${{ inputs.just_action }}; } 2>&1)" - status=$? - echo "$output" - echo "::endgroup::" - - if [[ $status -ne 0 ]]; then - echo "::error::Just command exited with status $status" - { - echo "### ❌ Just command failed" - echo "**Command:** \`just ${{ inputs.just_action }}\`" - echo "**Exit code:** $status" - echo "
Output (last 200 lines)" - printf '%s\n' "$output" | tail -n 200 - echo "
" - } >> "$GITHUB_STEP_SUMMARY" - exit "$status" - fi - - result="$(printf '%s\n' "$output" | awk 'NF{last=$0} END{print last}' | tr -d '\r')" - printf 'result=%s\n' "$result" >> "$GITHUB_OUTPUT" + set -euo pipefail + echo "📦 Running: ${{ inputs.just_action }}" + + if output="$(just ${{ inputs.just_action }} 2>&1)"; then + echo "$output" + result="$(printf '%s\n' "$output" | tail -n 1 | tr -d '\r')" + echo "result=$result" >> "$GITHUB_OUTPUT" + echo "✅ just '${{ inputs.just_action }}' succeeded" + else + code=$? + echo "$output" + echo "::error::just '${{ inputs.just_action }}' failed (exit $code)" + exit "$code" + fi \ No newline at end of file From 201b34cd91605fd8b9f796921abcbb68eeb638ea Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 15:47:21 +0100 Subject: [PATCH 16/44] chore: ger deployment error message --- justfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/justfile b/justfile index 4d7a6f3..5766780 100644 --- a/justfile +++ b/justfile @@ -180,6 +180,10 @@ lambda-deploy: exit 0 elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then echo "❌ Deployment $DEPLOYMENT_ID failed or was stopped." + aws deploy get-deployment \ + --deployment-id "$DEPLOYMENT_ID" \ + --query 'deploymentInfo.{Status:status, ErrorCode:errorInformation.code, ErrorMessage:errorInformation.message}' \ + --output table exit 1 fi From 5a31d62b6130a238a7422316574869b296f69676 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 15:59:57 +0100 Subject: [PATCH 17/44] fix: allow iams for code deploy --- infra/modules/aws/lambda/data.tf | 23 +++++++++++++++++++++++ infra/modules/aws/lambda/main.tf | 6 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/infra/modules/aws/lambda/data.tf b/infra/modules/aws/lambda/data.tf index 4a1c017..533e2d5 100644 --- a/infra/modules/aws/lambda/data.tf +++ b/infra/modules/aws/lambda/data.tf @@ -44,6 +44,29 @@ data "aws_iam_policy_document" "codedeploy_lambda" { ] } + statement { + sid = "ReadArtifactObject" + effect = "Allow" + actions = ["s3:GetObject", "s3:GetObjectVersion"] + resources = [ + "arn:aws:s3:::${data.aws_s3_bucket.lambda_code.bucket}/${local.lambda_code_zip_key}", + "arn:aws:s3:::${data.aws_s3_bucket.lambda_code.bucket}/${var.lambda_version}/*" + ] + } + + # Allow listing the bucket for that prefix (some SDKs call this) + statement { + sid = "ListArtifactPrefix" + effect = "Allow" + actions = ["s3:ListBucket", "s3:GetBucketLocation"] + resources = ["arn:aws:s3:::${data.aws_s3_bucket.lambda_code.bucket}"] + condition { + test = "StringLike" + variable = "s3:prefix" + values = ["${var.lambda_version}/*"] + } + } + statement { sid = "DescribeAlarms" effect = "Allow" diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index 2a803e6..d8f8b35 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -58,9 +58,9 @@ resource "aws_iam_role_policy" "cd_lambda" { } resource "aws_codedeploy_deployment_group" "dg" { - app_name = aws_codedeploy_app.app.name - deployment_group_name = "${local.lambda_name}-dg" - service_role_arn = aws_iam_role.code_deploy_role.arn + app_name = aws_codedeploy_app.app.name + deployment_group_name = "${local.lambda_name}-dg" + service_role_arn = aws_iam_role.code_deploy_role.arn deployment_style { deployment_type = "BLUE_GREEN" From d196b79cdbce09e5069679f8c7b5d9dd6fd6f757 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 16:07:29 +0100 Subject: [PATCH 18/44] chore: use latest just action version --- .github/just/action.yml | 58 --------------------------------- .github/workflows/build.yml | 2 +- .github/workflows/deploy.yml | 4 +-- .github/workflows/get_build.yml | 2 +- 4 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 .github/just/action.yml diff --git a/.github/just/action.yml b/.github/just/action.yml deleted file mode 100644 index b541445..0000000 --- a/.github/just/action.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: "Execute Just command with AWS OIDC" -description: "Sets up Just, configures AWS OIDC authentication and runs just action" - -inputs: - just_version: - description: "Version of Just to install" - required: false - default: "1.0.0" - aws_region: - description: "AWS Region" - default: "eu-west-2" - aws_oidc_role_arn: - description: "AWS iam role arn" - required: true - just_action: - description: "Just command (recipe) to execute" - required: true - -outputs: - just_outputs: - description: "Output from the just script" - value: ${{ steps.capture.outputs.result }} - -runs: - using: "composite" - steps: - - name: Install Just - uses: extractions/setup-just@v2 - with: - just-version: ${{ inputs.just_version }} - - - name: Configure AWS OIDC Authentication - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ inputs.aws_oidc_role_arn }} - aws-region: ${{ inputs.aws_region }} - - - name: Run just action (try/catch + capture) - id: capture - shell: bash - env: - AWS_REGION: ${{ inputs.aws_region }} - AWS_DEFAULT_REGION: ${{ inputs.aws_region }} - run: | - set -euo pipefail - echo "📦 Running: ${{ inputs.just_action }}" - - if output="$(just ${{ inputs.just_action }} 2>&1)"; then - echo "$output" - result="$(printf '%s\n' "$output" | tail -n 1 | tr -d '\r')" - echo "result=$result" >> "$GITHUB_OUTPUT" - echo "✅ just '${{ inputs.just_action }}' succeeded" - else - code=$? - echo "$output" - echo "::error::just '${{ inputs.just_action }}' failed (exit $code)" - exit "$code" - fi \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4c19ff1..ed09e10 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: run: just backend-build - name: Upload Lambda zips - uses: chrispsheehan/just-aws-oidc-action@0.1.1 + uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ needs.infra.outputs.lambda_bucket_name }} with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6de88cb..86f6e67 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -45,7 +45,7 @@ jobs: tg_directory: infra/live/${{ inputs.environment }}/aws/oidc - name: check Lambda version - uses: chrispsheehan/just-aws-oidc-action@0.1.1 + uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} VERSION: ${{ inputs.lambda_version }} @@ -78,7 +78,7 @@ jobs: echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT - name: check lambda version - uses: ./.github/just + uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} diff --git a/.github/workflows/get_build.yml b/.github/workflows/get_build.yml index bb21844..14525be 100644 --- a/.github/workflows/get_build.yml +++ b/.github/workflows/get_build.yml @@ -53,7 +53,7 @@ jobs: echo "bucket_lambda=$(echo $TG_OUTPUTS | jq -r '.bucket_lambda.value')" >> $GITHUB_OUTPUT - name: Check Lambda version exists - uses: chrispsheehan/just-aws-oidc-action@0.1.1 + uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ steps.get_bucket_name.outputs.bucket_lambda }} VERSION: ${{ inputs.version }} From f4a463a95911ecbf34859e732aedbe52e6330483 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 8 Sep 2025 18:19:44 +0100 Subject: [PATCH 19/44] chore: output alias and function name --- .github/workflows/deploy.yml | 4 ++++ infra/modules/aws/lambda/outputs.tf | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 86f6e67..a100e3a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -74,6 +74,8 @@ jobs: TG_OUTPUTS: ${{ steps.deploy-api.outputs.tg_outputs }} run: | echo "lambda_zip_key=$(echo $TG_OUTPUTS | jq -r '.lambda_zip_key.value')" >> $GITHUB_OUTPUT + echo "function_name=$(echo $TG_OUTPUTS | jq -r '.function_name.value')" >> $GITHUB_OUTPUT + echo "alias_name=$(echo $TG_OUTPUTS | jq -r '.alias_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_app_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_app_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT @@ -81,6 +83,8 @@ jobs: uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} + FUNCTION_NAME: ${{ steps.get-api-vars.outputs.function_name }} + ALIAS_NAME: ${{ steps.get-api-vars.outputs.alias_name }} LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} diff --git a/infra/modules/aws/lambda/outputs.tf b/infra/modules/aws/lambda/outputs.tf index 0e153bb..4fe1631 100644 --- a/infra/modules/aws/lambda/outputs.tf +++ b/infra/modules/aws/lambda/outputs.tf @@ -6,6 +6,14 @@ output "arn" { value = aws_lambda_function.lambda.arn } +output "function_name" { + value = aws_lambda_function.lambda.function_name +} + +output "alias_name" { + value = aws_lambda_alias.live.name +} + output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.lambda_cloudwatch_group.name } From 501bf7a14cbf4e0293184f9a57466de9e53192b4 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 09:21:31 +0100 Subject: [PATCH 20/44] chore: rename step --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a100e3a..a5a4adf 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -79,7 +79,7 @@ jobs: echo "code_deploy_app_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_app_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT - - name: check lambda version + - name: deploy lambda uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} From 07dc890a31a37b851e71b5156a464b3e0da6f51f Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 10:26:30 +0100 Subject: [PATCH 21/44] feat: get current alias version --- .github/workflows/deploy.yml | 28 ++++++++++++++++++++++------ justfile | 6 ++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a5a4adf..6e27143 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -79,15 +79,31 @@ jobs: echo "code_deploy_app_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_app_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT - - name: deploy lambda + - name: get lambda version + id: lambda-get-version uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: - BUCKET_NAME: ${{ inputs.lambda_bucket }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.function_name }} ALIAS_NAME: ${{ steps.get-api-vars.outputs.alias_name }} - LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} - CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} - CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} - just_action: lambda-deploy + just_action: lambda-get-version + + - name: read output from script + run: | + echo "Script output: ${{ steps.lambda-get-version.outputs.just_outputs }}" + VERSION="${{ steps.lambda-get-version.outputs.just_outputs }}" + echo "Parsed VERSION=$VERSION" + + # - name: deploy lambda + # uses: chrispsheehan/just-aws-oidc-action@0.1.2 + # env: + # BUCKET_NAME: ${{ inputs.lambda_bucket }} + # FUNCTION_NAME: ${{ steps.get-api-vars.outputs.function_name }} + # ALIAS_NAME: ${{ steps.get-api-vars.outputs.alias_name }} + # LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} + # CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} + # CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} + # with: + # aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} + # just_action: lambda-deploy diff --git a/justfile b/justfile index 5766780..dd6c71c 100644 --- a/justfile +++ b/justfile @@ -148,6 +148,12 @@ backend-build: echo "✅ Done: backend/$app_name.zip" done +lambda-get-version: + #!/usr/bin/env bash + aws lambda get-alias \ + --function-name "$FUNCTION_NAME" --name "$ALIAS_NAME" \ + --query 'FunctionVersion' --output text + lambda-deploy: #!/usr/bin/env bash DEPLOYMENT_ID=$(aws deploy create-deployment \ From 1b57eadea15081dca66eec1ed6f0ecbaa55208c9 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 10:35:09 +0100 Subject: [PATCH 22/44] chore: add outputs to parent module --- .github/workflows/deploy.yml | 4 ++-- infra/modules/aws/api/outputs.tf | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6e27143..532288b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -74,8 +74,8 @@ jobs: TG_OUTPUTS: ${{ steps.deploy-api.outputs.tg_outputs }} run: | echo "lambda_zip_key=$(echo $TG_OUTPUTS | jq -r '.lambda_zip_key.value')" >> $GITHUB_OUTPUT - echo "function_name=$(echo $TG_OUTPUTS | jq -r '.function_name.value')" >> $GITHUB_OUTPUT - echo "alias_name=$(echo $TG_OUTPUTS | jq -r '.alias_name.value')" >> $GITHUB_OUTPUT + echo "lambda_function_name=$(echo $TG_OUTPUTS | jq -r '.lambda_function_name.value')" >> $GITHUB_OUTPUT + echo "lambda_alias_name=$(echo $TG_OUTPUTS | jq -r '.lambda_alias_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_app_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_app_name.value')" >> $GITHUB_OUTPUT echo "code_deploy_group_name=$(echo $TG_OUTPUTS | jq -r '.code_deploy_group_name.value')" >> $GITHUB_OUTPUT diff --git a/infra/modules/aws/api/outputs.tf b/infra/modules/aws/api/outputs.tf index dcd2240..babcf18 100644 --- a/infra/modules/aws/api/outputs.tf +++ b/infra/modules/aws/api/outputs.tf @@ -17,3 +17,15 @@ output "code_deploy_app_name" { output "code_deploy_group_name" { value = module.lambda_api.code_deploy_group_name } + +output "lambda_arn" { + value = module.lambda_api.arn +} + +output "lambda_function_name" { + value = module.lambda_api.function_name +} + +output "lambda_alias_name" { + value = module.lambda_api.alias_name +} From 229cc96b65538bc0ac53a83b14ec984ec923d74c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 10:40:14 +0100 Subject: [PATCH 23/44] fix: env var set --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 532288b..075c8fc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -83,8 +83,8 @@ jobs: id: lambda-get-version uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: - FUNCTION_NAME: ${{ steps.get-api-vars.outputs.function_name }} - ALIAS_NAME: ${{ steps.get-api-vars.outputs.alias_name }} + FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} + ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-get-version From 8ed9c0ad05722a3cccd38ee49f11e94e249590e1 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 11:13:21 +0100 Subject: [PATCH 24/44] feat: lambda-create-version --- .github/workflows/deploy.yml | 13 +++++++++++++ justfile | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 075c8fc..3536a9e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -89,11 +89,24 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-get-version + - name: create lambda version + id: lambda-create-version + uses: chrispsheehan/just-aws-oidc-action@0.1.2 + env: + LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} + FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} + ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} + with: + aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} + just_action: lambda-create-version + - name: read output from script run: | echo "Script output: ${{ steps.lambda-get-version.outputs.just_outputs }}" VERSION="${{ steps.lambda-get-version.outputs.just_outputs }}" + NEW_VERSION="${{ steps.lambda-create-version.outputs.just_outputs }}" echo "Parsed VERSION=$VERSION" + echo "Parsed NEW_VERSION=$NEW_VERSION" # - name: deploy lambda # uses: chrispsheehan/just-aws-oidc-action@0.1.2 diff --git a/justfile b/justfile index dd6c71c..90b7a0f 100644 --- a/justfile +++ b/justfile @@ -154,6 +154,17 @@ lambda-get-version: --function-name "$FUNCTION_NAME" --name "$ALIAS_NAME" \ --query 'FunctionVersion' --output text + +lambda-create-version: + #!/usr/bin/env bash + aws lambda update-function-code \ + --function-name "$FUNCTION_NAME" \ + --s3-bucket "$BUCKET_NAME" \ + --s3-key "$LAMBDA_ZIP_KEY" \ + --publish \ + --query 'Version' --output text + + lambda-deploy: #!/usr/bin/env bash DEPLOYMENT_ID=$(aws deploy create-deployment \ From d49fe0fa7704c15e28b2c2b1da5bdb5d3944981e Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 11:17:31 +0100 Subject: [PATCH 25/44] fix: correct pass in bucket name --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3536a9e..b362475 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -95,11 +95,11 @@ jobs: env: LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} - ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} + BUCKET_NAME: ${{ inputs.lambda_bucket }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-create-version - + - name: read output from script run: | echo "Script output: ${{ steps.lambda-get-version.outputs.just_outputs }}" From baefe4ce5f4b7eac94471898991389d90c56584d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 12:16:48 +0100 Subject: [PATCH 26/44] feat: lambda-upload-bundle --- .github/workflows/deploy.yml | 26 ++++++++++++++++++++++---- appspec.yml | 9 +++++++++ justfile | 9 ++++++++- 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 appspec.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b362475..4a6b9f4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -56,6 +56,9 @@ jobs: api: needs: setup runs-on: ubuntu-latest + env: + APP_SPEC_FILE: appspec.yaml + APP_SPEC_KEY: appspec.zip steps: - uses: actions/checkout@v4 with: @@ -99,7 +102,7 @@ jobs: with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-create-version - + - name: read output from script run: | echo "Script output: ${{ steps.lambda-get-version.outputs.just_outputs }}" @@ -108,13 +111,28 @@ jobs: echo "Parsed VERSION=$VERSION" echo "Parsed NEW_VERSION=$NEW_VERSION" + - name: Prepare AppSpec File + run: | + rm -f ${{ env.APP_SPEC_FILE }} + echo "::notice::Preparing update for ${{ steps.get-api-vars.outputs.lambda_function_name }} from v${{ steps.lambda-get-version.outputs.just_outputs }} to v${{ steps.lambda-create-version.outputs.just_outputs }}" + sed -i 's|{{FUNCTION_NAME}}|${{ steps.get-api-vars.outputs.lambda_function_name }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{FUNCTION_ALIAS}}|${{ steps.get-api-vars.outputs.alias_name }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{CURRENT_VERSION}}|${{ steps.lambda-get-version.outputs.just_outputs }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{NEW_VERSION}}|${{ steps.lambda-create-version.outputs.just_outputs }}|g' ${{ env.APP_SPEC_FILE }} + cat ${{ env.APP_SPEC_FILE }} + + - name: Upload AppSpec File to s3 + uses: chrispsheehan/just-aws-oidc-action@0.1.2 + env: + BUCKET_NAME: ${{ inputs.lambda_bucket }} + with: + aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} + just_action: lambda-upload-bundle + # - name: deploy lambda # uses: chrispsheehan/just-aws-oidc-action@0.1.2 # env: # BUCKET_NAME: ${{ inputs.lambda_bucket }} - # FUNCTION_NAME: ${{ steps.get-api-vars.outputs.function_name }} - # ALIAS_NAME: ${{ steps.get-api-vars.outputs.alias_name }} - # LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} # CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} # CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} # with: diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 0000000..db9a9fc --- /dev/null +++ b/appspec.yml @@ -0,0 +1,9 @@ +version: 0.0 +Resources: + - LambdaFunction: + Type: AWS::Lambda::Function + Properties: + Name: ${FUNCTION_NAME} + Alias: ${FUNCTION_ALIAS} + CurrentVersion: ${CURRENT_VERSION} + TargetVersion: ${NEW_VERSION} \ No newline at end of file diff --git a/justfile b/justfile index 90b7a0f..126dc20 100644 --- a/justfile +++ b/justfile @@ -165,13 +165,20 @@ lambda-create-version: --query 'Version' --output text +lambda-upload-bundle: + #!/usr/bin/env bash + rm -f $APP_SPEC_KEY + zip -q $APP_SPEC_ZIP $APP_SPEC_FILE + aws s3 cp $APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" + + lambda-deploy: #!/usr/bin/env bash DEPLOYMENT_ID=$(aws deploy create-deployment \ --application-name "$CODE_DEPLOY_APP_NAME" \ --deployment-group-name "$CODE_DEPLOY_GROUP_NAME" \ --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes \ - --s3-location bucket=$BUCKET_NAME,key=$LAMBDA_ZIP_KEY,bundleType=zip \ + --s3-location bucket=$BUCKET_NAME,key=$APP_SPEC_KEY,bundleType=zip \ --query "deploymentId" --output text) echo "🚀 Started deployment: $DEPLOYMENT_ID" From 9942b6201ba52ae7dd839fcb1fdd29fd0f3c03f2 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 12:23:25 +0100 Subject: [PATCH 27/44] fix: use defined zip paths --- .github/workflows/deploy.yml | 2 +- justfile | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4a6b9f4..9c291cb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -57,7 +57,7 @@ jobs: needs: setup runs-on: ubuntu-latest env: - APP_SPEC_FILE: appspec.yaml + APP_SPEC_FILE: ${{github.workspace}}/appspec.yaml APP_SPEC_KEY: appspec.zip steps: - uses: actions/checkout@v4 diff --git a/justfile b/justfile index 126dc20..551bb3b 100644 --- a/justfile +++ b/justfile @@ -167,7 +167,9 @@ lambda-create-version: lambda-upload-bundle: #!/usr/bin/env bash - rm -f $APP_SPEC_KEY + APP_SPEC_ZIP="{{justfile_directory()}}/${APP_SPEC_KEY}" + rm -f $APP_SPEC_ZIP + zip -q $APP_SPEC_ZIP $APP_SPEC_FILE aws s3 cp $APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" From 38bfc21aef7e7bfc7f6111a75dd80532c0510013 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 12:27:04 +0100 Subject: [PATCH 28/44] fix: yaml -> yml --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9c291cb..9d7ea70 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -57,7 +57,7 @@ jobs: needs: setup runs-on: ubuntu-latest env: - APP_SPEC_FILE: ${{github.workspace}}/appspec.yaml + APP_SPEC_FILE: ${{github.workspace}}/appspec.yml APP_SPEC_KEY: appspec.zip steps: - uses: actions/checkout@v4 From 0d8b4306c37dd233d3de91e6bcf9b03b6fddd6c3 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 12:35:03 +0100 Subject: [PATCH 29/44] chore: rm -f ${{ env.APP_SPEC_FILE }} --- .github/workflows/deploy.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9d7ea70..1c42215 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -103,17 +103,8 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-create-version - - name: read output from script - run: | - echo "Script output: ${{ steps.lambda-get-version.outputs.just_outputs }}" - VERSION="${{ steps.lambda-get-version.outputs.just_outputs }}" - NEW_VERSION="${{ steps.lambda-create-version.outputs.just_outputs }}" - echo "Parsed VERSION=$VERSION" - echo "Parsed NEW_VERSION=$NEW_VERSION" - - name: Prepare AppSpec File run: | - rm -f ${{ env.APP_SPEC_FILE }} echo "::notice::Preparing update for ${{ steps.get-api-vars.outputs.lambda_function_name }} from v${{ steps.lambda-get-version.outputs.just_outputs }} to v${{ steps.lambda-create-version.outputs.just_outputs }}" sed -i 's|{{FUNCTION_NAME}}|${{ steps.get-api-vars.outputs.lambda_function_name }}|g' ${{ env.APP_SPEC_FILE }} sed -i 's|{{FUNCTION_ALIAS}}|${{ steps.get-api-vars.outputs.alias_name }}|g' ${{ env.APP_SPEC_FILE }} From 04beda3cf602298c2e390baff37d8fc179bc6e0a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 12:40:35 +0100 Subject: [PATCH 30/44] chore: re enable lambda deploy --- .github/workflows/deploy.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1c42215..02967e2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -120,12 +120,12 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-upload-bundle - # - name: deploy lambda - # uses: chrispsheehan/just-aws-oidc-action@0.1.2 - # env: - # BUCKET_NAME: ${{ inputs.lambda_bucket }} - # CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} - # CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} - # with: - # aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} - # just_action: lambda-deploy + - name: deploy lambda + uses: chrispsheehan/just-aws-oidc-action@0.1.2 + env: + BUCKET_NAME: ${{ inputs.lambda_bucket }} + CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} + CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} + with: + aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} + just_action: lambda-deploy From 445c1f67efd2d0125242e97231bd4c2dd3e67897 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 13:23:38 +0100 Subject: [PATCH 31/44] fix: upload appspec to version folder --- .github/workflows/deploy.yml | 4 ++-- infra/modules/aws/lambda/data.tf | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 02967e2..9a68593 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -57,8 +57,8 @@ jobs: needs: setup runs-on: ubuntu-latest env: - APP_SPEC_FILE: ${{github.workspace}}/appspec.yml - APP_SPEC_KEY: appspec.zip + APP_SPEC_FILE: ${{ github.workspace }}/appspec.yml + APP_SPEC_KEY: ${{ inputs.lambda_version }}/appspec.zip steps: - uses: actions/checkout@v4 with: diff --git a/infra/modules/aws/lambda/data.tf b/infra/modules/aws/lambda/data.tf index 533e2d5..dfcb8a7 100644 --- a/infra/modules/aws/lambda/data.tf +++ b/infra/modules/aws/lambda/data.tf @@ -49,7 +49,6 @@ data "aws_iam_policy_document" "codedeploy_lambda" { effect = "Allow" actions = ["s3:GetObject", "s3:GetObjectVersion"] resources = [ - "arn:aws:s3:::${data.aws_s3_bucket.lambda_code.bucket}/${local.lambda_code_zip_key}", "arn:aws:s3:::${data.aws_s3_bucket.lambda_code.bucket}/${var.lambda_version}/*" ] } From 2dbd8a07a98df85e8515c667df1394599cd15984 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 13:52:57 +0100 Subject: [PATCH 32/44] chore: use LOCAL_APP_SPEC_ZIP --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 551bb3b..1b35319 100644 --- a/justfile +++ b/justfile @@ -167,11 +167,11 @@ lambda-create-version: lambda-upload-bundle: #!/usr/bin/env bash - APP_SPEC_ZIP="{{justfile_directory()}}/${APP_SPEC_KEY}" + LOCAL_APP_SPEC_ZIP="{{justfile_directory()}}/appspec.zip" rm -f $APP_SPEC_ZIP - zip -q $APP_SPEC_ZIP $APP_SPEC_FILE - aws s3 cp $APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" + zip -q $LOCAL_APP_SPEC_ZIP $APP_SPEC_FILE + aws s3 cp $LOCAL_APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" lambda-deploy: From bda8957cf0823855fe1a5b4efb7fe923f094f34c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 13:55:11 +0100 Subject: [PATCH 33/44] fix: rm -f $LOCAL_APP_SPEC_ZIP --- justfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/justfile b/justfile index 1b35319..5599abc 100644 --- a/justfile +++ b/justfile @@ -168,8 +168,7 @@ lambda-create-version: lambda-upload-bundle: #!/usr/bin/env bash LOCAL_APP_SPEC_ZIP="{{justfile_directory()}}/appspec.zip" - rm -f $APP_SPEC_ZIP - + rm -f $LOCAL_APP_SPEC_ZIP zip -q $LOCAL_APP_SPEC_ZIP $APP_SPEC_FILE aws s3 cp $LOCAL_APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" From 2aaa75d42d8430fb9a1f70aed4387bdf0deb90af Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 15:26:20 +0100 Subject: [PATCH 34/44] feat: lambda-prepare-appspec --- .github/workflows/deploy.yml | 15 +++++---------- justfile | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9a68593..0571215 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -103,19 +103,14 @@ jobs: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-create-version - - name: Prepare AppSpec File - run: | - echo "::notice::Preparing update for ${{ steps.get-api-vars.outputs.lambda_function_name }} from v${{ steps.lambda-get-version.outputs.just_outputs }} to v${{ steps.lambda-create-version.outputs.just_outputs }}" - sed -i 's|{{FUNCTION_NAME}}|${{ steps.get-api-vars.outputs.lambda_function_name }}|g' ${{ env.APP_SPEC_FILE }} - sed -i 's|{{FUNCTION_ALIAS}}|${{ steps.get-api-vars.outputs.alias_name }}|g' ${{ env.APP_SPEC_FILE }} - sed -i 's|{{CURRENT_VERSION}}|${{ steps.lambda-get-version.outputs.just_outputs }}|g' ${{ env.APP_SPEC_FILE }} - sed -i 's|{{NEW_VERSION}}|${{ steps.lambda-create-version.outputs.just_outputs }}|g' ${{ env.APP_SPEC_FILE }} - cat ${{ env.APP_SPEC_FILE }} - - - name: Upload AppSpec File to s3 + - name: Prepare and upload AppSpec File to s3 uses: chrispsheehan/just-aws-oidc-action@0.1.2 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} + FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} + FUNCTION_ALIAS: ${{ steps.get-api-vars.outputs.alias_name }} + CURRENT_VERSION: ${{ steps.lambda-get-version.outputs.just_outputs }} + NEW_VERSION: ${{ steps.lambda-create-version.outputs.just_outputs }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-upload-bundle diff --git a/justfile b/justfile index 5599abc..c5a0416 100644 --- a/justfile +++ b/justfile @@ -165,11 +165,24 @@ lambda-create-version: --query 'Version' --output text +lambda-prepare-appspec: + #!/usr/bin/env bash + yq eval -i ' + .Resources[0].LambdaFunction.Properties.Name = env(FUNCTION_NAME) | + .Resources[0].LambdaFunction.Properties.Alias = env(FUNCTION_ALIAS) | + .Resources[0].LambdaFunction.Properties.CurrentVersion = env(CURRENT_VERSION) | + .Resources[0].LambdaFunction.Properties.TargetVersion = env(NEW_VERSION) + ' $APP_SPEC_FILE + cat $APP_SPEC_FILE + + lambda-upload-bundle: #!/usr/bin/env bash + just lambda-prepare-appspec + LOCAL_APP_SPEC_ZIP="{{justfile_directory()}}/appspec.zip" rm -f $LOCAL_APP_SPEC_ZIP - zip -q $LOCAL_APP_SPEC_ZIP $APP_SPEC_FILE + zip -q -j $LOCAL_APP_SPEC_ZIP $APP_SPEC_FILE aws s3 cp $LOCAL_APP_SPEC_ZIP "s3://${BUCKET_NAME}/${APP_SPEC_KEY}" From 9147d84fe2b7abb62bf1cd1869e03a2bd340894c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 15:32:01 +0100 Subject: [PATCH 35/44] chore: use standard ALIAS_NAME var name --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0571215..28b091a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -108,7 +108,7 @@ jobs: env: BUCKET_NAME: ${{ inputs.lambda_bucket }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} - FUNCTION_ALIAS: ${{ steps.get-api-vars.outputs.alias_name }} + ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} CURRENT_VERSION: ${{ steps.lambda-get-version.outputs.just_outputs }} NEW_VERSION: ${{ steps.lambda-create-version.outputs.just_outputs }} with: From 74eea60f99fc9bc08bf237b0a2d30ff6318d23c9 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 15:39:25 +0100 Subject: [PATCH 36/44] fix: proper fix --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index c5a0416..cf8a59a 100644 --- a/justfile +++ b/justfile @@ -169,7 +169,7 @@ lambda-prepare-appspec: #!/usr/bin/env bash yq eval -i ' .Resources[0].LambdaFunction.Properties.Name = env(FUNCTION_NAME) | - .Resources[0].LambdaFunction.Properties.Alias = env(FUNCTION_ALIAS) | + .Resources[0].LambdaFunction.Properties.Alias = env(ALIAS_NAME) | .Resources[0].LambdaFunction.Properties.CurrentVersion = env(CURRENT_VERSION) | .Resources[0].LambdaFunction.Properties.TargetVersion = env(NEW_VERSION) ' $APP_SPEC_FILE From e2dbe6343745b310f7fdfa3d6b2a4a065178342b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:02:44 +0100 Subject: [PATCH 37/44] debug: try to pipe output --- .github/just/action.yml | 57 ++++++++++++++++++++++++++++++++++++ .github/workflows/deploy.yml | 2 +- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 .github/just/action.yml diff --git a/.github/just/action.yml b/.github/just/action.yml new file mode 100644 index 0000000..88770d3 --- /dev/null +++ b/.github/just/action.yml @@ -0,0 +1,57 @@ +name: "Execute Just command with AWS OIDC" +description: "Sets up Just, configures AWS OIDC authentication and runs just action" + +inputs: + just_version: + description: "Version of Just to install" + required: false + default: "1.0.0" + aws_region: + description: "AWS Region" + default: "eu-west-2" + aws_oidc_role_arn: + description: "AWS iam role arn" + required: true + just_action: + description: "Just command (recipe) to execute" + required: true + +outputs: + just_outputs: + description: "Output from the just script" + value: ${{ steps.capture.outputs.result }} + +runs: + using: "composite" + steps: + - name: Install Just + uses: extractions/setup-just@v2 + with: + just-version: ${{ inputs.just_version }} + + - name: Configure AWS OIDC Authentication + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ inputs.aws_oidc_role_arn }} + aws-region: ${{ inputs.aws_region }} + + - name: Run just action (try/catch + capture) + id: capture + shell: bash + env: + AWS_REGION: ${{ inputs.aws_region }} + AWS_DEFAULT_REGION: ${{ inputs.aws_region }} + run: | + set +e + set -uo pipefail + + LOG_FILE="$RUNNER_TEMP/just_${{ inputs.just_action }}_$(date +%s).log" + echo "📦 Running: ${{ inputs.just_action }}" + just ${{ inputs.just_action }} 2>&1 | tee "$LOG_FILE" + status=${PIPESTATUS[0]} + + # keep your "last line" output behavior + result="$(tail -n 1 "$LOG_FILE" | tr -d '\r')" + echo "result=$result" >> "$GITHUB_OUTPUT" + + exit "$status" \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 28b091a..c56baad 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -116,7 +116,7 @@ jobs: just_action: lambda-upload-bundle - name: deploy lambda - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: ./.github/just env: BUCKET_NAME: ${{ inputs.lambda_bucket }} CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} From 91927c70bb785b2c6eaa78182d89d23a6175ce53 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:11:19 +0100 Subject: [PATCH 38/44] chore: shorten deploy feedback loop --- infra/modules/aws/lambda/main.tf | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index d8f8b35..fa364ee 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -57,6 +57,20 @@ resource "aws_iam_role_policy" "cd_lambda" { policy = data.aws_iam_policy_document.codedeploy_lambda.json } +resource "aws_codedeploy_deployment_config" "lambda_canary_10_1m" { + # A custom Lambda deployment config that sends 10% traffic for 1 minute, then shifts to 100% (with your DG using it and auto-rollback on failure/alarms). + deployment_config_name = "${local.lambda_name}-canary10-1m" + compute_platform = "Lambda" + + traffic_routing_config { + type = "TimeBasedCanary" + time_based_canary { + percentage = 10 + interval = 1 + } + } +} + resource "aws_codedeploy_deployment_group" "dg" { app_name = aws_codedeploy_app.app.name deployment_group_name = "${local.lambda_name}-dg" @@ -67,7 +81,7 @@ resource "aws_codedeploy_deployment_group" "dg" { deployment_option = "WITH_TRAFFIC_CONTROL" } - deployment_config_name = "CodeDeployDefault.LambdaCanary10Percent5Minutes" + deployment_config_name = aws_codedeploy_deployment_config.lambda_canary_10_1m.id auto_rollback_configuration { enabled = true From 223782302a2677d74b87765ccb048be05fd41baa Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:20:27 +0100 Subject: [PATCH 39/44] debug: test just with output works still --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c56baad..d6de116 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -84,7 +84,7 @@ jobs: - name: get lambda version id: lambda-get-version - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: ./.github/just env: FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} From 3d4ddb13ff29fb9410a8832c40d378094d3ea892 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:21:44 +0100 Subject: [PATCH 40/44] chore: try 50% switch --- infra/modules/aws/lambda/main.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index fa364ee..b0ef1fb 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -57,15 +57,15 @@ resource "aws_iam_role_policy" "cd_lambda" { policy = data.aws_iam_policy_document.codedeploy_lambda.json } -resource "aws_codedeploy_deployment_config" "lambda_canary_10_1m" { - # A custom Lambda deployment config that sends 10% traffic for 1 minute, then shifts to 100% (with your DG using it and auto-rollback on failure/alarms). +resource "aws_codedeploy_deployment_config" "lambda_canary_50_1m" { + # A custom Lambda deployment config that sends 50% traffic for 1 minute, then shifts to 100% (with your DG using it and auto-rollback on failure/alarms). deployment_config_name = "${local.lambda_name}-canary10-1m" compute_platform = "Lambda" traffic_routing_config { type = "TimeBasedCanary" time_based_canary { - percentage = 10 + percentage = 50 interval = 1 } } @@ -81,7 +81,7 @@ resource "aws_codedeploy_deployment_group" "dg" { deployment_option = "WITH_TRAFFIC_CONTROL" } - deployment_config_name = aws_codedeploy_deployment_config.lambda_canary_10_1m.id + deployment_config_name = aws_codedeploy_deployment_config.lambda_canary_50_1m.id auto_rollback_configuration { enabled = true From dd7831fd60b4534da7ffaee27578e613a9163e41 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:42:44 +0100 Subject: [PATCH 41/44] chore: bump to just-aws-oidc-action@0.1.3 --- .github/just/action.yml | 57 --------------------------------- .github/workflows/build.yml | 2 +- .github/workflows/deploy.yml | 10 +++--- .github/workflows/get_build.yml | 2 +- 4 files changed, 7 insertions(+), 64 deletions(-) delete mode 100644 .github/just/action.yml diff --git a/.github/just/action.yml b/.github/just/action.yml deleted file mode 100644 index 88770d3..0000000 --- a/.github/just/action.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: "Execute Just command with AWS OIDC" -description: "Sets up Just, configures AWS OIDC authentication and runs just action" - -inputs: - just_version: - description: "Version of Just to install" - required: false - default: "1.0.0" - aws_region: - description: "AWS Region" - default: "eu-west-2" - aws_oidc_role_arn: - description: "AWS iam role arn" - required: true - just_action: - description: "Just command (recipe) to execute" - required: true - -outputs: - just_outputs: - description: "Output from the just script" - value: ${{ steps.capture.outputs.result }} - -runs: - using: "composite" - steps: - - name: Install Just - uses: extractions/setup-just@v2 - with: - just-version: ${{ inputs.just_version }} - - - name: Configure AWS OIDC Authentication - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ inputs.aws_oidc_role_arn }} - aws-region: ${{ inputs.aws_region }} - - - name: Run just action (try/catch + capture) - id: capture - shell: bash - env: - AWS_REGION: ${{ inputs.aws_region }} - AWS_DEFAULT_REGION: ${{ inputs.aws_region }} - run: | - set +e - set -uo pipefail - - LOG_FILE="$RUNNER_TEMP/just_${{ inputs.just_action }}_$(date +%s).log" - echo "📦 Running: ${{ inputs.just_action }}" - just ${{ inputs.just_action }} 2>&1 | tee "$LOG_FILE" - status=${PIPESTATUS[0]} - - # keep your "last line" output behavior - result="$(tail -n 1 "$LOG_FILE" | tr -d '\r')" - echo "result=$result" >> "$GITHUB_OUTPUT" - - exit "$status" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ed09e10..663a8cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: run: just backend-build - name: Upload Lambda zips - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: BUCKET_NAME: ${{ needs.infra.outputs.lambda_bucket_name }} with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d6de116..6592649 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -45,7 +45,7 @@ jobs: tg_directory: infra/live/${{ inputs.environment }}/aws/oidc - name: check Lambda version - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} VERSION: ${{ inputs.lambda_version }} @@ -84,7 +84,7 @@ jobs: - name: get lambda version id: lambda-get-version - uses: ./.github/just + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} @@ -94,7 +94,7 @@ jobs: - name: create lambda version id: lambda-create-version - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} @@ -104,7 +104,7 @@ jobs: just_action: lambda-create-version - name: Prepare and upload AppSpec File to s3 - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} @@ -116,7 +116,7 @@ jobs: just_action: lambda-upload-bundle - name: deploy lambda - uses: ./.github/just + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: BUCKET_NAME: ${{ inputs.lambda_bucket }} CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} diff --git a/.github/workflows/get_build.yml b/.github/workflows/get_build.yml index 14525be..1480ca2 100644 --- a/.github/workflows/get_build.yml +++ b/.github/workflows/get_build.yml @@ -53,7 +53,7 @@ jobs: echo "bucket_lambda=$(echo $TG_OUTPUTS | jq -r '.bucket_lambda.value')" >> $GITHUB_OUTPUT - name: Check Lambda version exists - uses: chrispsheehan/just-aws-oidc-action@0.1.2 + uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: BUCKET_NAME: ${{ steps.get_bucket_name.outputs.bucket_lambda }} VERSION: ${{ inputs.version }} From f25a8870807a904e6c34ce84fadbe935092c1b2b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:44:02 +0100 Subject: [PATCH 42/44] chore: set BUCKET_NAME: ${{ inputs.lambda_bucket }} at top --- .github/workflows/deploy.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6592649..2715ceb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,6 +30,7 @@ permissions: env: TF_VAR_lambda_version: ${{ inputs.lambda_version }} AWS_OIDC_ROLE_ARN: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/aws-serverless-github-deploy-${{ inputs.environment }}-github-oidc-role + BUCKET_NAME: ${{ inputs.lambda_bucket }} jobs: setup: @@ -47,7 +48,6 @@ jobs: - name: check Lambda version uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: - BUCKET_NAME: ${{ inputs.lambda_bucket }} VERSION: ${{ inputs.lambda_version }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} @@ -98,7 +98,6 @@ jobs: env: LAMBDA_ZIP_KEY: ${{ steps.get-api-vars.outputs.lambda_zip_key }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} - BUCKET_NAME: ${{ inputs.lambda_bucket }} with: aws_oidc_role_arn: ${{ env.AWS_OIDC_ROLE_ARN }} just_action: lambda-create-version @@ -106,7 +105,6 @@ jobs: - name: Prepare and upload AppSpec File to s3 uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: - BUCKET_NAME: ${{ inputs.lambda_bucket }} FUNCTION_NAME: ${{ steps.get-api-vars.outputs.lambda_function_name }} ALIAS_NAME: ${{ steps.get-api-vars.outputs.lambda_alias_name }} CURRENT_VERSION: ${{ steps.lambda-get-version.outputs.just_outputs }} @@ -118,7 +116,6 @@ jobs: - name: deploy lambda uses: chrispsheehan/just-aws-oidc-action@0.1.3 env: - BUCKET_NAME: ${{ inputs.lambda_bucket }} CODE_DEPLOY_APP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_app_name }} CODE_DEPLOY_GROUP_NAME: ${{ steps.get-api-vars.outputs.code_deploy_group_name }} with: From 8f4ffcda80432f46100f9203aa1d7e4c2af238e1 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:49:43 +0100 Subject: [PATCH 43/44] chore: rename deploy config block --- infra/modules/aws/lambda/main.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/modules/aws/lambda/main.tf b/infra/modules/aws/lambda/main.tf index b0ef1fb..eb9434a 100644 --- a/infra/modules/aws/lambda/main.tf +++ b/infra/modules/aws/lambda/main.tf @@ -57,9 +57,9 @@ resource "aws_iam_role_policy" "cd_lambda" { policy = data.aws_iam_policy_document.codedeploy_lambda.json } -resource "aws_codedeploy_deployment_config" "lambda_canary_50_1m" { +resource "aws_codedeploy_deployment_config" "lambda_deployment_config" { # A custom Lambda deployment config that sends 50% traffic for 1 minute, then shifts to 100% (with your DG using it and auto-rollback on failure/alarms). - deployment_config_name = "${local.lambda_name}-canary10-1m" + deployment_config_name = "${local.lambda_name}-deployment-config" compute_platform = "Lambda" traffic_routing_config { @@ -81,7 +81,7 @@ resource "aws_codedeploy_deployment_group" "dg" { deployment_option = "WITH_TRAFFIC_CONTROL" } - deployment_config_name = aws_codedeploy_deployment_config.lambda_canary_50_1m.id + deployment_config_name = aws_codedeploy_deployment_config.lambda_deployment_config.id auto_rollback_configuration { enabled = true From 1c1ce415c2276099db657df7b6f672929567a419 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 9 Sep 2025 16:56:34 +0100 Subject: [PATCH 44/44] fix: rm --deployment-config-name from cli deploy --- justfile | 1 - 1 file changed, 1 deletion(-) diff --git a/justfile b/justfile index cf8a59a..70e79c0 100644 --- a/justfile +++ b/justfile @@ -191,7 +191,6 @@ lambda-deploy: DEPLOYMENT_ID=$(aws deploy create-deployment \ --application-name "$CODE_DEPLOY_APP_NAME" \ --deployment-group-name "$CODE_DEPLOY_GROUP_NAME" \ - --deployment-config-name CodeDeployDefault.LambdaCanary10Percent5Minutes \ --s3-location bucket=$BUCKET_NAME,key=$APP_SPEC_KEY,bundleType=zip \ --query "deploymentId" --output text)