diff --git a/.github/workflows/base-deploy.yml b/.github/workflows/base-deploy.yml index 4cb767c10..86a30b8f7 100644 --- a/.github/workflows/base-deploy.yml +++ b/.github/workflows/base-deploy.yml @@ -32,6 +32,8 @@ jobs: terraform_version: ${{ steps.variables.outputs.terraform_version }} ref: ${{ steps.variables.outputs.ref }} environment: ${{ steps.variables.outputs.environment }} + tag: ${{ steps.tag.outputs.name }} + promoted_environment: ${{ steps.promoted_env.outputs.promoted_environment }} steps: - name: "Checkout ref" uses: actions/checkout@v5 @@ -74,6 +76,74 @@ jobs: echo "ref=$REF" echo "environment=$ENVIRONMENT" + - name: "Resolve the dev-* tag for this commit" + id: tag + run: | + git fetch --tags --force + SHA="${{ github.event.workflow_run.head_sha }}" + TAG=$(git tag --points-at "$SHA" | grep '^dev-' | head -n1 || true) + if [ -z "$TAG" ]; then + echo "No dev-* tag found on $SHA" >&2 + exit 1 + fi + echo "name=$TAG" >> $GITHUB_OUTPUT + echo "Resolved tag: $TAG" + + - name: "Resolve promoted environment" + id: promoted_env + run: | + ENV="${{ steps.variables.outputs.environment }}" + if [[ "$ENV" == "preprod" ]]; then + echo "promoted_environment=test" >> $GITHUB_OUTPUT + elif [[ "$ENV" == "prod" ]]; then + echo "promoted_environment=preprod" >> $GITHUB_OUTPUT + else + echo "promoted_environment=$ENV" >> $GITHUB_OUTPUT + fi + + download-lambda-artifact: + name: "Fetch the lambda artifact from previous stage" + runs-on: ubuntu-latest + needs: [metadata] + timeout-minutes: 45 + permissions: + id-token: write + contents: write + environment: ${{ needs.metadata.outputs.promoted_environment }} + steps: + - name: "Checkout repository at ref" + uses: actions/checkout@v5 + with: + ref: ${{ needs.metadata.outputs.ref }} + fetch-depth: 0 + + - name: "Configure AWS Credentials" + uses: aws-actions/configure-aws-credentials@v5 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/service-roles/github-actions-api-deployment-role + aws-region: eu-west-2 + + - name: "Extract S3 bucket name from Terraform output" + id: tf_output + run: | + BUCKET=$(terraform output -raw lambda_artifact_bucket) + echo "bucket_name=$BUCKET" >> $GITHUB_OUTPUT + working-directory: ./infrastructure/stacks/api-layer + + - name: "Download lambda artifact from S3" + run: | + aws s3 cp \ + s3://${{ steps.tf_output.outputs.bucket_name }}/artifacts/${{ needs.metadata.outputs.tag }}/lambda.zip \ + ./build/lambda.zip \ + --region eu-west-2 + + - name: "Upload lambda artifact for the current workflow" + uses: actions/upload-artifact@v4 + with: + name: lambda-${{ needs.metadata.outputs.tag }} + path: ./build/lambda.zip + + deploy: name: "Deploy to ${{ needs.metadata.outputs.environment }}" runs-on: ubuntu-latest @@ -95,36 +165,10 @@ jobs: with: terraform_version: ${{ needs.metadata.outputs.terraform_version }} - - name: "Install Poetry" - run: | - curl -sSL https://install.python-poetry.org | python3 - - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: "Set up Python" - uses: actions/setup-python@v6 - with: - python-version: "3.13" - cache: 'poetry' - - - name: "Install dependencies" - run: poetry install - - - name: "Build lambda artefact" - shell: bash - run: | - make dependencies install-python - make build - - - name: "Upload lambda artefact" - uses: actions/upload-artifact@v4 - with: - name: lambda - path: dist/lambda.zip - - - name: "Download Built Lambdas" + - name: "Download Lambda Artifact" uses: actions/download-artifact@v5 with: - name: lambda + name: lambda-${{ needs.metadata.outputs.tag }} path: ./build - name: "Configure AWS Credentials" @@ -153,6 +197,19 @@ jobs: echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=api-layer tf-command=apply" make terraform env=$ENVIRONMENT stack=api-layer tf-command=apply workspace=$WORKSPACE + - name: "Extract S3 bucket name from Terraform output" + id: tf_output + run: | + BUCKET=$(terraform output -raw lambda_artifact_bucket) + echo "bucket_name=$BUCKET" >> $GITHUB_OUTPUT + working-directory: ./infrastructure/stacks/api-layer + + - name: "Upload lambda artifact to S3" + run: | + aws s3 cp ./build/lambda.zip \ + s3://${{ steps.tf_output.outputs.bucket_name }}/artifacts/${{ needs.metadata.outputs.tag }}/lambda.zip \ + --region eu-west-2 + - name: "Validate Feature Toggles" env: ENV: ${{ needs.metadata.outputs.environment }} diff --git a/.github/workflows/cicd-2-publish.yaml b/.github/workflows/cicd-2-publish.yaml index a89d3298f..b35f7c76b 100644 --- a/.github/workflows/cicd-2-publish.yaml +++ b/.github/workflows/cicd-2-publish.yaml @@ -81,16 +81,16 @@ jobs: make dependencies install-python make build - - name: "Upload lambda artefact" + - name: "Upload lambda artefact for cross-workflow use" uses: actions/upload-artifact@v4 with: - name: lambda + name: lambda-${{ needs.metadata.outputs.version }} path: dist/lambda.zip - name: "Download Built Lambdas" uses: actions/download-artifact@v5 with: - name: lambda + name: lambda-${{ needs.metadata.outputs.version }} path: ./build - name: "Configure AWS Credentials" diff --git a/.github/workflows/cicd-3-test-deploy.yaml b/.github/workflows/cicd-3-test-deploy.yaml index 5ab2f1f26..ef0458353 100644 --- a/.github/workflows/cicd-3-test-deploy.yaml +++ b/.github/workflows/cicd-3-test-deploy.yaml @@ -67,21 +67,19 @@ jobs: with: terraform_version: ${{ needs.metadata.outputs.terraform_version }} - - name: "Set up Python" - uses: actions/setup-python@v6 - with: - python-version: "3.13" - - name: "Configure AWS Credentials" uses: aws-actions/configure-aws-credentials@v5 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/service-roles/github-actions-api-deployment-role aws-region: eu-west-2 - - name: "Build lambda artefact (rebuild in TEST)" - run: | - make dependencies install-python - make build + - name: "Download lambda artefact from dev workflow" + uses: actions/download-artifact@v5 + with: + name: lambda-${{ needs.metadata.outputs.tag }} + path: ./build + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} - name: "Terraform Apply (TEST)" env: @@ -101,6 +99,19 @@ jobs: make terraform env=$ENVIRONMENT stack=api-layer tf-command=apply workspace=$WORKSPACE working-directory: ./infrastructure + - name: "Extract S3 bucket name from Terraform output" + id: tf_output + run: | + BUCKET=$(terraform output -raw lambda_artifact_bucket) + echo "bucket_name=$BUCKET" >> $GITHUB_OUTPUT + working-directory: ./infrastructure/stacks/api-layer + + - name: "Upload lambda artifact to S3" + run: | + aws s3 cp ./build/lambda.zip \ + s3://${{ steps.tf_output.outputs.bucket_name }}/artifacts/${{ needs.metadata.outputs.tag }}/lambda.zip \ + --region eu-west-2 + regression-tests: name: "Regression Tests" needs: deploy diff --git a/infrastructure/stacks/api-layer/s3_buckets.tf b/infrastructure/stacks/api-layer/s3_buckets.tf index a2dc4af53..1a94f7284 100644 --- a/infrastructure/stacks/api-layer/s3_buckets.tf +++ b/infrastructure/stacks/api-layer/s3_buckets.tf @@ -25,3 +25,16 @@ module "s3_firehose_backup_bucket" { stack_name = local.stack_name workspace = terraform.workspace } + +module "s3_lambda_artifact_bucket" { + source = "../../modules/s3" + bucket_name = "eli-artifacts" + environment = var.environment + project_name = var.project_name + stack_name = local.stack_name + workspace = terraform.workspace +} + +output "lambda_artifact_bucket" { + value = module.s3_lambda_artifact_bucket.storage_bucket_name +} diff --git a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf index ead66d5ff..1fb835a26 100644 --- a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf +++ b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf @@ -198,7 +198,11 @@ resource "aws_iam_policy" "s3_management" { "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-splunk", "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-splunk/*", "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-splunk-access-logs", - "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-splunk-access-logs/*" + "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-splunk-access-logs/*", + "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-artifacts", + "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-artifacts/*", + "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-artifacts-access-logs", + "arn:aws:s3:::*eligibility-signposting-api-${var.environment}-eli-artifacts-access-logs/*", ] } ]