in Lambda/BackupOrgPolicyManager/src/BackupOrgPolicyManager.py [0:0]
def lambda_handler(event, context):
"""
Main Lambda handler function. This function will handle the Create, Update and Delete operation requests
from CloudFormation
"""
try:
# create physical resource id
status = 'SUCCESS'
if 'PhysicalResourceId' in event:
physical_resource_id = event['PhysicalResourceId']
logger.info(f"PhysicalResourceId is {physical_resource_id}")
else:
logger.info('No PhysicalResourceId in request, setting to logical id')
physical_resource_id = event['LogicalResourceId']
logger.info(f"BackupOrgPolicyManager Request: {event}")
resource_action = event['RequestType']
if resource_action == 'Delete' and physical_resource_id == event['LogicalResourceId']:
response_data = {
'Message': 'Nothing to delete'
}
status = 'SUCCESS'
send(event, context, status, response_data, physical_resource_id)
return False
properties = check_properties(event)
if properties['success']:
properties = properties['properties']
else:
response_data = {
'Message': properties['message']
}
status = 'FAILED'
send(event, context, status, response_data, physical_resource_id)
return False
if resource_action == 'Create':
response_data = create(properties)
if response_data:
physical_resource_id = response_data['PolicyId']
send(event, context, status, response_data, physical_resource_id)
else:
response_data = {
'Message': 'Policy creation and attachment failed'
}
status = 'FAILED'
send(event, context, status, response_data, physical_resource_id)
return False
elif resource_action in ('Delete', 'Update'):
assume_role_creds = assume_role(properties['OrgManagementAccount'],
'BackupOrgPolicyManagerUpdateDelete')
org_client = boto3_client('organizations', AWS_REGION, assume_role_creds)
logger.info(
f" Action: {resource_action} policy, policy_type: {properties['PolicyType']}, policy_prefix : {properties['PolicyName']}")
response = org_client.list_policies(Filter=properties['PolicyType'])
policyList = list(
filter(lambda item: item['Name'].startswith(properties['PolicyName']), response["Policies"]))
logger.info(f"Policy Found : {policyList}, Length : {len(policyList)}")
if len(policyList) == 0 and resource_action == 'Delete':
logger.error(f"Policy not found with prefix : {properties['PolicyName']} for delete, continuing")
response_data = {
'Message': 'Policy not found for prefix : ' + properties['PolicyName'] + ' skipping delete'
}
status = 'SUCCESS'
elif len(policyList) == 0 and resource_action == 'Update':
logger.error(f"Policy not found with prefix : {properties['PolicyName']}")
response_data = {
'Message': 'Policy not found for prefix : ' + properties['PolicyName']
}
status = 'FAILED'
else:
for policy in policyList:
policy_id = policy['Id']
org_client = boto3_client('organizations', AWS_REGION, assume_role_creds)
response = org_client.list_targets_for_policy(PolicyId=policy_id)
if 'Targets' in response:
curr_policy_target_list = []
for target in response['Targets']:
curr_policy_target_list.append(target['TargetId'])
# Detach the policy from existing list
detach_policy_from_target_list(curr_policy_target_list, policy_id, assume_role_creds)
# delete policies neverthless to allow new creation
try:
response = org_client.delete_policy(PolicyId=policy_id)
logger.info(f"deletePolicy response: {response}")
except Exception as e: # pylint: disable = W0703
logger.error(str(e))
if resource_action == 'Delete':
response_data = {'Message': 'Policy(s) deleted successfully'}
status = 'SUCCESS'
elif resource_action == 'Update':
# Create and attach policies with new contents
response_data = create(properties)
if not response_data:
response_data = {
'Message': 'Policy creation and attachment failed'
}
status = 'FAILED'
else:
status = 'SUCCESS'
send(event, context, status, response_data, physical_resource_id)
else:
logger.error(f"Unexpected Action : {resource_action}")
response_data = {
'Message': 'Unexpected event received from CloudFormation'
}
status = 'FAILED'
send(event, context, status, response_data, physical_resource_id)
except Exception as exc:
logger.error(f"Exception: {str(exc)}")
response_data = {
'Message': str(exc)
}
status = 'FAILED'
send(event, context, status, response_data, physical_resource_id)
raise