def create_aws_clients(region, profile, *clients):
  """
  Create boto3 clients for one or more AWS services. These are the services used within the libs:
    cloudformation, cloudfront, ec2, iam, lambda, route53, waf
  Args:
    region: the region in which to create clients that are region-specific (all but IAM)
    profile: Name of profile (in .aws/credentials). Pass the value None if using instance credentials on EC2 or Lambda
    clients: names of the clients to create (lowercase, must match what boto3 expects)
  Returns:
    A dictionary of <key>,<value> pairs for several AWS services, using the labels above as keys, e.g.:
    { "cloudfront": <cloudfront_client>, ... }
    Dictionary contains an extra record, "SESSION" - pointing to the session that created the clients
  """
  if not profile:
    profile = None

  client_key = (region, profile)

  aws_clients = client_cache.get(client_key, {})
  requested_clients = set(clients)
  new_clients = requested_clients.difference(aws_clients)

  if not new_clients:
    return aws_clients

  session = aws_clients.get("SESSION")
  try:
    if not session:
      session = boto3.Session(region_name=region, profile_name=profile)
      aws_clients["SESSION"] = session
    # build clients
    client_dict = {c: session.client(c) for c in new_clients}
    # append the session itself in case it's needed by the client code - can't get it from the clients themselves
    aws_clients.update(client_dict)

    # add the created clients to the cache
    client_cache[client_key] = aws_clients
    return aws_clients
  except ClientError as error:
    raise RuntimeError("Exception logging in with Session() and creating clients", error)