def METHOD_NAME(self, cfn):
    matches = []
    getatts = cfn.search_deep_keys("Fn::GetAtt")
    valid_getatts = cfn.get_valid_getatts()
    valid_attribute_functions = ["Ref"]
    for getatt in getatts:
        if len(getatt[-1]) < 2:
            message = "Invalid GetAtt for {0}"
            matches.append(
                RuleMatch(getatt, message.format("/".join(map(str, getatt[:-1]))))
            )
            continue
        if isinstance(getatt[-1], str):
            resname, restype = getatt[-1].split(".", 1)
        else:
            resname = None
            restype = None
            if isinstance(getatt[-1][1], str):
                resname = getatt[-1][0]
                restype = ".".join(getatt[-1][1:])
            elif isinstance(getatt[-1][1], dict):
                # You can ref the secondary part of a getatt
                resname = getatt[-1][0]
                restype = getatt[-1][1]
                if len(restype) == 1:
                    for k in restype.keys():
                        if k not in valid_attribute_functions:
                            message = 'GetAtt only supports functions "{0}" for attributes at {1}'
                            matches.append(
                                RuleMatch(
                                    getatt,
                                    message.format(
                                        ", ".join(
                                            map(str, valid_attribute_functions)
                                        ),
                                        "/".join(map(str, getatt[:-1])),
                                    ),
                                )
                            )
                else:
                    message = "Invalid GetAtt structure {0} at {1}"
                    matches.append(
                        RuleMatch(
                            getatt,
                            message.format(
                                getatt[-1], "/".join(map(str, getatt[:-1]))
                            ),
                        )
                    )
                # setting restype to None as we can't validate that anymore
                restype = None
            else:
                message = "Invalid GetAtt structure {0} at {1}"
                matches.append(
                    RuleMatch(
                        getatt,
                        message.format(getatt[-1], "/".join(map(str, getatt[:-1]))),
                    )
                )
        # only check resname if its set.  if it isn't it is because of bad structure
        # and an error is already provided
        if resname:
            if not isinstance(resname, str):
                message = "Invalid GetAtt structure {0} at {1}"
                matches.append(
                    RuleMatch(
                        getatt,
                        message.format(getatt[-1], "/".join(map(str, getatt[:-1]))),
                    )
                )
                continue
            if resname in valid_getatts:
                if restype is not None:
                    # Check for maps
                    restypeparts = restype.split(".")
                    if (
                        restypeparts[0] in valid_getatts[resname]
                        and len(restypeparts) >= 2
                    ):
                        if (
                            valid_getatts[resname][restypeparts[0]].get("Type")
                            != "Map"
                        ):
                            message = "Invalid GetAtt {0}.{1} for resource {2}"
                            matches.append(
                                RuleMatch(
                                    getatt[:-1],
                                    message.format(resname, restype, getatt[1]),
                                )
                            )
                        else:
                            continue
                    if (
                        restype not in valid_getatts[resname]
                        and "*" not in valid_getatts[resname]
                    ):
                        message = "Invalid GetAtt {0}.{1} for resource {2}"
                        matches.append(
                            RuleMatch(
                                getatt[:-1],
                                message.format(resname, restype, getatt[1]),
                            )
                        )
            else:
                modules = cfn.get_modules()
                if any(resname.startswith(s) for s in modules.keys()):
                    LOGGER.debug(
                        "Will consider valid getatt %s because it references a resource within a module",
                        resname,
                    )
                else:
                    message = "Invalid GetAtt {0}.{1} for resource {2}"
                    matches.append(
                        RuleMatch(
                            getatt, message.format(resname, restype, getatt[1])
                        )
                    )
    return matches