skip to Main Content

I have an array of AWS Cloudformation stacks names in stackList. Now this contains all the stacks in my AWS account, I want to delete them, but in a particular order.

Lets say the stackList contains the following string array:

aaa-bbb-ccc
aaa-ccc-ddd
aaa-ggg-ddd
bbb-ccc-ddd
mmm-nnn-yyy

I have some patterns like the cloudformation stack starts with mmm* should get deleted first, the stacks ending with *ddd should be second etc.

What is the easiest and most efficient way in doing this?

EDIT

To better explain the question, I am adding the some of the code below:

stackList="$(aws cloudformation describe-stacks | jq -r '.Stacks[].StackName')"
for stack_name in ${stackList}; do
   stack_id="$(aws cloudformation describe-stacks --stack-name ${stack_name} | jq -r '.Stacks[].StackId')"
   aws cloudformation delete-stack --stack-name "${stack_id}"
   echo "Deleting cloudformation stack ${stack_name}"
   aws cloudformation wait stack-delete-complete --stack-name "${stack_id}"
done

Now I want cloudformation stacks related to infrastructure users and credentials to be deleted last, For example, below is the order in which I want it to get deleted but the describestacks can also contain other entries, as well as the order, could be different in other landscapes.

aws-persistence-infrastructure
aws-persistence-users
aws-firewall-infrastructure
aws-network-infrastructure
aws-infrastructure-users
bootstrap-credentials-aws

I can use grep as answered below but if there is any more efficient method, it would be nice.

2

Answers


  1. grep for example:

    stackList='
        aaa-bbb-ccc
        aaa-ccc-ddd
        aaa-ggg-ddd
        bbb-ccc-ddd
        mmm-nnn-yyy
    '
    
    grep -E '^mmm' <<< $stackList 
    grep -E 'ddd$' <<< $stackList 
    
    mmm-nnn-yyy
    aaa-ccc-ddd
    aaa-ggg-ddd
    bbb-ccc-ddd
    
    Login or Signup to reply.
  2. A common arrangement for producing a custom sort order is the "decorate-sort-undecorate" pattern. Here’s a quick demo.

    aws cloudformation describe-stacks |
    jq -r '.Stacks[].StackName' |
    awk '{ key=1 }
       /-infrastructure-users$/ { key += 10 }
       /-credentials-/ { key += 100 }
       { print key "t" $0 }' |
    sort -n |
    # for debugging
    tee /dev/stderr |
    cut -f2 - |
    while read -r stack_name; do
        :
    

    The pipe to tee /dev/stderr is just for debugging, so you can examine the output from sort.
    I obviously had to guess a bit as to what your precise requirements are. Here’s a brief demo with just the Awk and sort applied to your example data: https://ideone.com/5775Ts

    1   aws-firewall-infrastructure
    1   aws-network-infrastructure
    1   aws-persistence-infrastructure
    1   aws-persistence-users
    11  aws-infrastructure-users
    101 bootstrap-credentials-aws
    

    With cut -f2- we discard the number field we added for sort (that’s the "undecorate" part).

    If you had stacks which matched both -infrastructure-users and -credentials- they would get a sort key of 111 and end up after all the others; if that’s not what you want, you can probably figure out how to change the weights. For example, if you want to put -persistence- earlier in the list, you could subtract one if you saw that pattern in the Awk script.

    Tangentially, nothing here except /dev/stderr is Bash-specific. If you wanted to use arrays, those are Bash only, but uses a different syntax. Perhaps see also Difference between sh and bash.

    Also, as a stylistic remark, probably don’t use variables just to capture the things you then immediately loop over. The above code replaces your for loop with a while read -r loop; perhaps see also https://mywiki.wooledge.org/DontReadLinesWithFor

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search