in aws/solutions/StackSetsResource/FunctionCode/lambda_function.py [0:0]
def create(event, context):
"""
Handle StackSetResource CREATE events.
Create StackSet resource and any stack instances specified in the template.
"""
# pylint: disable=unused-argument
# Collect everything we need to create the stack set
# optional
if 'StackSetName' in event['ResourceProperties']:
set_name = event['ResourceProperties']['StackSetName']
else:
set_name = "{}-{}".format(get_stack_from_arn(event['StackId']), event['LogicalResourceId'])
if 'StackSetDescription' in event['ResourceProperties']:
set_description = event['ResourceProperties']['StackSetDescription']
else:
set_description = "This StackSet belongs to the CloudFormation stack {}.".format(
get_stack_from_arn(event['StackId']))
if 'OperationPreferences' in event['ResourceProperties']:
set_ops_prefs = convert_ops_prefs(event['ResourceProperties']['OperationPreferences'])
else:
set_ops_prefs = {}
if 'Tags' in event['ResourceProperties']:
set_tags = expand_tags(event['ResourceProperties']['Tags'])
else:
set_tags = []
if 'Capabilities' in event['ResourceProperties']:
set_capabilities = event['ResourceProperties']['Capabilities']
else:
set_capabilities = ''
if 'AdministrationRoleARN' in event['ResourceProperties']:
set_admin_role_arn = event['ResourceProperties']['AdministrationRoleARN']
else:
set_admin_role_arn = ''
if 'ExecutionRoleName' in event['ResourceProperties']:
set_exec_role_name = event['ResourceProperties']['ExecutionRoleName']
else:
set_exec_role_name = ''
if 'Parameters' in event['ResourceProperties']:
set_parameters = expand_parameters(event['ResourceProperties']['Parameters'])
else:
set_parameters = []
# Required
set_template = event['ResourceProperties']['TemplateURL']
# Create the StackSet
try:
client = boto3.client('cloudformation',
region_name=os.environ['AWS_REGION'])
response = client.create_stack_set(
StackSetName=set_name,
Description=set_description,
TemplateURL=set_template,
# TemplateBody='string',
Parameters=set_parameters,
Capabilities=set_capabilities,
Tags=set_tags,
AdministrationRoleARN=set_admin_role_arn,
ExecutionRoleName=set_exec_role_name
# ClientRequestToken='string'
)
if response['ResponseMetadata']['HTTPStatusCode'] == 200:
set_id = response['StackSetId']
else:
raise Exception("HTTP Error: {}".format(response))
except ClientError as e:
if e.response['Error']['Code'] == 'NameAlreadyExistsException':
raise Exception("A StackSet called {} already exists.".format(set_name))
else:
raise Exception("Unexpected error: {}".format(e))
logger.info("Created StackSet: {}".format(set_id))
physical_resource_id = set_id
# Deploy stack to accounts and regions if defined.
# We're going to switch from a single stack instance definition to an array
# of stack instance objects. This will allow more complex stack structures
# across accounts and regions, including parameter overrides
# Iterate over stack instances
for instance in event['ResourceProperties']['StackInstances']:
if 'ParameterOverrides' in instance:
param_overrides = expand_parameters(instance['ParameterOverrides'])
else:
param_overrides = []
logger.debug("Stack Instance: Regions: {} : Accounts: {} : Parameters: {}".format(
instance['Regions'], instance['Accounts'], param_overrides))
# Make sure every stack instance defines both a list of accounts and
# a list of regions
if instance['Regions'][0] != '' and instance['Accounts'][0] == '':
raise Exception("You must specify at least one account with a list of regions.")
elif instance['Regions'][0] == '' and instance['Accounts'][0] != '':
raise Exception("You must specify at least one region with a list of accounts.")
elif instance['Regions'][0] != '' and instance['Accounts'][0] != '':
logger.info("Creating stacks in accounts: %s and regions: {}".format(
instance['Accounts'], instance['Regions']))
response = create_stacks(
os.environ['AWS_REGION'],
set_id,
instance['Accounts'],
instance['Regions'],
param_overrides,
set_ops_prefs
)
logger.debug(response)
response_data = {}
return physical_resource_id, response_data