Comment puis-je résoudre les erreurs de validation ou de format de modèle dans CloudFormation ?

Lecture de 10 minute(s)
0

Je souhaite valider mon modèle AWS CloudFormation pour m’assurer qu’il est exempt d’erreur de syntaxe.

Brève description

Choisissez l’une des solutions suivantes en fonction du message d’erreur que vous recevez :

  • Pour les erreurs « JSON not well-formed » ou « YAML not well-formed », consultez la section Valider la syntaxe du modèle.
  • Pour les erreurs « Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template », consultez la section Valider les ID et paramètres logiques.
  • Pour les erreurs « Unrecognized parameter type: XXXXXXXX » ou « Invalid template parameter property ’XXXXXXXX’ », consultez la section Valider les définitions de paramètres.
  • Pour les erreurs « Every Condition member must be a string », consultez la section Confirmer que les conditions sont spécifiées sous forme de chaîne.
  • Pour les erreurs « Unrecognized resource types: [XXXXXXXX] », consultez la section Vérifier la disponibilité de votre type de ressource.
  • Pour les erreurs « The [environmental resource] ’XXXXXXXX’ does not exist », consultez la section Vérifier que votre ressource existe en dehors de la pile ou valider les dépendances pour les ressources de la même pile.
  • Pour les erreurs « Invalid template property or properties [XXXXXXXX] », consultez la section Vérifier les propriétés du modèle.
  • Pour les erreurs « Invalid policy syntax » ou « MalformedPolicy », consultez la section Vérifier la syntaxe de la politique pour toutes les ressources liées à la politique IAM.

Résolution

Si des erreurs surviennent lorsque vous exécutez des commandes de l’interface de la ligne de commande AWS (AWS CLI), reportez-vous à Corriger des erreurs liées à l’AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l’AWS CLI.

Valider la syntaxe du modèle

Pour suivre la syntaxe JSON ou YAML appropriée dans votre modèle CloudFormation, tenez compte des points suivants :

Valider les ID et paramètres logiques

Vérifiez que les ID et paramètres logiques des ressources sont définis dans votre modèle.

Dans les modèles JSON et YAML suivants, test est référencé pour la propriété ImageID. Cependant, aucun modèle n’inclut d’identifiant logique de ressource ni de paramètre nommé test. Ces modèles renvoient le message d’erreur suivant : « Unresolved resource dependencies [test] in the Resources block of the template. » Pour plus d’informations sur les définitions de ressources et leur syntaxe, consultez Ressources.

Exemple de JSON (incorrect) :

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

Exemple de YAML (incorrect) :

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

Pour résoudre ce problème, ajoutez un ID logique de ressource nommé test. Vous pouvez aussi créer un paramètre nommé test dans lequel la référence renvoie la valeur ImageID. Les exemples de modèles JSON et YAML suivants incluent un paramètre dont la valeur est le nom test et ImageID.

Exemple de JSON (correct) :

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

Exemple de YAML (correct) :

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

Valider les définitions de paramètres

  1. Définissez Type sur l’une des propriétés prises en charge suivantes :
  2. Dans votre modèle CloudFormation, vérifiez que les paramètres incluent exclusivement les propriétés autorisées suivantes. Pour plus d’informations sur les propriétés autorisées, consultez Propriétés.
  3. Dans votre modèle CloudFormation, vérifiez que la section Paramètres ne contient aucune fonction intrinsèque.

Dans les exemples de modèles JSON et YAML suivants, la valeur par défaut de ParameterC a la fonction intrinsèque Fn::Sub. Cette fonction intrinsèque provoque l’erreur de validation suivante : « Every Default member must be a string. »

Exemple de JSON (incorrect) :

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

Exemple de YAML (incorrect) :

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

Confirmez que Conditions est spécifiée sous forme de chaîne

Dans votre modèle CloudFormation, spécifiez Conditions sous forme de chaîne.

