Ir para o conteúdo

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

9 minuto de leitura
0

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

Resolução

Observação: se você receber mensagens de erro ao executar comandos da AWS Command Line Interface (AWS CLI), consulte Solução de problemas da AWS CLI. Além disso, verifique se você está usando a versão mais recente da AWS CLI.

Conclua as tarefas a seguir com base na mensagem de erro recebida.

Erro "JSON not well-formed" ou "YAML not well-formed"

Se você não formatou corretamente seu modelo do CloudFormation, receberá uma das seguintes mensagens de erro:

"JSON not well-formed"

"YAML not well-formed"

Certifique-se de seguir as práticas recomendadas de sintaxe JSON ou YAML em seu modelo do CloudFormation. Para resolver esse erro, realize as seguintes ações:

Erro "Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template"

Se seu modelo do CloudFormation não especificar um ID lógico de recurso ou um parâmetro, você receberá a seguinte mensagem de erro:

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

Para resolver esse erro, especifique um ID lógico do recurso. Ou crie um parâmetro chamado test em que a referência retorne o valor de 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:

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

Exemplo de YAML:

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

Erro "Unrecognized parameter type: XXXXXXXX" or "Invalid template parameter property 'XXXXXXXX'"

Se seus modelos JSON e YAML incluírem o valor padrão de ParameterC como a função intrínseca Fn::Sub, você receberá a seguinte mensagem de erro:

"Every Default member must be a string."

Os parâmetros não oferecem suporte a funções intrínsecas. Use a função Fn::Sub para especificar os valores de ParameterA e ParameterB. Para resolver esse erro, remova ParameterC.

Para remover ParameterC em seu modelo do CloudFormation, conclua as seguintes etapas:

  1. Defina Type como uma das seguintes propriedades compatíveis: String, Number, List ou CommaDelimitedList.
  2. Verifique se os parâmetros incluem somente as propriedades permitidas.
  3. Confirme se a seção Parâmetros não contém nenhuma função intrínseca.

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

Exemplo de YAML:

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

Erro "Every Condition member must be a string"

Seus modelos JSON e YAML podem especificar condição no recurso EC2RouteA como uma lista de strings em vez de uma única string. Assim, você recebe a seguinte mensagem de erro:

"Every Condition member must be a string."

Para resolver esse erro, adicione ConditionAandB à seção Condições do seu modelo. Em seguida, use ConditionAandB como condição para o recurso EC2RouteA.

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

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

Erro "Unrecognized resource types: [XXXXXXXX]"

Nem todo tipo de recurso está disponível em todas as regiões da AWS. Se seu modelo incluir tipos de recursos que não estão disponíveis em sua região, você receberá a seguinte mensagem de erro:

"Unrecognized resource types: [XXXXXXXX]."

Para resolver esse erro, verifique se seu recurso está disponível na sua região. Se seu modelo consistir em algum recurso de tecnologia sem servidor, inclua uma instrução Transform.

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

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

Erro "The [environmental resource] 'XXXXXXXX' does not exist"

Se o recurso AWS::EC2::Instance da sua pilha especificar um grupo de segurança, você receberá a seguinte mensagem de erro:

"The sg-1234567890 does not exist."

A pilha falha se o grupo de segurança não existir ou se ele não existir na região da pilha. Para resolver esse erro, adicione SecurityGroupIDs ao seu modelo.

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

Se você codificar 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 pilha. Alguns recursos aceitam propriedades em todas as regiões ou contas.

Erro "Invalid template property or properties [XXXXXXXX]"

Se você definir o recurso do bucket no mesmo nível da seção Recursos em seus modelos JSON e YAML, receberá a seguinte mensagem de erro:

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

Esse erro ocorre quando o validador de modelo do CloudFormation identifica 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. É uma prática recomendada usar somente propriedades de modelo permitidas em seu modelo do CloudFormation.

Para resolver esse erro, especifique o recurso do bucket na seção Recursos.

Exemplo de JSON:

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

Observação: substitua BucketName pelo nome do seu bucket.

Exemplo de YAML:

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

Observação: substitua BucketName pelo nome do seu bucket.

Erro "Invalid policy syntax" ou "MalformedPolicy"

Quando você cria uma política de identidade, política de recursos, política de controle de serviços ou política de controle de recursos, a validação é dividida em duas etapas. Essas etapas incluem a validação do AWS Identity and Access Management (AWS IAM) e a validação do CloudFormation.

Para validar a política, crie sua política e execute o seguinte comando validate-policy da AWS CLI:

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

Observação: substitua policy-document.json pelo caminho do arquivo para seu JSON.

Se você executar o comando validate-policy da AWS CLI, receberá a mensagem de erro "Invalid policy syntax" ou "MalformedPolicy". Para resolver esse problema, altere a Ação para s3:DeleteObject e execute o comando novamente.

Exemplo de JSON:

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

Observação: substitua BUCKET_NAME pelo nome do seu bucket.

Adicione a política validada ao seu modelo do CloudFormation e especifique parâmetros ou recursos.

Se a subfunção fizer referência a um parâmetro que não está presente no modelo, você receberá a seguinte mensagem de erro:

"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 esse erro, atualize o Recurso para arn:aws:s3:::${BucketName}/* no modelo.

Exemplo 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}/*"
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Observação: substitua BucketName pelo nome do seu bucket.

Verifique manualmente a sintaxe da política para recursos relacionados à política do IAM

Para verificar manualmente se a política é válida, use o seguinte modelo 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": "<...>"  
                            }  
                        }  
                    ]  
                }  
            }  
        }  
    }  
}

Observação: substitua service pelo nome do seu serviço e API_action pela ação da sua API para o serviço selecionado. Para obter mais informações, consulte Referência de elemento de política JSON do IAM.

Integre seu documento de política JSON a um modelo de formato YAML

Se você integrar um documento de política JSON a um modelo de formato YAML para provisionar o CloudFormation, pode alterar a forma como o documento aparece no modelo. Isso evita blocos mistos de YAML e JSON. Após a integração, os elementos da política parecem semelhantes ao modelo de exemplo a seguir:

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 IamPolicyName pelo nome da sua política do IAM.

AWS OFICIALAtualizada há 5 meses