[Cloudformation] Deploying Cloudformation Change Sets without InvalidChangeSetStatus Error
The Error I Hit
I got this error during a CloudFormation deployment via GitHub Actions:
1An error occurred (InvalidChangeSetStatus) when calling the ExecuteChangeSet operation:2ChangeSet [...] cannot be executed in its current status of [CREATE_IN_PROGRESS]
The execute-change-set
step was trying to run before the change set was fully created. Classic timing issue.
The Fix
I added a simple polling step to wait for the change set to reach CREATE_COMPLETE
before executing it. If the status becomes FAILED
, it prints out the error and exits.
1- name: Wait for change set to be created2 run: |3 for i in {{1..30}}; do4 status=$(aws cloudformation describe-change-set5 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}"6 --stack-name "${{ env.STACK_NAME }}"7 --query "Status" --output text)89 echo "Current change set status: $status"1011 if [[ "$status" == "CREATE_COMPLETE" ]]; then12 break13 elif [[ "$status" == "FAILED" ]]; then14 echo "ERROR: Change set creation failed." >&215 aws cloudformation describe-change-set16 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}"17 --stack-name "${{ env.STACK_NAME }}"18 exit 119 fi2021 echo "Waiting 10s for change set to be ready..."22 sleep 1023 done
When It Happens
This happens because create-change-set
is asynchronous β it returns instantly while still processing in the background. If you try to execute it right away, CloudFormation throws an error.
The Full Code
1runs-on: ubuntu-latest2 steps:3 - name: Checkout4 uses: actions/checkout@v456 - name: Configure AWS credentials7 uses: aws-actions/configure-aws-credentials@v48 with:9 role-to-assume: ${{ env.AWS_ROLE }}10 aws-region: ${{ env.AWS_REGION }}1112 - name: Generate change set name13 id: generate-stack-name14 run: |15 TIMESTAMP=$(date '+%Y%m%d-%H%M%S')16 echo "timestamp=$TIMESTAMP" >> "$GITHUB_OUTPUT"17 echo "change_set_name=${STACK_NAME}-$TIMESTAMP" >> "$GITHUB_OUTPUT"1819 - name: Upload template to S320 run: |21 aws s3 cp $TEMPLATE_FILE s3://${{ env.S3_BUCKET }}/${{ github.sha }}.yaml2223 - name: Create CloudFormation change set24 run: |25 aws cloudformation create-change-set \26 --stack-name "${{ env.STACK_NAME }}" \27 --template-url https://s3.amazonaws.com/${{ env.S3_BUCKET }}/${{ github.sha }}.yaml \28 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}" \29 --capabilities CAPABILITY_NAMED_IAM3031 - name: Wait for change set to be created32 run: |33 for i in {1..30}; do34 status=$(aws cloudformation describe-change-set \35 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}" \36 --stack-name "${{ env.STACK_NAME }}" \37 --query "Status" --output text)3839 echo "Current change set status: $status"4041 if [[ "$status" == "CREATE_COMPLETE" ]]; then42 break43 elif [[ "$status" == "FAILED" ]]; then44 echo "ERROR: Change set creation failed." >&245 aws cloudformation describe-change-set \46 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}" \47 --stack-name "${{ env.STACK_NAME }}"48 exit 149 fi5051 echo "Waiting 10s for change set to be ready..."52 sleep 1053 done5455 - name: Execute CloudFormation change set56 run: |57 aws cloudformation execute-change-set \58 --change-set-name "${{ steps.generate-stack-name.outputs.change_set_name }}" \59 --stack-name "${{ env.STACK_NAME }}"
Pro Tip
Always check the change set status before execution. I had no idea at first that GitHub Actions could try to execute it mid-creation.
This fix helped make my deploys stable and smooth.
If you're also automating CloudFormation updates via GitHub Actions, definitely consider waiting before the execution step. Itβs a small addition but saved me a lot of debugging time π§π