Skip to content

[PRM-425] When deploying new images, depend on new image promotion prior to terraform plan #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 24, 2025

Conversation

chrisbloe-nhse
Copy link
Contributor

No description provided.

Comment on lines 184 to 283
name: Deploy Infrastructure (with new image)
needs: [ promote-images-to-prod, plan-infra-with-images ]
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./stacks/${{ inputs.terraform_stack }}/terraform
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: nhsconnect/prm-gp2gp-data-pipeline-infra

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ inputs.is_deployment && secrets.AWS_ASSUME_ROLE || secrets.AWS_ASSUME_ROLE_READ_ONLY }}
role-to-assume: ${{ inputs.is_deployment && secrets.AWS_ASSUME_ROLE || secrets.AWS_ASSUME_ROLE_READ_ONLY }}
role-skip-session-tagging: true
mask-aws-account-id: true

- name: Build Lambdas
if: inputs.build_lambda
run: |
cd $GITHUB_WORKSPACE
chmod +x ./tasks_github_actions.sh
./tasks_github_actions.sh build-lambdas

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest

- name: Terraform Format
id: fmt
run: terraform fmt -check

- name: Terraform Init
id: init
run: |
terraform init -no-color -backend-config="key=data-pipeline/${{ inputs.terraform_stack }}/terraform.tfstate" \
-backend-config="bucket=${{ secrets.AWS_STATE_BUCKET }}" \
-backend-config="dynamodb_table=${{ secrets.AWS_STATE_LOCK_TABLE }}"
shell: bash

- name: Terraform Validate
id: validate
run: terraform validate -no-color

- name: Setup Terraform variables
id: vars
run: |-
cat > pipeline.auto.tfvars <<EOF
environment = "${{ vars.AWS_ENVIRONMENT }}"
EOF

- name: Setup Terraform variables for Image Tag
id: vars-image-tag
if: inputs.image_tag
run: |-
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
cat > pipeline.auto.tfvars <<EOF
${{ inputs.image_tag }}_image_tag = $IMAGE_TAG
environment = "${{ vars.AWS_ENVIRONMENT }}"
EOF

- name: Setup Terraform variables for Build Lambda
id: update-lambda-build-references
if: inputs.build_lambda
run: |-
image_key="${{ inputs.image_tag }}"
aws_env="${{ vars.AWS_ENVIRONMENT }}"
cat > pipeline.auto.tfvars <<EOF
environment = "$aws_env"
log_alerts_pipeline_error_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/log-alerts-pipeline-error.zip"
log_alerts_technical_failures_above_threshold_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/log-alerts-technical-failures-above-threshold.zip"
gp2gp_dashboard_alert_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/gp2gp-dashboard-alert.zip"
email_report_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/email-report.zip"
validate_metrics_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/validate-metrics.zip"
degrades_dashboards_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/degrades-dashboards.zip"
store_asid_lookup_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/store-asid-lookup.zip"
EOF
if [[ -n "$image_key" ]]; then
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
image_tag=$IMAGE_TAG
echo "${image_key}_image_tag = $image_tag" >> pipeline.auto.tfvars
cat pipeline.auto.tfvars
fi

- name: Terraform Plan
id: plan
run: |
terraform plan -no-color -input=false -var-file="../vars/${{ vars.AWS_ENVIRONMENT }}.tfvars" -out "${{ vars.AWS_ENVIRONMENT }}.tfplan"
terraform show -no-color ${{ vars.AWS_ENVIRONMENT }}.tfplan > ${{ vars.AWS_ENVIRONMENT }}.tfplan.txt
echo "summary=$(grep -E 'Plan: [0-9]+ to add, [0-9]+ to change, [0-9]+ to destroy\.|No changes\. Your infrastructure matches the configuration\.' ${{ vars.AWS_ENVIRONMENT }}.tfplan.txt | sed 's/.*No changes\. Your infrastructure matches the configuration/Plan: no changes/g' | sed 's/.*Plan: //g' | sed 's/\..*//g')" >> $GITHUB_OUTPUT
shell: bash

- name: Terraform Apply
run: terraform apply -auto-approve -input=false ${{ vars.AWS_ENVIRONMENT }}.tfplan
run: terraform apply -auto-approve -input=false ${{ vars.AWS_ENVIRONMENT }}.tfplan

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 4 days ago

To address the issue, we will add a permissions block at the root of the workflow file. This block will define the minimal permissions required for the workflow to function correctly. Based on the tasks performed in the workflow (e.g., configuring AWS credentials, interacting with ECR, and running Terraform commands), the contents: read permission is sufficient. If additional permissions are required for specific jobs, they can be defined at the job level.


Suggested changeset 1
.github/workflows/base-deploy-to-production.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/base-deploy-to-production.yml b/.github/workflows/base-deploy-to-production.yml
--- a/.github/workflows/base-deploy-to-production.yml
+++ b/.github/workflows/base-deploy-to-production.yml
@@ -2,2 +2,5 @@
 
+permissions:
+  contents: read
+
 on:
EOF
@@ -2,2 +2,5 @@

permissions:
contents: read

on:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines 139 to 147
- name: Setup Terraform variables for Image Tag
id: vars-image-tag
if: inputs.image_tag
run: |-
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
cat > pipeline.auto.tfvars <<EOF
${{ inputs.image_tag }}_image_tag = $IMAGE_TAG
environment = "${{ vars.AWS_ENVIRONMENT }}"
EOF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed if no image?

