Reputation: 6770
I want to get a list of stacks based on a give set of states. I am aware of a solution using the boto3 client for cloudformation, e.g. from the documentation:
response = client.list_stacks(
NextToken='string',
StackStatusFilter=[
'CREATE_IN_PROGRESS'|'CREATE_FAILED'|'CREATE_COMPLETE'|
'ROLLBACK_IN_PROGRESS'|'ROLLBACK_FAILED'|'ROLLBACK_COMPLETE'|
'DELETE_IN_PROGRESS'|'DELETE_FAILED'|'DELETE_COMPLETE'|
'UPDATE_IN_PROGRESS'|'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS'|
'UPDATE_COMPLETE'|'UPDATE_ROLLBACK_IN_PROGRESS'|'UPDATE_ROLLBACK_FAILED'|
'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS'|'UPDATE_ROLLBACK_COMPLETE'|
'REVIEW_IN_PROGRESS',
]
)
(side note: I think the |
should be ,
, but anyway)
However, I understand that the "recommended" way is using boto3 resources to access the AWS services. Unfortunately, the boto3 cloudformation resource has not method to list and filter stacks (see the documentation).
I would like to avoid looping over all stacks and check each retrieved stack object for its status.
The only way I found so far, is the work around by accessing the client of the resource, though it feels a bit hacky and there is no way to filter for instance on the stackname.
cf = boto3.Session().resource('cloudformation')
cf.meta.client.list_stacks(StackStatusFilter=['ROLLBACK_COMPLETE'])
Question: Any idea how I could get something like list_stacks(StackStatusFilter=..)
for cf
, which is a cloudformation.ServiceResource
object that allows to filter on the status and the stackname?
Upvotes: 1
Views: 12914
Reputation: 1642
This is an old post, but I thought this detailed answer would be helpful to others.
import boto3
COMMA = ','
GOOD_STATES = ('CREATE_COMPLETE,UPDATE_COMPLETE,UPDATE_ROLLBACK_COMPLETE').split(COMMA)
BUSY_STATES = ('CREATE_IN_PROGRESS,ROLLBACK_IN_PROGRESS,DELETE_IN_PROGRESS,UPDATE_IN_PROGRESS,UPDATE_COMPLETE_CLEANUP_IN_PROGRESS,UPDATE_ROLLBACK_IN_PROGRESS,UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS,REVIEW_IN_PROGRESS').split(COMMA)
BAD_STATES = ('CREATE_FAILED,ROLLBACK_FAILED,DELETE_FAILED,UPDATE_ROLLBACK_FAILED,DELETE_COMPLETE,ROLLBACK_COMPLETE').split(COMMA)
cfn_rs = boto3.resource('cloudformation')
#use one of the following that serves your purpose
good_stacks = [stack for stack in cfn_rs.stacks.all() if stack.stack_status in GOOD_STATES]
good_stack_names = [stack.name for stack in cfn_rs.stacks.all() if stack.stack_status in GOOD_STATES]
busy_stacks = [stack for stack in cfn_rs.stacks.all() if stack.stack_status in BUSY_STATES]
busy_stack_names = [stack.name for stack in cfn_rs.stacks.all() if stack.stack_status in BUSY_STATES]
bad_stacks = [stack for stack in cfn_rs.stacks.all() if stack.stack_status in BAD_STATES]
bad_stack_names = [stack.name for stack in cfn_rs.stacks.all() if stack.stack_status in BAD_STATES]
my_stacks = [stack for stack in cfn_rs.stacks.all() if stack.stack_status not in BAD_STATES]
my_stack_names = [stack.name for stack in cfn_rs.stacks.all() if stack.stack_status not in BAD_STATES]
Please note the difference between the following two:
Upvotes: -1
Reputation: 5065
Interesting; that's an unfortunate asymmetry in the boto API. That said, I would stick with the resource and use a list comprehension vs. going through the meta
attribute:
statuses = ['ROLLBACK_COMPLETE', 'CREATE_COMPLETE', 'UPDATE_COMPLETE']
cfn = boto3.resource('cloudformation')
stacks = [stack for stack in cfn.stacks.all() if stack.stack_status in statuses]
By dropping back to the meta.client
, you get a dict response rather than Resource objects. If that's ok, just use cloudformation client instead of the resource. The comprehension will return Stack
resource objects instead of dicts
Ultimately, either works and it's a matter of preference; just avoid mixing paradigms if you can.
Upvotes: 3