def lambda_handler()

in functions/source/RoleChecker/role_checker.py [0:0]


def lambda_handler(event, context):
    try:
        logger.debug("Received event: {}".format(json.dumps(event)))
        result = cfnresponse.SUCCESS
        reason = None
        client = boto3.client("iam")

        # Pull identifiers from the request (passes as Properties in the custom resource)
        role_names = event["ResourceProperties"].get("RoleNames", [])
        role_arns = {}
        missing_roles = []

        if event["RequestType"] in ["Create", "Update"]:
            for name in role_names:
                key = name.split("-")[-1]  # Strip the leading ProjectName from role name
                try:
                    logger.debug(f"Checking Account Roles for {name}")
                    role = client.get_role(RoleName=name)["Role"]
                    role_arn = role["Arn"]
                    logger.debug(f"Role already exists: {role_arn}")
                    role_arns[key + "Arn"] = role_arn
                    role_arns[key + "Name"] = role["RoleName"]
                except botocore.exceptions.ClientError as e:
                    if e.response["Error"]["Code"] in ["NoSuchEntity", "AccessDenied"]:
                        logger.error(f"{name} Role does not exist")
                        # The roles should be deployed all at once or not at all (via the supplied template);
                        #  therefore, it does not make sense to proceed with the deployment if one of them is missing
                        result = cfnresponse.FAILED
                        missing_roles.append(name)
                    else:
                        logger.error("Uncaught boto exception", e)
                        result = cfnresponse.FAILED
        elif event["RequestType"] == "Delete":
            logger.info("Delete request - NOOP")
            result = cfnresponse.SUCCESS

    except Exception as e:
        logger.error("Error: {}".format(e))
        result = cfnresponse.FAILED

    responseData = role_arns
    if result == cfnresponse.FAILED:
        reason = ("Required roles were not found in account; please use or refer to the ast-iam-role template for a "
                  "list of required roles. The following roles were not found: " + ", ".join(missing_roles))
    logger.info("Returning response of: {}, with result of: {}".format(result, responseData))
    sys.stdout.flush()
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html
    cfnresponse.send(event, context, result, responseData, reason=reason)