¿Cómo puedo solucionar los errores de formato o de validación de plantillas en CloudFormation?

10 minutos de lectura
0

Recibo un mensaje de error cuando intento crear mi pila de AWS CloudFormation.

Descripción corta

Elija una de las siguientes soluciones según el mensaje de error que reciba:

  • Para los errores “JSON not well-formed” (JSON con forma no válida) o “YAML not well-formed” (YAML con forma no válida), consulte la sección Validate template syntax (Validar síntaxis de plantilla).
  • Para los errores “Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template” (Dependencias de recursos [XXXXXXXX] no resueltas el bloque de recursos de la plantilla), consulte la sección Validate logical IDs and parameters (Validar lógicas y parámetros).
  • Para los errores “Unrecognized parameter type: XXXXXXXX” (Tipo de parámetro no reconocido: XXXXXXXX) o “Invalid template parameter property 'XXXXXXXX'” (Propiedad de parámetro de plantilla XXXXXXXX no válida), consulte la sección Validate parameter definitions (Validar definiciones de parámetros).
  • En el caso de errores “Every Condition member must be a string” (Todos los miembros de condiciones deben ser una cadena), consulte la sección Confirmar que las condiciones se especifican como una cadena.
  • Para los errores “Unrecognized resource types: [XXXXXXXX]” (Tipos de recurso no reconocidos: [XXXXXXXX]), consulte la sección Verifique la disponibilidad de su tipo de recurso.
  • Para los errores “The [environmental resource] 'XXXXXXXX' does not exist” ([Recurso de entorno] 'XXXXXXXX' no existe), consulte la sección Verificar que su recurso existe fuera de la pila, o validar dependencias para recursos en la misma pila.
  • Para los errores “Invalid template property or properties [XXXXXXXX]” (Propiedad o propiedades de plantilla [XXXXXXXX] no válidas), consulte la sección Verificar propiedades de plantilla.

Resolución

Nota: Si recibe errores al ejecutar comandos de AWS Command Line Interface (AWS CLI), asegúrese de que está utilizando la versión más reciente de AWS CLI.

Validar sintaxis de plantilla

Para seguir una sintaxis de JSON o YAML apropiada en su plantilla de CloudFormation, tenga en cuenta lo siguiente:

Valide los ID lógicos y los parámetros

Confirme que los ID lógicos de recursos y los parámetros están definidos en su plantilla.

En las siguientes plantillas de JSON y YAML test está referenciado para la propiedad ImageId. Sin embargo, ninguna plantilla incluye un ID lógico de recurso o parámetro llamado test. Estas plantillas devuelven el siguiente error: “Unresolved resource dependencies [test] in the Resources block of the template” (Dependencias de recursos no resueltas [test] en el bloque de recursos de la plantilla). Para obtener más información sobre definiciones de recursos y sus sintaxis, consulte Recursos.

Ejemplo de JSON (incorrecto):

{
  "Resources" : {
    "EC2Instance01" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : {"Ref": "test"}
      }
    }
  }
}

Ejemplo de YAML (incorrecto):

Resources:
  EC2Instance01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref test

Para solucionar este problema, agregue un ID lógico de recurso denominado test. O bien, cree un parámetro denominado test en el que la referencia devuelva el valor ImageID. Los siguientes ejemplos de plantillas JSON y YAML incluyen un parámetro denominado test e imageID como valor.

Ejemplo de JSON (correcto):

{
  "Parameters": {
     "test": {
         "Type": "String",
         "Default": "ami-xxx"
       }
  },
  "Resources" : {
    "EC2Instance01" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : {"Ref": "test"}
      }
    }
  }
}

Ejemplo de YAML (correcto):

Parameters:
  test:
    Type: String
    Default: ami-xxx
Resources:
  EC2Instance01:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref test

Valide las definiciones de parámetros

1.    Establezca el Tipo en una de las siguientes propiedades compatibles:

2.    En su plantilla de CloudFormation, verifique que los parámetros solo incluyen las siguientes propiedades permitidas:

