dev | suspension-service | Terraform Apply? = true #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Destroy end-of-transfer-service infrastructure | |
| run-name: "${{ inputs.environment }} | ${{ inputs.stack }} | Terraform Apply? = ${{ inputs.is_deployment }}" | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| default: "dev" | |
| description: "Environment" | |
| required: true | |
| type: choice | |
| options: | |
| - dev | |
| - pre-prod | |
| - prod | |
| stack: | |
| description: "Stack" | |
| required: true | |
| type: choice | |
| options: | |
| - suspension-service | |
| is_deployment: | |
| default: false | |
| type: boolean | |
| description: "Terraform Apply?" | |
| workflow_call: | |
| inputs: | |
| environment: | |
| default: dev | |
| description: "Environment to deploy to" | |
| type: string | |
| stack: | |
| description: "Stack to deploy - stack folder name" | |
| type: string | |
| backend_key_alias: | |
| description: "Alias for the stack - i.e. deductions is referred to as deductions-infra" | |
| type: string | |
| required: false | |
| ecr_alias: | |
| description: "ECR Repository Alias" | |
| type: string | |
| required: false | |
| is_deployment: | |
| default: false | |
| type: boolean | |
| description: "Terraform Apply?" | |
| ci_account: | |
| default: false | |
| description: "Are we deploying to the CI account?" | |
| type: boolean | |
| lambdas_to_build: | |
| default: false | |
| description: "Do we need to build any lambdas before deploying?" | |
| type: boolean | |
| permissions: | |
| pull-requests: write | |
| id-token: write # This is required for requesting the JWT | |
| contents: read # This is required for actions/checkout | |
| jobs: | |
| destroy_stack: | |
| environment: ${{ inputs.environment}} | |
| env: | |
| GITHUB_ENV: ${{ inputs.environment }} | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: ./stacks/${{ inputs.stack }}/terraform | |
| steps: | |
| - name: Check out Repo | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: NHSDigital/orphaned-record-continuity-infrastructure | |
| fetch-depth: 0 | |
| ref: PRM-726 | |
| - name: Configure AWS Credentials (ReadWrite) | |
| uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 | |
| id: creds | |
| with: | |
| role-to-assume: ${{ secrets.IAM_ROLE }} | |
| aws-region: ${{ vars.AWS_REGION }} | |
| mask-aws-account-id: true | |
| role-skip-session-tagging: true | |
| - name: Setup Terraform variables | |
| id: vars | |
| env: | |
| ECR_ALIAS: ${{ inputs.ecr_alias }} | |
| IMAGE_TAG: 51-4e60390b | |
| run: | | |
| # Only add task_image_tag if stack uses an ECR image | |
| if [ -n "$ECR_ALIAS" ] && [ -n "$IMAGE_TAG" ]; then | |
| echo "task_image_tag = \"${IMAGE_TAG}\"" >> pipeline.auto.tfvars | |
| fi | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: latest | |
| # - name: Terraform Format | |
| # id: fmt | |
| # run: | | |
| # terraform fmt | |
| - name: Terraform Init | |
| id: init | |
| env: | |
| KEY: end-of-transfer-service-${{ inputs.environment }} | |
| run: | | |
| echo "Using backend key: $KEY/terraform.tfstate" | |
| terraform init -no-color \ | |
| -backend-config="key=$KEY/terraform.tfstate" \ | |
| -backend-config="bucket=${{ secrets.TF_BACKEND_BUCKET }}" \ | |
| -backend-config="dynamodb_table=${{ secrets.TF_BACKEND_TABLE }}" | |
| shell: bash | |
| - name: Terraform Validate | |
| id: validate | |
| run: terraform validate -no-color | |
| - name: Terraform Plan | |
| id: plan | |
| run: | | |
| terraform plan -var task_image_tag=$IMAGE_TAG -var-file="configs/end-of-transfer-service/end-of-transfer-service.tfvars" -var-file="configs/end-of-transfer-service/${{ vars.AWS_ENVIRONMENT }}.tfvars" -out="${{ vars.AWS_ENVIRONMENT }}.tfplan" -destroy | |
| 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: Truncate Plan Output | |
| id: plan-truncated | |
| if: success() || failure() | |
| env: | |
| LENGTH: 64512 | |
| run: | | |
| PLAN_FULL=$(grep -v 'Refreshing state...' <<'EOF' | |
| ${{ steps.plan.outputs.stdout }} | |
| ${{ steps.plan.outputs.stderr }} | |
| EOF | |
| ) | |
| # Optionally redact sensitive strings in the PLAN_FULL variable | |
| PLAN_FULL=$(echo "$PLAN_FULL" | sed -E 's#arn:aws:iam::[0-9]{12}:role/[a-zA-Z0-9_-]+#[REDACTED_IAM_ROLE_ARN]#g') | |
| PLAN_FULL=$(echo "$PLAN_FULL" | sed -E 's/[0-9]{12}/[REDACTED_AWS_ACCOUNT_ID]/g') | |
| PLAN_FULL=$(echo "$PLAN_FULL" | sed -E 's#https://[a-zA-Z0-9.-]+\.lambda\.amazonaws\.com/[a-zA-Z0-9/._-]+#[REDACTED_LAMBDA_URL]#g') | |
| PLAN_FULL=$(echo "$PLAN_FULL" | sed -E 's#https://[a-zA-Z0-9.-]+\.execute-api\.[a-zA-Z0-9.-]+\.amazonaws\.com/[a-zA-Z0-9/._-]*#[REDACTED_API_GATEWAY_URL]#g') | |
| PLAN_FULL=$(echo "$PLAN_FULL" | sed -E '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/s/.*/[REDACTED_PEM_CERT]/') | |
| echo "PLAN<<EOF" >> $GITHUB_ENV | |
| echo "${PLAN_FULL::$LENGTH}" >> $GITHUB_ENV | |
| [ ${#PLAN_FULL} -gt $LENGTH ] && echo "(truncated - see workflow logs for full output)" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| shell: bash | |
| - name: Add PR comment | |
| uses: actions/github-script@v8 | |
| if: github.event_name == 'pull_request' && (success() || failure()) | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| // 1. Retrieve existing bot comments for the PR | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }) | |
| const botComment = comments.find(comment => { | |
| return comment.user.type === 'Bot' && comment.body.includes('Report for environment: ndr-dev') | |
| }) | |
| // 2. Prepare format of the comment | |
| const output = `### Report for ${{ inputs.stack }} | |
| #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` | |
| <details><summary>Initialization Output</summary> | |
| \`\`\`\n | |
| ${{ steps.init.outputs.stdout }} | |
| \`\`\` | |
| </details> | |
| #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` | |
| <details><summary>Validation Output</summary> | |
| \`\`\`\n | |
| ${{ steps.validate.outputs.stdout }} | |
| \`\`\` | |
| </details> | |
| #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` | |
| <details><summary>Show Plan (${{ steps.plan.outputs.summary }})</summary> | |
| \`\`\`\n | |
| ${{ env.PLAN }} | |
| \`\`\` | |
| </details>`; | |
| // 3. If we have a comment, update it, otherwise create a new one | |
| if (botComment) { | |
| github.rest.issues.deleteComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: output | |
| }) | |
| } | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: output | |
| }) | |
| - name: Terraform Apply | |
| if: inputs.is_deployment | |
| run: terraform apply -auto-approve -input=false ${{ vars.AWS_ENVIRONMENT }}.tfplan |