def remove_stack_set_instances(args): client = AWS.current_session().client('cloudformation') client.delete_stack_instances(StackSetName=args.stack_set, Accounts=args.accounts, Regions=args.regions, RetainStacks=args.retain) logger.info('Removed StackSet Instances for StackSet {}'.format(args.stack_set))
def aws_regions(): from formica.aws import AWS current_session = AWS.current_session() ec2 = current_session.client('ec2') regions = ec2.describe_regions() regions = [r['RegionName'] for r in regions['Regions']] return {'AWSRegions': regions}
def __manage_stack_set(args, create): client = AWS.current_session().client('cloudformation') params = parameters(parameters=args.parameters, tags=args.tags, capabilities=args.capabilities, accounts=vars(args).get('accounts'), regions=vars(args).get('regions'), execution_role_name=args.execution_role_name, administration_role_arn=args.administration_role_arn) loader = Loader(variables=args.vars) loader.load() if create: result = client.create_stack_set( StackSetName=args.stack_set, TemplateBody=loader.template(), ** params ) logger.info('StackSet {} created'.format(args.stack_set)) else: result = client.update_stack_set( StackSetName=args.stack_set, TemplateBody=loader.template(), ** params ) logger.info('StackSet {} updated in Operation {}'.format(args.stack_set, result['OperationId']))
def deploy(args): client = AWS.current_session().client('cloudformation') last_event = client.describe_stack_events( StackName=args.stack)['StackEvents'][0]['EventId'] client.execute_change_set( ChangeSetName=(CHANGE_SET_FORMAT.format(stack=args.stack)), StackName=args.stack) StackWaiter(args.stack, client).wait(last_event)
def remove(args): client = AWS.current_session().client('cloudformation') stack_id = client.describe_stacks( StackName=args.stack)['Stacks'][0]['StackId'] logger.info('Removing Stack and waiting for it to be removed, ...') last_event = client.describe_stack_events( StackName=args.stack)['StackEvents'][0]['EventId'] client.delete_stack(StackName=args.stack) StackWaiter(stack_id, client).wait(last_event)
def compare_stack_set(stack, vars=None, parameters={}, tags={}, main_account_parameter=False): client = AWS.current_session().client('cloudformation') stack_set = client.describe_stack_set(StackSetName=stack, )['StackSet'] __compare(stack_set['TemplateBody'], stack_set, vars, parameters, tags, main_account_parameter)
def change(args): client = AWS.current_session().client('cloudformation') loader = Loader() loader.load() change_set = ChangeSet(stack=args.stack, client=client) change_set.create(template=loader.template(), change_set_type='UPDATE', parameters=args.parameters, tags=args.tags, capabilities=args.capabilities) change_set.describe()
def new(args): client = AWS.current_session().client('cloudformation') loader = Loader() loader.load() logger.info('Creating change set for new stack, ...') change_set = ChangeSet(stack=args.stack, client=client) change_set.create(template=loader.template(), change_set_type='CREATE', parameters=args.parameters, tags=args.tags, capabilities=args.capabilities) change_set.describe() logger.info('Change set created, please deploy')
def stacks(args): client = AWS.current_session().client('cloudformation') stacks = client.describe_stacks() table = Texttable(max_width=150) table.add_rows([STACK_HEADERS]) for stack in stacks['Stacks']: table.add_row([ stack['StackName'], stack['CreationTime'], stack.get('LastUpdatedTime', ''), stack['StackStatus'] ]) logger.info("Current Stacks:\n" + table.draw() + "\n")
def resources(args): client = AWS.current_session().client('cloudformation') paginator = client.get_paginator('list_stack_resources').paginate( StackName=args.stack) table = Texttable(max_width=150) table.add_rows([RESOURCE_HEADERS]) for page in paginator: for resource in page['StackResourceSummaries']: table.add_row([ resource['LogicalResourceId'], resource['PhysicalResourceId'], resource['ResourceType'], resource['ResourceStatus'] ]) logger.info(table.draw() + "\n")
def aws_accounts(): from formica.aws import AWS current_session = AWS.current_session() organizations = current_session.client('organizations') sts = current_session.client('sts') orgs = organizations.list_accounts() accounts = [{ 'Id': a['Id'], 'Name': a['Name'], 'Email': a['Email'] } for a in orgs['Accounts'] if a['Status'] == 'ACTIVE'] account_id = sts.get_caller_identity()['Account'] return { 'AWSAccounts': accounts, 'AWSSubAccounts': [a for a in accounts if a['Id'] != account_id] }
def main_account_id(): from formica.aws import AWS sts = AWS.current_session().client('sts') identity = sts.get_caller_identity() return identity['Account']
def describe(args): client = AWS.current_session().client('cloudformation') change_set = ChangeSet(stack=args.stack, client=client) change_set.describe()
def add_stack_set_instances(args): client = AWS.current_session().client('cloudformation') client.create_stack_instances(StackSetName=args.stack_set, Accounts=args.accounts, Regions=args.regions) logger.info('Added StackSet Instances for StackSet {}'.format(args.stack_set))
def remove_stack_set(args): client = AWS.current_session().client('cloudformation') client.delete_stack_set(StackSetName=args.stack_set) logger.info('Removed StackSet with name {}'.format(args.stack_set))
def test_session_needs_to_be_set(session): AWS._AWS__session = None with pytest.raises(AttributeError): AWS.current_session()
def test_AWS_is_singleton(session): AWS.initialize() AWS.current_session() AWS.current_session() session.assert_called_once()
def create(self, template, change_set_type, parameters=[], tags=[], capabilities=[], role_arn=None, s3=False): optional_arguments = {} if parameters: optional_arguments['Parameters'] = [{ 'ParameterKey': key, 'ParameterValue': value, 'UsePreviousValue': False } for (key, value) in parameters.items()] if tags: optional_arguments['Tags'] = [{ 'Key': key, 'Value': value, } for (key, value) in tags.items()] if role_arn: optional_arguments['RoleARN'] = role_arn if capabilities: optional_arguments['Capabilities'] = capabilities if change_set_type == 'UPDATE': self.remove_existing_changeset() try: if s3: session = AWS.current_session() s3_client = session.client('s3') bucket_name = 'formica-deploy-{}'.format( str(uuid.uuid4()).lower()) bucket_path = '{}-template.json'.format(self.stack) logger.info('Creating Bucket: {}'.format(bucket_name)) s3_client.create_bucket( Bucket=bucket_name, CreateBucketConfiguration=dict( LocationConstraint=session.region_name)) logger.info('Uploading to bucket: {}/{}'.format( bucket_name, bucket_path)) s3_client.put_object(Bucket=bucket_name, Key=bucket_path, Body=template) template_url = 'https://{}.s3.amazonaws.com/{}'.format( bucket_name, bucket_path) optional_arguments['TemplateURL'] = template_url else: optional_arguments['TemplateBody'] = template self.client.create_change_set(StackName=self.stack, ChangeSetName=self.name, ChangeSetType=change_set_type, **optional_arguments) logger.info( 'Change set submitted, waiting for CloudFormation to calculate changes ...' ) waiter = self.client.get_waiter('change_set_create_complete') waiter.wait(ChangeSetName=self.name, StackName=self.stack) logger.info('Change set created successfully') except WaiterError as e: status_reason = e.last_response.get('StatusReason', '') logger.info(status_reason) if "didn't contain changes" not in status_reason: sys.exit(1) finally: if s3: logger.info('Deleting Object and Bucket: {}/{}'.format( bucket_name, bucket_path)) s3_client.delete_object(Bucket=bucket_name, Key=bucket_path) s3_client.delete_bucket(Bucket=bucket_name)
def compare_stack(stack, vars=None, parameters={}, tags={}): client = AWS.current_session().client('cloudformation') template = client.get_template(StackName=stack, )['TemplateBody'] stack = client.describe_stacks(StackName=stack, )['Stacks'][0] __compare(template, stack, vars, parameters, tags)
def diff(args): Diff(AWS.current_session()).run(args.stack)