I spent a couple of hours yesterday trying to deploy a parent stack with two nested dynamodb table stacks. Both stacks were to be built from the same template and so provided a TableName parameter for the general purpose child stack to use along with its standard settings. This is one of the primary use cases for child stacks.

It didn’t work, and looking at #1921 it appears that the code treats the child stack as though it should just run independently.

I suspect that #2079 needs the obverse of this, which is the collection of outputs from a child to use with a peer.

""" Convert a CloudFormation ACL string (e.g., 'PublicRead') to an S3 ACL string (e.g., 'public-read') """
    return re.sub('(?<!^)(?=[A-Z])', '-', acl).lower()
def retrieve_topic_arn(topic_name):
    topics = aws_stack.connect_to_service('sns').list_topics()['Topics']
    topic_arns = [t['TopicArn'] for t in topics if t['TopicArn'].endswith(':%s' % topic_name)]
    return topic_arns[0]
def get_role_arn(role_arn, **kwargs):
    role_arn = resolve_refs_recursively(kwargs.get('stack_name'), role_arn, kwargs.get('resources'))
    return aws_stack.role_arn(role_arn)
def parse_template(template):
    try:
        return json.loads(template)
    except Exception:
        yaml.add_multi_constructor('', moto.cloudformation.utils.yaml_tag_constructor, Loader=NoDatesSafeLoader)
        try:
            return yaml.safe_load(template)
        except Exception:
            return yaml.load(template, Loader=NoDatesSafeLoader)
def template_to_json(template):
    template = parse_template(template)
    return json.dumps(template)
def get_resource_type(resource):
    res_type = resource.get('ResourceType') or resource.get('Type') or ''
    parts = res_type.split('::', 1)
    if len(parts) == 1:
        return None
    return parts[1]
def get_service_name(resource):