Como resolver erros de validação ou de formato de modelos no CloudFormation?

Data da última atualização: 23/2/2022

Recebo uma mensagem de erro quando tento criar minha pilha do AWS CloudFormation.

Descrição breve

Escolha uma das seguintes soluções com base na mensagem de erro recebida:

  • Para erros “JSON not well-formed” (JSON não bem formado) ou “YAML not well-formed” (YAML não bem formado), consulte a seção Validar a sintaxe do modelo.
  • Para erros “Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template” (Dependências de recursos não resolvidas [XXXXXXXX] no bloco Resources do modelo), consulte a seção Validar a lógica e parâmetros.
  • Para erros “Unrecognized parameter type: XXXXXXXX” (Tipo de parâmetro não reconhecido: XXXXXXXX) ou “Invalid template parameter property 'XXXXXXXX” (Propriedade de parâmetro de modelo inválida 'XXXXXXXX'), consulte a seção Validar definições de parâmetros.
  • Para erros “Every Condition member must be a string” (Cada membro Conditions deve ser uma string), consulte a seção Confirmar que Conditions está especificada como uma string.
  • Para erros “Unrecognized resource types: [XXXXXXXX]” (Tipos de recursos não reconhecidos: [XXXXXXXX]), consulte a seção Verificar a disponibilidade do tipo de recurso.
  • Para erros “The [environmental resource] 'XXXXXXXX' does not exist” (O [recurso ambiental] 'XXXXXXXX' não existe), consulte a seção Verificar se o seu recurso existe fora da pilha ou validar dependências para recursos na mesma pilha.
  • Para erros “Invalid template property or properties [XXXXXXXX]” (Uma ou mais propriedades de modelo inválidas [XXXXXXXX]), consulte a seção Verificar propriedades de modelos.

Resolução

Observação: se você receber erros ao executar comandos da AWS Command Line Interface (AWS CLI), certifique-se de estar usando a versão mais recente da AWS CLI.

Validar a sintaxe do modelo

Para seguir a sintaxe JSON ou YAML apropriada no modelo do CloudFormation, considere o seguinte:

Validar IDs e parâmetros lógicos

Confirme se IDs lógicos e parâmetros de recursos estão definidos no modelo.

Nos seguintes modelos JSON e YAML, test é referenciado para ImageId. No entanto, Nenhum dos modelos inclui um ID lógico de recurso ou um parâmetro chamado test. Esses modelos retornam o erro “Unresolved resource dependencies [test] in the Resources block of the template” (Dependências de recursos não resolvidas [test] no bloco Resources do modelo). Para obter mais informações sobre definições de recursos e sua sintaxe, consulte Recursos.

JSON de exemplo (incorreto):

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

YAML de exemplo (incorreto):

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

Para resolver esse problema, adicione um ID lógico de recurso chamado test. Ou crie um parâmetro denominado test em que a referência retorna o valor imageId. O exemplo a seguir de modelos JSON e YAML inclui um parâmetro com o nome test e imageId como o valor.

JSON de exemplo (correto):

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

YAML de exemplo (correto):

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

Validar definições de parâmetros

1.    Defina Type (Tipo) como uma das seguintes propriedades com suporte:

2.    No modelo do CloudFormation, verifique se os parâmetros incluem apenas as seguintes propriedades 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.    No modelo do CloudFormation, confirme se a seção Parameters não contém funções intrínsecas.

Nos seguintes exemplos de modelos JSON e YAML, o valor padrão para ParameterC tem a função intrínseca Fn::Sub. Essa função intrínseca causa o erro de validação “Every Default member must be a string” (Cada membro Default deve ser uma string).

JSON de exemplo (incorreto):

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

YAML de exemplo (incorreto):

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 Conditions está especificada como uma string

No modelo do CloudFormation, especifique Conditions como uma string.

Nos seguintes exemplos de modelos JSON e YAML, a condição no recurso EC2RouteA é especificada como uma lista de strings em vez de uma única string. Esses modelos resultam no seguinte erro de validação: “Every Condition member must be a string” (Cada membro Conditions deve ser uma string).

JSON de exemplo (incorreto):

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

YAML de exemplo (incorreto):

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

Para resolver esse erro, adicione ConditionaAndB à seção Conditions do seu modelo e, em seguida, use ConditionaAndB como a condição para o recurso EC2RouteA. Veja os seguintes exemplos de modelos JSON e YAML.

JSON de exemplo (correto):

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

YAML de exemplo (correto):

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:

Verificar a disponibilidade do tipo de recurso

1.    Verifique se o recurso está disponível na sua Região da AWS.

Nem todos os tipos de recursos estão disponíveis em todas as Regiões da AWS. Modelos que incluem tipos de recursos que não estão disponíveis na sua Região da AWS resultam no seguinte erro: “Unrecognized resource types: [XXXXXXXX]” (Tipos de recursos não reconhecidos).

2.    Se o modelo consistir em recursos sem servidor, inclua uma declaração Transform. Veja os seguintes exemplos de modelos JSON e YAML.

JSON de exemplo:

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

YAML de exemplo:

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'

Verificar se o seu recurso existe fora da pilha ou validar dependências para recursos na mesma pilha

Se você estiver codificando um recurso ou nome do recurso da Amazon (ARN) em um dos recursos da pilha para um que esteja fora da pilha do CloudFormation, verifique o seguinte:

  • Se o nome do recurso ou ARN está correto.
  • Se o recurso existe.
  • Se o recurso existe na mesma Região da AWS que a pilha. Considere que alguns recursos aceitam propriedades em todas as contas ou Regiões da AWS.

Por exemplo, um recurso AWS::EC2::Instance na pilha que especifica um grupo de segurança (sg-1234567890) falhará se:

  • O grupo de segurança não existir.
  • O grupo de segurança não existir na região da AWS da pilha.

Como resultado, você recebe a mensagem de erro: “O sg-1234567890 não existe”. Veja o seguinte exemplo:

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

Verificar as propriedades do modelo

Use somente propriedades de modelo permitidas no seu modelo do CloudFormation.

No exemplo a seguir, modelos JSON e YAML, o recurso de bucket está no mesmo nível da seção Resources (Recursos). Isso retorna o seguinte erro: “Template validation error: Invalid template property or properties [Bucket]” (Erro de validação de modelo: Uma ou mais propriedades de modelo inválidas [Bucket]). Esse erro é causado porque o validador de modelo do CloudFormation vê o recurso do bucket como uma especificação em nível de seção. Uma especificação em nível de seção não é permitida como uma propriedade de modelo.

JSON de exemplo (incorreto):

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

YAML de exemplo (incorreto):

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 resolver esse problema, corrija a formatação para que o recurso do bucket seja especificado na seção Resources. Veja os seguintes exemplos de modelos JSON e YAML formatados corretamente.

JSON de exemplo (correto):

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

YAML de exemplo (correto):

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

Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?