import json import cfnresponse import boto3 from botocore.exceptions import ClientError import time

def findNestedStack(client,resource):

if len(resource) == 2:
    return resource
else:
    max_retries = 20
    sleep_time = 1
    for i in range(max_retries):
        try:
            response = client.list_stack_resources(StackName=resource[0])
        except ClientError as e:
            print e
            time.sleep(sleep_time)
            sleep_time += 1
            continue
        else:
            break
    else:
        return
    for r in response['StackResourceSummaries']:
        if r['ResourceType'] == 'AWS::CloudFormation::Stack':
            if r['LogicalResourceId'] == resource[1]:
                resource[1] = r['PhysicalResourceId']
    del resource[0]
    return findNestedStack(client,resource)

def findResource(client,resource):

time.sleep(5)
if resource:
    max_retries = 20
    sleep_time = 1
    for i in range(max_retries):
        try:
            paginator = client.get_paginator('list_stack_resources')
            page_iterator = paginator.paginate(StackName=resource[0])
            response = []
            for page in page_iterator:
                response = response + page['StackResourceSummaries']
        except ClientError as e:
            print e
            time.sleep(sleep_time)
            sleep_time += 1
            continue
        else:
            break
    else:
        return
    for r in response:
        if r['LogicalResourceId'] == resource[1]:
            return r['PhysicalResourceId']
else:
    return

def handler(event, context):

resource = event['ResourceProperties']['LogicalResourceId'].split(".")
region = event['ResourceProperties']['Region']
client = boto3.client('cloudformation',region_name=region)

responseData = {}
responseData['PhysicalResourceId'] = findResource(client,findNestedStack(client,resource))
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")