Les exemples de modèles JSON et YAML suivants spécifient la condition dans la ressource EC2RouteA sous la forme d’une liste de chaînes au lieu d’une seule chaîne. Ces modèles génèrent l’erreur de validation suivante : « Every Condition member must be a string. »

Exemple de JSON (incorrect) :

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

Exemple de YAML (incorrect) :

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

Pour résoudre cette erreur, ajoutez ConditionAandB à la section Conditions de votre modèle, puis utilisez ConditionAandB comme condition pour la ressource EC2RouteA. Consultez les exemples de modèles JSON et YAML suivants.

Exemple de JSON (correct) :

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

Exemple de YAML (correct) :

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:

Vérifier la disponibilité de votre type de ressource

1. Vérifiez que votre ressource est disponible dans votre région AWS.

Certains types de ressources ne sont pas disponibles dans toutes les régions AWS. Les modèles qui incluent des types de ressources qui ne sont pas disponibles dans votre région AWS génèrent le message d’erreur suivant : « Unrecognized resource types: [XXXXXXXX]. »

2. Si votre modèle contient des ressources sans serveur, incluez une déclaration Transform. Consultez les exemples de modèles JSON et YAML suivants.

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

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

Vérifier que votre ressource existe en dehors de la pile ou validez les dépendances pour les ressources de la même pile

Si vous codez en dur une ressource ou un Amazon Resource Name (ARN) dans l’une des ressources de votre pile pour une ressource qui ne fait pas partie de la pile CloudFormation, vérifiez les points suivants :

  • Le nom de la ressource ou l’ARN est correct.
  • La ressource existe.
  • La ressource existe dans la même région AWS que la pile. Sachez que certaines ressources acceptent des propriétés appartenant à des régions ou à des comptes AWS.

Par exemple, une ressource AWS::EC2::Instance de votre pile qui spécifie un groupe de sécurité (sg-1234567890) échoue si :

  • Le groupe de sécurité n’existe pas.
  • Le groupe de sécurité n’existe pas dans la région AWS de la pile.

Par conséquent, le message d’erreur suivant s’affiche : « The sg-1234567890 does not exist. » Reportez-vous à l’exemple suivant :

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

Vérifier les propriétés du modèle

Utilisez uniquement les propriétés de modèle autorisées dans votre modèle CloudFormation.

Les exemples de modèles JSON et YAML suivants définissent la ressource du compartiment au même niveau que la section Ressources. Il en résulte le message d’erreur suivant : « Template validation error: Invalid template property or properties [Bucket]. » Cette erreur se produit lorsque l’outil de validation de modèles CloudFormation considère la ressource du compartiment comme une spécification au niveau de la section. Une spécification au niveau de la section n’est pas autorisée en tant que propriété de modèle.

Exemple de JSON (incorrect) :

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

Exemple de YAML (incorrect) :

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

Pour résoudre ce problème, corrigez le formatage afin que la ressource du compartiment soit spécifiée dans la section Ressources. Consultez les exemples suivants de modèles JSON et YAML dont le format est correct.

Exemple de JSON (correct) :

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

Exemple de YAML (correct) :

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

Vérifier la syntaxe des politiques pour toutes les ressources liées aux politiques IAM

Si vous créez une ressource de politique Identity and Access Management (IAM) ou une configuration associée dans les propriétés de vos ressources, vérifiez que la politique est bien valide avec cette base de structure.

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

Remarque : remplacez <service> par le nom de service de votre choix. Remplacez <APIaction> par l’action d’API pour le service que vous avez sélectionné. Pour plus d’informations, consultez Politique JSON relative à IAM.

Intégrer votre document de politique JSON au format YAML

Vous souhaiterez peut-être intégrer un document de politique JSON à un modèle de format YAML pour approvisionner CloudFormation. Pour ce faire, vous devez modifier la façon dont le document apparaît dans le modèle.

Une fois l’intégration terminée, les éléments de la politique ressemblent à ce que vous voyez ci-dessous :

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 OFFICIEL
AWS OFFICIELA mis à jour il y a un mois