Como resolvo erros de validação ou formato de modelo no CloudFormation?

10 minuto de leitura
0

Quero validar meu modelo do AWS CloudFormation para ter certeza de que não tenho erros de sintaxe.

Resumo

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

  • Para erros de “JSON não está bem formado” ou “YAML não está bem formado”, consulte a seção Validar sintaxe do modelo.
  • Para erros de “Dependências de recursos não resolvidas [XXXXXXXX] no bloco Recursos do modelo”, consulte a seção Validar IDs e parâmetros lógicos.
  • Para erros de “Tipo de parâmetro não reconhecido: XXXXXXXX” ou “Propriedade de parâmetro de modelo inválida 'XXXXXXXX'”, consulte a seção Validar definições de parâmetros.
  • Para erros de “Cada membro da condição deve ser uma string”, consulte a seção Confirmar se as condições estão especificadas como uma string.
  • Para erros de “Tipos de recursos não reconhecidos: [XXXXXXXX]”, consulte a seção Verificar a disponibilidade do seu tipo de recurso.
  • Para erros de “O [environmental resource] 'XXXXXXXX' não existe”, consulte a seção Verificar se seu recurso existe fora da pilha ou validar dependências para recursos na mesma pilha.
  • Para erros de “Propriedade ou propriedades inválidas do modelo [XXXXXXXX]”, consulte a seção Verificar propriedades do modelo.
  • Para erros de “Sintaxe de política inválida” ou “Política malformada”, consulte a seção Verificar a sintaxe da política para qualquer recurso relacionado à política do IAM.

Resolução

Se você receber erros ao executar comandos da AWS Command Line Interface (AWS CLI), consulte Troubleshoot AWS CLI errors. Além disso, verifique se você está usando a versão mais recente da AWS CLI.

Validar a sintaxe do modelo

Para seguir a sintaxe JSON ou YAML adequada em seu modelo do CloudFormation, considere o seguinte:

Validar IDs e parâmetros lógicos

Confirme se os IDs e parâmetros lógicos do recurso estão definidos em seu modelo.

Nos modelos JSON e YAML a seguir, test é referenciado para a propriedade ImageId. No entanto, nenhum modelo inclui uma ID lógica de recurso nem um parâmetro chamado test. Esses modelos retornam o seguinte erro: “Dependências de recursos não resolvidas [test] no bloco Recursos do modelo”. Para obter mais informações sobre definições de recursos e sua sintaxe, consulte Recursos.

Exemplo de JSON (incorreto):

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

Exemplo de YAML (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 chamado test em que a referência retorne o valor ImageId. Os exemplos de modelos JSON e YAML a seguir incluem um parâmetro com o nome test e ImageId como valor.

Exemplo de JSON (correto):

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

Exemplo de YAML (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 Tipo como uma das seguintes propriedades suportadas:
  2. No seu modelo do CloudFormation, verifique se os parâmetros incluem somente as seguintes propriedades permitidas. Para obter mais informações sobre propriedades permitidas, consulte Propriedades.
  3. No seu modelo do CloudFormation, confirme se a seção Parâmetros não contém nenhuma função intrínseca.

No exemplo de modelos JSON e YAML a seguir, o valor padrão para o ParameterC tem a função intrínseca Fn::Sub. Essa função intrínseca causa o erro de validação: “Cada membro padrão deve ser uma string”.

Exemplo de JSON (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"
        }
      }
    }
  }
}

Exemplo de YAML (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

Confirme se as condições estão especificadas como uma string

No seu modelo do CloudFormation, especifique Condições como uma string.

Os exemplos de modelos JSON e YAML a seguir especificam a condição no recurso EC2RouteA como uma lista de cadeias de caracteres em vez de uma única cadeia de caracteres. Esses modelos resultam no seguinte erro de validação: “Cada membro da Condição deve ser uma string”.

Exemplo de JSON (incorreto):

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

Exemplo de YAML (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 Condições do seu modelo e use ConditionAandB como condição para o recurso EC2RouteA. Veja os exemplos a seguir de modelos JSON e YAML.

Exemplo de JSON (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": {
        ...
      }
    }
  }
}

Exemplo de YAML (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 seu tipo de recurso

1. Verifique se seu 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 em sua região da AWS resultam no seguinte erro: “Tipos de recursos não reconhecidos: [XXXXXXXX]”.

2. Se seu modelo consistir em algum recurso de tecnologia sem servidor, inclua uma declaração de Transformação. Veja os exemplos a seguir de modelos JSON e YAML.

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

Exemplo 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'

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

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

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

Por exemplo, um recurso AWS::EC2::Instance em sua pilha que especifica um grupo de segurança (sg-1234567890) falha se:

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

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

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 as propriedades de modelo permitidas em seu modelo do CloudFormation.

Os exemplos de modelos JSON e YAML a seguir definem o recurso do bucket no mesmo nível da seção Recursos. Isso retorna o seguinte erro: “Erro de validação do modelo: Propriedade ou propriedades inválidas do modelo [Bucket]”. Esse erro é causado quando 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.

Exemplo de JSON (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"
    }
  }
}

Exemplo de YAML (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 Recursos. Veja o exemplo a seguir de modelos JSON e YAML que estão formatados corretamente.

Exemplo de JSON (correto):

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

Exemplo de YAML (correto):

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

Verificar a sintaxe da política para qualquer recurso relacionado à política do IAM

Se você estiver criando um recurso de política de Gerenciamento de Identidade e Acesso (IAM) ou uma configuração relacionada nas propriedades do recurso, verifique se a política é válida com essa base de estrutura.

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

Observação: substitua <service> por um nome de serviço de sua escolha. Substitua <APIaction> pela ação da API para o serviço selecionado. Para obter mais informações, consulte Política JSON do IAM.

Integrar seu documento de política JSON com um formato YAML

Talvez você queira integrar um documento de política JSON com um modelo de formato YAML para provisionar o CloudFormation. Isso exige que você altere a forma como o documento aparece no modelo.

Após a integração, os elementos da política parecem semelhantes aos mostrados abaixo:

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: <...>
AWS OFICIAL
AWS OFICIALAtualizada há 10 meses