in code/fms/fms-mimic-shield-protect-route53-hosted-zones/lambda/index.py [0:0]
def lambda_handler(event, context):
responseData = {}
try:
#List of Hosted Zones
hostedZones = (r53_paginator.paginate().build_full_result())['HostedZones']
logger.debug(hostedZones)
#List of Shield Protected Resources
shieldProtected = (shield_paginator.paginate().build_full_result())['Protections']
logger.debug(shieldProtected)
except botocore.exceptions.ClientError as error:
logger.error(error.response['Error']['Message'])
if 'RequestType' in event:
responseData['Error'] = error.response['Error']
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "PaginateFailed")
return (error.response['Error']['Message'])
protectedArns = []
protectionIdList = {}
#Build a list of just resource ARN's for Shield Protected resouces
for s in shieldProtected:
protectedArns.append(s['ResourceArn'])
protectionIdList[s['ResourceArn']] = s['Id']
#If no hosted zones exist, stop gracefully now
if hostedZones == []:
logger.info("No Hosted Zones")
return ()
else:
#For each Hosted Zone
for zone in hostedZones:
logger.info(zone)
zoneId = zone['Id'].split('/')[2]
zoneArn = "arn:aws:route53:::hostedzone/" + zoneId
try:
r = r53_client.list_tags_for_resources(
ResourceType='hostedzone',
ResourceIds=[
zoneId
])
except botocore.exceptions.ClientError as error:
logger.error(error.response['Error']['Message'])
if 'RequestType' in event:
responseData['Error'] = error.response['Error']
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "ListTagsFailed")
return (error.response['Error']['Message'])
#Check resource tags vs. checkTags as include/exclude logic
tagResults = tag_check(r['ResourceTagSets'][0]['Tags'])
#If the hosted Zone is current Shield Protected
isProtected = zoneArn in protectedArns
#If tags match and it isn't protected
if tagResults == True and isProtected == False:
logger.info ("Not protected and should be")
try:
shield_client.create_protection(
Name=zoneId,
ResourceArn=zoneArn)
except botocore.exceptions.ClientError as error:
logger.error(error.response['Error']['Message'])
if 'RequestType' in event:
responseData['Error'] = error.response['Error']
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "ShieldCreateProtectionFailed")
return (error.response['Error']['Message'])
#If tags do not match requirements and it is Shield protected
elif tagResults == False and isProtected == True:
logger.info ("Protected and should not be")
protectionId = protectionIdList['zoneArn']
try:
shield_client.delete_protection(
ProtectionId=protectionId)
except botocore.exceptions.ClientError as error:
logger.error(error.response['Error']['Message'])
if 'RequestType' in event:
responseData['Error'] = error.response['Error']
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "ShieldDeleteProtectionFailed")
return (error.response['Error']['Message'])
#The other possible results require no change/action for this resource
#Is passed check tags and is already protected
#Did not pass check tags and is not protected
else:
logger.info("No change to protection needed")
#Signal CFN if this is a create, or update
if 'RequestType' in event:
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")