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.
CodePudding user response:
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
CodePudding user response:
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