"Parameters" : {
  "ParameterName" : {
    "AllowedPattern" : "A regular expression that represents the patterns to allow for String types.",
    "AllowedValues" : "An array containing the list of values allowed for the parameter",
    "ConstraintDescription" : "A string that explains a constraint when the constraint is violated"
    "Default" : "A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints",
    "Description" : "A string of up to 4000 characters that describes the parameter",
    "MaxLength" : "An integer value that determines the largest number of characters you want to allow for String types",
    "MaxValue" : "A numeric value that determines the largest numeric value you want to allow for Number types.",
    "MinLength" : "An integer value that determines the smallest number of characters you want to allow for String types.",
    "MinValue" : "A numeric value that determines the smallest numeric value you want to allow for Number types.",
    "NoEcho" : "Whether to mask the parameter value when a call is made that describes the stack.
                 If you set the value to true, the parameter value is masked with asterisks (*****).",
    "Type" : "The data type for the parameter (DataType)."
 },

3.    En su plantilla de CloudFormation, confirme que la sección Parameters (Parámetros) no contiene ninguna función intrínseca.

En las siguientes plantillas JSON y YAML de ejemplo, el valor predeterminado para ParameterC tiene la función intrínseca Fn::Sub. La función intrínseca causa el error de validación: “Every Default member must be a string” (Todos los miembros predeterminados deben ser una cadena).

Ejemplo de JSON (incorrecto):

{
  "Parameters": {
    "ParameterA": {
      "Type": "String",
      "Default": "abc"
    },
    "ParameterB": {
      "Type": "String",
      "Default": "def"
    },
    "ParameterC": {
      "Type": "String",
      "Default": {
        "Fn::Sub": "${ParameterA}-${ParameterB}"
      }
    }
  },
  "Resources": {
    "MyS3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Ref": "ParameterC"
        }
      }
    }
  }
}

Ejemplo de YAML (incorrecto):

Parameters:
 ParameterA:
  Type: String
  Default: abc
 ParameterB:
  Type: String
  Default: def
 ParameterC:
  Type: String
  Default: !Sub '${ParameterA}-${ParameterB}'
Resources:
 MyS3Bucket:
  Type: 'AWS::S3::Bucket'
  Properties:
   BucketName: !Ref ParameterC

Confirmar que las condiciones están especificadas como una cadena

En su plantilla de CloudFormation, especifique Conditions (Condiciones) como una cadena.

En las siguientes plantillas JSON y YAML de ejemplo, la condición en el recurso EC2RouteA se especifica como una lista de cadenas en lugar de una única cadena. Estas plantillas dan lugar al siguiente error de validación: “Every Condition member must be a string” (Todos los miembros de Condición deben ser una cadena).

Ejemplo de JSON (incorrecto):

{
  "Conditions": {
    "ConditionA": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            "",
            "Sample"
          ]
        }
      ]
    },
    "ConditionB": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            "",
            "Sample"
          ]
        }
      ]
    }
  },
  "Resources": {
    "EC2RouteA": {
      "Type": "AWS::EC2::Route",
      "Condition": [
        "ConditionA",
        "ConditionB"
      ],
      "Properties": {
       ...
      }
    }
  }
}

Ejemplo de YAML (incorrecto):

Conditions:
 ConditionA: !Not 
  - !Equals 
   - ''
   - Sample
 ConditionB: !Not 
  - !Equals 
   - ''
   - Sample
Resources:
  EC2RouteA:
  Type: 'AWS::EC2::Route'
  Condition:
   - ConditionA
   - ConditionB
  Properties:

Para resolver este error, agregue ConditionAandB sección de Condiciones de su plantilla y, a continuación, utilice ConditionAandB como la condición para el recurso de EC2RouteA. Vea el siguiente ejemplo de plantillas de JSON y YAML.

Ejemplo de JSON (correcto):

{
  "Conditions": {
    "ConditionA": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            "",
            "Sample"
          ]
        }
      ]
    },
    "ConditionB": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            "",
            "Sample"
          ]
        }
      ]
    },
    "ConditionAandB": {
      "Fn::And": [
        {
          "Condition": "ConditionA"
        },
        {
          "Condition": "ConditionB"
        }
      ]
    }
  },
  "Resources": {
    "EC2RouteA": {
      "Type": "AWS::EC2::Route",
      "Condition": "ConditionAandB",
      "Properties": {
        ...
      }
    }
  }
}

Ejemplo de YAML (correcto):

Conditions:
  ConditionA:
    Fn::Not:
    - Fn::Equals:
      - ''
      - Sample
  ConditionB:
    Fn::Not:
    - Fn::Equals:
      - ''
      - Sample
  ConditionAandB:
    Fn::And:
    - Condition: ConditionA
    - Condition: ConditionB
Resources:
  EC2RouteA:
    Type: AWS::EC2::Route
    Condition: ConditionAandB
    Properties:

Verifique la disponibilidad de su tipo de recurso

1.    Verifique que el recurso esté disponible en su región de AWS.

No todos los tipos de recurso están disponibles en todas las regiones de AWS. Las plantillas que incluyen tipos de recursos que no están disponibles en su región de AWS generan el siguiente error: “Unrecognized resource types: [XXXXXXXX]” (Tipos de recursos no reconocidos: [XXXXXXXX]).

2.    Si su plantilla se compone de algún recurso sin servidor, entonces incluya una declaración de Transform (Transformación). Vea el siguiente ejemplo de plantillas de JSON y YAML.

Ejemplo de JSON:

{
    "Transform": "AWS::Serverless-2016-10-31", #Please make sure to include this.
    "Resources": {
        "MyServerlessFunctionLogicalID": {
            "Type": "AWS::Serverless::Function",
            "Properties": {
                "Handler": "index.handler",
                "Runtime": "nodejs8.10",
                "CodeUri": "s3://testBucket/mySourceCode.zip"
            }
        }
   }
}

Ejemplo de YAML:

Transform: AWS::Serverless-2016-10-31 #Please make sure to include this.
Resources:
  MyServerlessFunctionLogicalID:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://testBucket/mySourceCode.zip'

Verifique que sus recursos existen fuera de la pila, o valida dependencias para recursos en la misma pila

Si está codificando un recurso o nombre de recurso de Amazon (ARN) en uno de los recursos de su pila para uno que está fuera de la pila de CloudFormation, verifique lo siguiente:

  • El nombre de recurso o ARN es correcto.
  • El recurso existe.
  • El recurso existe en la misma región de AWS que la pila. Tenga en cuenta que algunos recursos aceptan propiedades entre cuentas o regiones de AWS.

Por ejemplo, un recurso AWS::EC2::Instance en su pila que especifica un grupo de seguridad (sg-1234567890) genera un error si:

  • El grupo de seguridad no existe.
  • El grupo de seguridad no existe en la región de AWS de la pila.

Como resultado, recibirá el mensaje de error: “The sg-1234567890 does not exist” (sg-1234567890 no existe). Consulte el siguiente ejemplo:

LinuxInstance:
    Type: AWS::EC2::Instance
    Properties:
      SubnetId: !Ref ServerSubnetID 
      KeyName: !Ref EC2KeyPairName
      SecurityGroupIds: sg-1234567890 #<This resource must exist and be in the same AWS Region as the stack.>

Verifique las propiedades de plantilla

Utilice solo propiedades de plantilla permitidas en su plantilla de CloudFormation.

En los siguientes ejemplos de plantillas JSON y YAML, el recurso del bucket está en el mismo nivel que la sección Resources. Esto hace que se produzca el siguiente error: “Template validation error: Invalid template property or properties [Bucket]” (Error de validación de plantilla: Propiedad o propiedades de plantilla [Bucket] no válidas). Esto error se debe a que el validador de plantillas de CloudFormation ve al recurso del bucket como una especificación a nivel de sección. Una especificación a nivel de sección no está permitida como propiedad de plantilla.

Ejemplo de JSON (incorrecto):

{
  "Resources": {
    "WaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition"
    }
  },  #<There is an extra '}' causing the Resources section to be closed off after the WaitCondition resource.>
  "Bucket": {
    "Type": "AWS::S3::Bucket",
    "Properties": {
      "Name": "BucketName"
    }
  }
}

Ejemplo de YAML (incorrecto):

Resources:
  WaitCondition:
    Type: AWS::CloudFormation::WaitCondition
Bucket: # <The spacing for the entire Bucket resource is incorrect and needs to be shifted 2 spaces to the right.>
  Type: AWS::S3::Bucket
  Properties:
    Name: BucketName

Para solucionar este problema, corrija el formato para que el recurso del bucket se especifique dentro de la sección Recursos. Vea los siguientes ejemplos de plantillas JSON y YAML con formato correcto.

Ejemplo de JSON (correcto):

{
  "Resources": {
    "WaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition"
    },
    "Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "Name": "BucketName"
      }
    }
  }
}

Ejemplo de YAML (correcto):

Resources:
  WaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
  Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      Name: BucketName

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace un año