1

I am using the AWS CLI with bash to create and copy RDS snapshots. I have an until loop running with the condition that once the status of the snapshot is "available" the loop should close and execute the additional code to copy the snapshot. However, I see in the AWS console that the status is available but the script continues to hang, so the loop is not exiting as it should. What am I doing wrong in my loop?

Code:

#/bin/bash/

now=$(date '+%Y-%m-%d-%H')

# Creates DB snapshot
echo ---------------------------------------- >> create_snap.txt
echo Start time:  >> create_snap.txt
date >> create_snap.txt

aws rds create-db-snapshot --db-instance-identifier db --db-snapshot-identifier test-for-dr-$now

while true; do
STATUS=`aws rds describe-db-snapshots --db-snapshot-identifier test-for-$now | grep "Status" | awk '{print $2}' | sed 's/[",]//g'`

until [ "$STATUS" == "available" ]; do
  echo "" &> /dev/null

  if [ "$STATUS" == "available" ]; then
    break 2
  fi
  done
done

echo Completion time: >> create_snap.txt
date >> create_snap.txt
echo ---------------------------------------- >> create_snap.txt
echo "" >> create_snap.txt

Any help would be appreciated!

  • 5
    you should probably update the STATUS inside the loop? – Jeff Schaller Mar 1 '17 at 17:11
  • The out while true loop probably shouldn't exist either. – jordanm Mar 1 '17 at 17:11
  • 1
    You are hammering the AWS api with the command aws rds describe-db-snapshots --db-snapshot-identifier test-for-$now, possibly several times per second. I wouldn't be surprised that your query got ignored afer a few attempts. Try putting a debug line echo $STATUS in the loop to make sure it actually becomes available. – Bruno9779 Mar 1 '17 at 17:16
  • @Bruno9779 you make a great point. I put in the debug line, and as you suspected, my queries were getting ignored. It never became available. Do you know of a way to work around this? – N.M.D Mar 1 '17 at 17:24
  • @N.M.D there is also the problem pointed out from jeff. You need to update STATUS inside the loop and possibly put a sleep 20 in there so you don't get banned. – Bruno9779 Mar 1 '17 at 17:29
2

Resuming the various comments, you should modify the script to be something like this:

#/bin/bash/

now=$(date '+%Y-%m-%d-%H')

# Creates DB snapshot
echo ---------------------------------------- >> create_snap.txt
echo Start time:  >> create_snap.txt
date >> create_snap.txt

aws rds create-db-snapshot --db-instance-identifier db --db-snapshot-identifier test-for-dr-$now

while true; do
  STATUS=`aws rds describe-db-snapshots --db-snapshot-identifier test-for-$now | grep "Status" | awk '{print $2}' | sed 's/[",]//g'`

  if [ "$STATUS" == "available" ]; then
    break
  else
    echo "" &> /dev/null
  fi

  sleep 15

done

echo Completion time: >> create_snap.txt
date >> create_snap.txt
echo ---------------------------------------- >> create_snap.txt
echo "" >> create_snap.txt

As you can see, there is a single loop, the $STATUS variable gets updated in the loop and there is a sleep 15 to avoid hammering the api

  • This worked. Very nice. Thanks for your help. Very much appreciated. So, essentially, the until loop was redundant and hammering the API, causing the requests to fail. – N.M.D Mar 1 '17 at 17:53
  • 2
    The main problem was the one pointed out by Jeff Schaller. Your until loop kept comparing the same instance of STATUS and never breaking, because STATUS is updated outside the loop – Bruno9779 Mar 1 '17 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.