in control-tower-account-factory/src/common.py [0:0]
def _update_product_constraint(self, product_id, porfolio_name, regions, destination_account):
"""Delete Launch contraint, if exists. Add/update StackSet contraint for product"""
# get porfolio id
porfolio_id = self.__get_product_portfolio(product_id, porfolio_name)
if not porfolio_id:
self._log_error(f'Portfolio id for product {product_id} could not be determined. Product deployment skipped')
self._send_notification('Portfolio issue', f'Portfolio id for product {product_id} could not be determined. Product deployment skipped')
return False
try:
# get list of constraints associate with product
constraint_list = self.sc_client.list_constraints_for_portfolio(
PortfolioId=porfolio_id,
ProductId=product_id
)
stack_set_constraint_id = None
# iterate through constraints
for constraint in constraint_list['ConstraintDetails']:
# if product has Launch constraint, it has to be deleted as
# Service Catalog does not allow both Launch and StackSet contraints
# attach to product
if constraint['Type'] == 'LAUNCH':
self._log_info(f'Deleting LAUNCH contraint id: {constraint["ConstraintId"]}')
self.sc_client.delete_constraint(Id=constraint['ConstraintId'])
elif constraint['Type'] == 'STACKSET':
stack_set_constraint_id = constraint['ConstraintId']
# if no StackSet constraint create one
if not stack_set_constraint_id:
admin_role = f'arn:aws:iam::{self.master_account}:role/service-role/AWSControlTowerStackSetRole'
constraint_config = {"Version": "2.0", "Properties": {"AccountList": [destination_account], "RegionList": regions, "AdminRole": admin_role, "ExecutionRole": "AWSControlTowerExecution"}}
self.sc_client.create_constraint(
PortfolioId=porfolio_id,
ProductId=product_id,
Parameters=json.dumps(constraint_config),
Type='STACKSET',
Description='Control-Tower-Account-Baseline',
IdempotencyToken=f'ct-baseline-constraint-{datetime.utcnow().strftime("%Y%m%d%H%M%S%f")}'
)
# if product has StackSet constraint add the new account and region, if needed
else:
constraint_info = self.sc_client.describe_constraint(
Id=stack_set_constraint_id
)
constraint_config = json.loads(constraint_info['ConstraintParameters'])
if destination_account not in constraint_config['Properties']['AccountList']:
(constraint_config['Properties']['AccountList']).append(destination_account)
for region in regions:
if region not in constraint_config['Properties']['RegionList']:
(constraint_config['Properties']['RegionList']).append(region)
self.sc_client.update_constraint(
Id=stack_set_constraint_id,
Parameters=json.dumps(constraint_config)
)
return True
except ClientError as error:
self._log_error(f'Error adding account to contraint: Error: {error.response["Error"]}')
self._send_notification('Error adding account to contraint', f'Error: {error.response["Error"]}')
return False