From edb09fb9c981c36f0cc6313b3f38aed88b6f86ca Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Tue, 7 Jan 2020 13:50:42 -0500 Subject: [PATCH 1/3] Deployment role for CloudFormation Role as arguement if not None Role as arguement if not None Test Test --- deployer/cloudformation.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/deployer/cloudformation.py b/deployer/cloudformation.py index 5bdac2e..812f6ee 100644 --- a/deployer/cloudformation.py +++ b/deployer/cloudformation.py @@ -95,21 +95,19 @@ def cancel_create(self, signal, frame): def cancel_update(self, signal, frame): logger.critical('Process Interupt') logger.critical('Cancelling Stack Update: %s' % self.stack_name) - self.client.cancel_update_stack(StackName=self.stack_name) + self.client.cancel_update_stack(RoleARN=self.role, StackName=self.stack_name) exit(1) @retry(ClientError,logger=logger) def get_outputs(self): - resp = self.client.describe_stacks( - StackName=self.stack_name) + resp = self.client.describe_stacks(RoleARN=self.role, StackName=self.stack_name) self.outputs = resp['Stacks'][0]['Outputs'] return self.outputs @retry(ClientError,tries=6,logger=logger) def reload_stack_status(self): try: - resp = self.client.describe_stacks( - StackName=self.stack_name) + resp = self.client.describe_stacks(RoleARN=self.role, StackName=self.stack_name) self.stack_status = resp['Stacks'][0]['StackStatus'] except Exception as e: self.stack_status = 'False' @@ -118,6 +116,7 @@ def reload_stack_status(self): def reload_change_set_status(self, change_set_name): try: resp = self.client.describe_change_set( + RoleARN=self.role, ChangeSetName=change_set_name, StackName=self.stack_name ) @@ -218,8 +217,10 @@ def create_stack(self): 'CAPABILITY_AUTO_EXPAND' ] } + args.update({"RoleARN": self.role}) if self.role else logger.debug("Not using deployment role!") args.update({'TemplateBody': self.template_body} if self.template_body else {"TemplateURL": self.template_url}) - args.update({'TimeoutInMinutes': self.timeout} if self.timeout else {}) + + args.update({'TimeoutInMinutes': self.timeout}) if self.timeout else logger.debug("Not using timeout!") if self.template_body: logger.info("Using local template due to null template bucket") self.client.create_stack(**args) @@ -242,7 +243,7 @@ def create_waiter(self, start_time): raise e else: try: - waiter.wait(StackName=self.stack_name) + waiter.wait(RoleARN=self.role, StackName=self.stack_name) except WaiterError as e: status = self.reload_stack_status() logger.info(status) @@ -264,6 +265,7 @@ def update_stack(self): 'CAPABILITY_AUTO_EXPAND' ] } + args.update({"RoleARN": self.role}) if self.role else logger.debug("Not using deployment role!") args.update({'TemplateBody': self.template_body} if self.template_body else {"TemplateURL": self.template_url}) if self.template_body: logger.info("Using local template due to null template bucket") @@ -288,7 +290,7 @@ def update_waiter(self, start_time): self.output_events(start_time, 'update') else: try: - waiter.wait(StackName=self.stack_name) + waiter.wait(RoleARN=self.role, StackName=self.stack_name) except WaiterError as e: status = self.reload_stack_status() logger.info(status) @@ -307,7 +309,7 @@ def output_events(self, start_time, action): status = self.reload_stack_status() table = [] sleep(15) - events = self.client.describe_stack_events(StackName=self.stack_name) + events = self.client.describe_stack_events(RoleARN=self.role, StackName=self.stack_name) events = events['StackEvents'] events.reverse() for event in events: @@ -337,7 +339,9 @@ def output_events(self, start_time, action): count += 1 def delete_stack(self): - self.client.delete_stack(StackName=self.stack_name) + args = { "StackName" : self.stack_name } + args.update({"RoleARN": self.role}) if self.role else logger.debug("Not using deployment role!") + self.client.delete_stack(**args) logger.info(self.colors['error'] + "Sent delete request to stack" + self.colors['reset']) return True @@ -347,11 +351,13 @@ def get_latest_change_set_name(self): while 'NextToken' in resp or latest == None: if 'NextToken' in resp: resp = self.client.list_change_sets( + RoleARN=self.role, StackName=self.stack_name, NextToken=resp['NextToken'] ) else: resp = self.client.list_change_sets( + RoleARN=self.role, StackName=self.stack_name ) for change in resp['Summaries']: @@ -367,6 +373,7 @@ def get_change_set(self, change_set_name, change_set_description, change_set_typ # create the change set if self.stack_status: resp = self.client.create_change_set( + RoleARN=self.role, StackName=self.stack_name, TemplateURL=self.template_url, Parameters=self.build_params(), @@ -394,12 +401,14 @@ def get_change_set(self, change_set_name, change_set_description, change_set_typ def execute_change_set(self, change_set_name): resp = self.client.execute_change_set( + RoleARN=self.role, ChangeSetName=change_set_name, StackName=self.stack_name ) def print_change_set(self, change_set_name, change_set_description): resp = self.client.describe_change_set( + RoleARN=self.role, ChangeSetName=change_set_name, StackName=self.stack_name ) @@ -421,14 +430,14 @@ def print_change_set(self, change_set_name, change_set_description): def check_stack_exists(self): try: - self.client.describe_stacks(StackName=self.stack_name) + self.client.describe_stacks(RoleARN=self.role, StackName=self.stack_name) return True except ClientError: return False def describe(self): try: - return self.client.describe_stacks(StackName=self.stack_name)['Stacks'][0] + return self.client.describe_stacks(RoleARN=self.role, StackName=self.stack_name)['Stacks'][0] except ClientError: return {} @@ -446,6 +455,7 @@ def __init__(self, profile, config_file, stack, disable_rollback=False, print_ev self.stack_name = self.get_config_att('stack_name', required=True) self.base = self.get_config_att('sync_base', '.') self.session = Session(profile_name=profile,region_name=self.get_config_att('region')) + self.role = self.get_config_att('deployment_role') self.repository = self.get_repository() self.region = self.session.region_name self.commit = self.repository.head.object.hexsha if self.repository else 'null' From a1a33f4b65199d553a3f21e9ab27aa603b31a8e6 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Mon, 13 Jan 2020 09:50:44 -0500 Subject: [PATCH 2/3] Remove RoleARN from waiter --- deployer/cloudformation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployer/cloudformation.py b/deployer/cloudformation.py index 812f6ee..73b5777 100644 --- a/deployer/cloudformation.py +++ b/deployer/cloudformation.py @@ -243,7 +243,7 @@ def create_waiter(self, start_time): raise e else: try: - waiter.wait(RoleARN=self.role, StackName=self.stack_name) + waiter.wait(StackName=self.stack_name) except WaiterError as e: status = self.reload_stack_status() logger.info(status) From 08f013ebaa569b4d101599ff76f8e93a393c7bec Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Mon, 13 Jan 2020 09:58:40 -0500 Subject: [PATCH 3/3] Remove from describe stacks Remove from describe stacks --- deployer/cloudformation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployer/cloudformation.py b/deployer/cloudformation.py index 73b5777..41d5e07 100644 --- a/deployer/cloudformation.py +++ b/deployer/cloudformation.py @@ -107,7 +107,7 @@ def get_outputs(self): @retry(ClientError,tries=6,logger=logger) def reload_stack_status(self): try: - resp = self.client.describe_stacks(RoleARN=self.role, StackName=self.stack_name) + resp = self.client.describe_stacks(StackName=self.stack_name) self.stack_status = resp['Stacks'][0]['StackStatus'] except Exception as e: self.stack_status = 'False' @@ -309,7 +309,7 @@ def output_events(self, start_time, action): status = self.reload_stack_status() table = [] sleep(15) - events = self.client.describe_stack_events(RoleARN=self.role, StackName=self.stack_name) + events = self.client.describe_stack_events(StackName=self.stack_name) events = events['StackEvents'] events.reverse() for event in events: