code: def convert_join(value):
      
  
      if not isinstance(value, list) or len(value) != 2:
          # Cowardly refuse
          return value
  
      sep, parts = value[0], value[1]
  
      if isinstance(parts, six.string_types):
          return parts
  
      if not isinstance(parts, list):
          # This looks tricky, just return the join as it was
          return {
              "Fn::Join": value,
          }
  
      plain_string = True
  
      args = ODict()
      new_parts = []
  
      for part in parts:
          part = clean(part)
  
          if isinstance(part, dict):
              plain_string = False
  
              if "Ref" in part:
                  new_parts.append("${{{}}}".format(part["Ref"]))
              elif "Fn::GetAtt" in part:
                  params = part["Fn::GetAtt"]
                  new_parts.append("${{{}}}".format(".".join(params)))
              else:
                  for key, val in args.items():
                      # we want to bail if a conditional can evaluate to AWS::NoValue
                      if isinstance(val, dict):
                          if "Fn::If" in val and "AWS::NoValue" in str(val["Fn::If"]):
                              return {
                                  "Fn::Join": value,
                              }
  
                      if val == part:
                          param_name = key
                          break
                  else:
                      param_name = "Param{}".format(len(args) + 1)
                      args[param_name] = part
  
                  new_parts.append("${{{}}}".format(param_name))
  
          elif isinstance(part, six.string_types):
              new_parts.append(part.replace("${", "${!"))
  
          else:
              # Doing something weird; refuse
              return {
                  "Fn::Join": value
              }
  
      source = sep.join(new_parts)
  
      if plain_string:
          return source
  
      if args:
          return ODict((
              ("Fn::Sub", [source, args]),
          ))
  
      return ODict((
          ("Fn::Sub", source),
      ))
docs: Fix a Join ;)