Comment on lines 165 to 170
if [[ -n "$image_key" ]]; then
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
image_tag=$IMAGE_TAG
echo "${image_key}_image_tag = $image_tag" >> pipeline.auto.tfvars
cat pipeline.auto.tfvars
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed if no image?

Comment on lines 82 to 183
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./stacks/${{ inputs.terraform_stack }}/terraform
run:
working-directory: ./stacks/${{ inputs.terraform_stack }}/terraform
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: nhsconnect/prm-gp2gp-data-pipeline-infra

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ inputs.is_deployment && secrets.AWS_ASSUME_ROLE || secrets.AWS_ASSUME_ROLE_READ_ONLY }}
role-skip-session-tagging: true
mask-aws-account-id: true

- name: Build Lambdas
if: inputs.build_lambda
run: |
cd $GITHUB_WORKSPACE
chmod +x ./tasks_github_actions.sh
./tasks_github_actions.sh build-lambdas

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest

- name: Terraform Format
id: fmt
run: terraform fmt -check

- name: Terraform Init
id: init
run: |
terraform init -no-color -backend-config="key=data-pipeline/${{ inputs.terraform_stack }}/terraform.tfstate" \
-backend-config="bucket=${{ secrets.AWS_STATE_BUCKET }}" \
-backend-config="dynamodb_table=${{ secrets.AWS_STATE_LOCK_TABLE }}"
shell: bash

- name: Terraform Validate
id: validate
run: terraform validate -no-color

- name: Setup Terraform variables
id: vars
run: |-
cat > pipeline.auto.tfvars <<EOF
environment = "${{ vars.AWS_ENVIRONMENT }}"
EOF

- name: Setup Terraform variables for Image Tag
id: vars-image-tag
if: inputs.image_tag
run: |-
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
cat > pipeline.auto.tfvars <<EOF
${{ inputs.image_tag }}_image_tag = $IMAGE_TAG
environment = "${{ vars.AWS_ENVIRONMENT }}"
EOF

- name: Setup Terraform variables for Build Lambda
id: update-lambda-build-references
if: inputs.build_lambda
run: |-
image_key="${{ inputs.image_tag }}"
aws_env="${{ vars.AWS_ENVIRONMENT }}"
cat > pipeline.auto.tfvars <<EOF
environment = "$aws_env"
log_alerts_pipeline_error_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/log-alerts-pipeline-error.zip"
log_alerts_technical_failures_above_threshold_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/log-alerts-technical-failures-above-threshold.zip"
gp2gp_dashboard_alert_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/gp2gp-dashboard-alert.zip"
email_report_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/email-report.zip"
validate_metrics_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/validate-metrics.zip"
degrades_dashboards_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/degrades-dashboards.zip"
store_asid_lookup_lambda_zip = "$GITHUB_WORKSPACE/lambda/build/store-asid-lookup.zip"
EOF
if [[ -n "$image_key" ]]; then
IMAGE_TAG=$(aws ecr describe-images --repository-name ${{ secrets.ECR_REPOSITORY_NAME }}${{ inputs.terraform_stack }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]')
image_tag=$IMAGE_TAG
echo "${image_key}_image_tag = $image_tag" >> pipeline.auto.tfvars
cat pipeline.auto.tfvars
fi

- name: Terraform Plan
id: plan
run: |
terraform plan -no-color -input=false -var-file="../vars/${{ vars.AWS_ENVIRONMENT }}.tfvars" -out "${{ vars.AWS_ENVIRONMENT }}.tfplan"
terraform show -no-color ${{ vars.AWS_ENVIRONMENT }}.tfplan > ${{ vars.AWS_ENVIRONMENT }}.tfplan.txt
echo "summary=$(grep -E 'Plan: [0-9]+ to add, [0-9]+ to change, [0-9]+ to destroy\.|No changes\. Your infrastructure matches the configuration\.' ${{ vars.AWS_ENVIRONMENT }}.tfplan.txt | sed 's/.*No changes\. Your infrastructure matches the configuration/Plan: no changes/g' | sed 's/.*Plan: //g' | sed 's/\..*//g')" >> $GITHUB_OUTPUT
shell: bash

- name: Terraform Apply
run: terraform apply -auto-approve -input=false ${{ vars.AWS_ENVIRONMENT }}.tfplan

deploy-infra-with-images:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 4 days ago

To fix the issue, we will add a permissions block at the root of the workflow file. This block will define the minimal permissions required for the workflow to function correctly. Based on the provided workflow, it appears that the workflow primarily interacts with AWS services and does not require write access to the repository contents. Therefore, we will set contents: read as the default permission. If specific jobs require additional permissions, they can override the root-level permissions with their own permissions block.


Suggested changeset 1
.github/workflows/base-deploy-to-production.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/base-deploy-to-production.yml b/.github/workflows/base-deploy-to-production.yml
--- a/.github/workflows/base-deploy-to-production.yml
+++ b/.github/workflows/base-deploy-to-production.yml
@@ -2,2 +2,5 @@
 
+permissions:
+  contents: read
+
 on:
EOF
@@ -2,2 +2,5 @@

permissions:
contents: read

on:
Copilot is powered by AI and may make mistakes. Always verify output.
@chrisbloe-nhse chrisbloe-nhse merged commit d2cb012 into main Jul 24, 2025
4 checks passed
@chrisbloe-nhse chrisbloe-nhse deleted the PRM-425-3 branch July 24, 2025 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants