Saltar al contenido

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

9 minutos de lectura
0

Deseo validar mi plantilla de AWS CloudFormation para asegurarme de que no tiene errores de sintaxis.

Solución

Nota: Si se muestran errores al poner en marcha comandos de Interfaz de la línea de comandos de AWS (AWS CLI), consulta Solución de problemas para AWS CLI. Además, asegúrate de utilizar la versión más reciente de AWS CLI.

Completa las siguientes tareas según el mensaje de error que recibas:

Error “JSON not well-formed” o “YAML not well-formed”

Si no has formateado correctamente la plantilla de CloudFormation, recibirás uno de los siguientes mensajes de error:

“JSON not well-formed”

“YAML not well-formed”

Asegúrate de seguir las prácticas recomendadas de sintaxis de JSON o YAML en tu plantilla de CloudFormation. Para resolverlo, haz lo siguiente:

  • Crea tu pila con Infrastructure Composer.
  • Valida la sintaxis de JSON y YAML con el comando validate-template de AWS CLI.
  • Valida las plantillas de JSON o YAML con el linter de AWS CloudFormation; consulta cfn-lint en el sitio web de GitHub.

Error “Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template”

Si la plantilla de CloudFormation no especifica un ID lógico de recurso o un parámetro, recibirás el siguiente mensaje de error:

“Unresolved resource dependencies [test] in the Resources block of the template”.

Para resolver este error, especifica un ID lógico de recurso. Como alternativa, crea un parámetro denominado test en el que la referencia devuelva el valor ImageId. Los siguientes ejemplos de plantillas de JSON y YAML incluyen un parámetro denominado test con ImageId como valor.

Ejemplo de JSON:

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

Ejemplo de YAML:

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

Error “Unrecognized parameter type: XXXXXXXX” o “Invalid template parameter property 'XXXXXXXX”

Si las plantillas de JSON y YAML incluyen el valor predeterminado de ParameterC como la función intrínseca Fn::Sub, recibirás el siguiente mensaje de error:

“Every Default member must be a string”.

Los parámetros no admiten funciones intrínsecas. Usa la función Fn::Sub para especificar los valores ParameterA y ParameterB. Para resolver este error, elimina ParameterC.

Para eliminar ParameterC de tu plantilla de CloudFormation, sigue estos pasos:

  1. Establece una de las siguientes propiedades admitidas para Type: String, Number, List o CommaDelimitedList.
  2. Comprueba que los parámetros incluyan solo las propiedades permitidas.
  3. Confirma que la sección Parameters no contenga ninguna función intrínseca.

Ejemplo de JSON:

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

Ejemplo de YAML:

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

Error “Every Condition member must be a string”

Las plantillas de JSON y YAML pueden especificar la condición en el recurso EC2RouteA como una lista de cadenas en lugar de una única cadena. De ser así, recibirás el siguiente mensaje de error:

“Every Condition member must be a string”.

Para resolver este error, añade ConditionAandB a la sección Conditions de tu plantilla. A continuación, utiliza ConditionAandB como condición para el recurso EC2RouteA.

Ejemplo de JSON:

{
  "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:

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:

Error “Unrecognized resource types: [XXXXXXXX]”

No todos los tipos de recursos están disponibles en todas las regiones de AWS. Si tu plantilla incluye tipos de recursos que no están disponibles en tu región, recibirás el siguiente mensaje de error:

“Unrecognized resource types: [XXXXXXXX]”.

Para resolver este error, comprueba que tu recurso esté disponible en la región. Si la plantilla está compuesta por algún recurso sin servidor, entonces incluye una declaración Transform.

Ejemplo de JSON:

{
    "Transform": "AWS::Serverless-2016-10-31", #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 #Make sure to include this.
Resources:
  MyServerlessFunctionLogicalID:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://testBucket/mySourceCode.zip'

Error “The [environmental resource] 'XXXXXXXX' does not exist”

Si el recurso AWS::EC2::Instance de la pila especifica un grupo de seguridad, recibirás el siguiente mensaje de error:

“The sg-1234567890 does not exist”.

La pila falla si el grupo de seguridad no existe del todo o si no existe en la región de la pila. Para resolver este error, añade SecurityGroupIDs a la plantilla.

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.>

Si codificas de forma fija un recurso o un nombre de recurso de Amazon (ARN) en uno de los recursos de tu pila para uno que esté fuera de la pila de CloudFormation, comprueba lo siguiente:

  • El nombre del recurso o ARN es correcto.
  • El recurso existe.
  • El recurso existe en la misma región que la pila. Algunos recursos aceptan propiedades en distintas regiones o cuentas.

Error “Invalid template property or properties [XXXXXXXX]”

Si configuras el recurso del bucket en el mismo nivel que la sección Resources de tus plantillas de JSON y YAML, recibirás el siguiente mensaje de error:

“Template validation error: Invalid template property or properties [Bucket]”.

Este error se debe a que el validador de plantillas de CloudFormation identifica el recurso del bucket como una especificación en el nivel de sección. No se permite una especificación de sección como propiedad de plantilla. Una práctica recomendada es usar solo propiedades de plantilla permitidas en la plantilla de CloudFormation.

Para resolver este error, especifica el recurso del bucket en la sección Recursos.

Ejemplo de JSON:

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

Nota: Sustituye  BucketName por el nombre de tu bucket.

Ejemplo de YAML:

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

Nota: Sustituye  BucketName por el nombre de tu bucket.

Error “Invalid policy syntax” o “MalformedPolicy”

Al crear una política de identidad, una política de recursos, una política de control de servicio o una política de control de recurso, la validación se divide en dos pasos. Estos pasos incluyen la validación de AWS Identity and Access Management (IAM) y la validación de CloudFormation.

Para validar la política, crea la tuya y, a continuación, usa el comando validate-policy de AWS CLI:

➜  aws accessanalyzer validate-policy --policy-document file://policy-document.json --policy-type IDENTITY_POLICY

Nota: Sustituye policy-document.json por la ruta del archivo JSON.

Si usas el comando validate-policy de AWS CLI, recibirás el mensaje de error “Invalid policy syntax” o “MalformedPolicy”. Para resolver este problema, cambia la Action (Acción) a s3:DeleteObject y vuelve a usar el comando.

Ejemplo de JSON:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyObjectDeletionForAllExceptRolePrefix",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:PutLifecycleConfiguration"
      ],
      "Resource": ["arn:aws:s3:::BUCKET_NAME/*"]
    }
  ]
}

Nota: Sustituye BUCKET_NAME por el nombre de tu bucket.

Añade la política validada a tu plantilla de CloudFormation y especifica los parámetros o los recursos.

Si la función secundaria hace referencia a un parámetro que no está presente en la plantilla, recibirás el siguiente mensaje de error:

“An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [Bucket] in the Resources block of the template”

Para resolver este error, actualiza Resource (Recurso) a arn:aws:s3:::${BucketName}/* en la plantilla.

Ejemplo de JSON:

{
  "Parameters": {
    "BucketName": {
      "Type": "String"
    },
    "RoleName": {
      "Type": "String"
    }
  },
  "Resources": {
    "ManagedPolicy": {
      "Type": "AWS::IAM::ManagedPolicy",
      "Properties": {
        "Roles": [
          {
            "Ref": "RoleName"
          }
        ],
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "DenyObjectDeletionForAllExceptRolePrefix",
              "Effect": "Deny",
              "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:PutLifecycleConfiguration"
              ],
              "Resource": [
                {
                  "Fn::Sub": "arn:aws:s3:::${BucketName}/*"
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Nota: Sustituye  BucketName por el nombre de tu bucket.

Comprobación manual de la sintaxis de la política de los recursos relacionados con una política de IAM

Para comprobar manualmente que la política es válida, utiliza la siguiente plantilla de política:

{  
    "Resources": {  
        "Policy": {  
            "Type": "AWS::IAM::Policy",  
            "Properties": {  
                "PolicyName": "IamPolicyName",  
                "PolicyDocument": {  
                    "Version": "2012-10-17",  
                    "Statement": [  
                        {  
                            "Effect": "effect",  
                            "Action": [  
                                "service:API_action",  
                                "<...>"  
                            ],  
                            "Resource": "desiredResourceARN",  
                            "Condition": {  
                                "ConditionConfiguration": {  
                                    "conditionKey": [  
                                        "values"  
                                    ]  
                                },  
                                "ConditionConfiguration2": "<...>"  
                            }  
                        }  
                    ]  
                }  
            }  
        }  
    }  
}

Nota: Sustituye service por el nombre del servicio y API_action por la acción de la API del servicio seleccionado. Para obtener más información, consulta Elementos de la política de JSON de IAM.

Integración del documento de la política de JSON con una plantilla en formato YAML

Si integras un documento de política de JSON con una plantilla en formato YAML para aprovisionar CloudFormation, puedes cambiar la forma en que aparece el documento en la plantilla. Esto evita los bloques mixtos en YAML y JSON. Tras la integración, los elementos de la política tienen un aspecto similar al de la siguiente plantilla de ejemplo:

Resources:  
  Policy:  
    Type: 'AWS::IAM::Policy'  
    Properties:  
      PolicyName: IamPolicyName  
      PolicyDocument:  
        Version: 2012-10-17  
        Statement:  
          - Effect: effect  
            Action:  
              - '<service>:<API_action>'  
              - <...>  
            Resource: desiredResourceARN  
            Condition:  
              ConditionConfiguration:  
                conditionKey:  
                  - values  
              ConditionConfiguration2: <...>

Nota: Sustituye IamPolicyName por el nombre de tu política de IAM.

OFICIAL DE AWSActualizada hace 9 meses