Passer au contenu

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

Lecture de 9 minute(s)
0

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

Résolution

Remarque : si des erreurs surviennent lorsque vous exécutez des commandes de l'interface de la ligne de commande AWS (AWS CLI), consultez la section Résoudre des erreurs liées à l’AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l'AWS CLI.

Effectuez les tâches suivantes en fonction du message d'erreur que vous recevez.

Message d’erreur « JSON not well-formed » ou « YAML not well-formed »

Si vous n'avez pas correctement formaté votre modèle CloudFormation, l'un des messages d'erreur suivants s'affiche :

« JSON not well-formed »

« YAML not well-formed »

Assurez-vous de suivre les bonnes pratiques en matière de syntaxe JSON ou YAML dans votre modèle CloudFormation. Pour résoudre cette erreur, procédez comme suit :

  • Créez votre pile avec Infrastructure Composer.
  • Validez votre syntaxe JSON et YAML à l'aide de la commande validate-template de l’AWS CLI.
  • Pour valider vos modèles JSON ou YAML à l’aide d’AWS CloudFormation Linter, consultez la page cfn-lint sur le site Web de GitHub.

Message d’erreur « Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template »

Si votre modèle CloudFormation ne spécifie pas d'ID logique de ressource ou de paramètre, le message d'erreur suivant s'affiche :

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

Pour résoudre cette erreur, spécifiez un ID logique de ressource. Vous pouvez aussi créer un paramètre nommé test dans lequel la référence renvoie la valeur ImageId. Les exemples de modèle JSON et YAML suivants incluent un paramètre dont la valeur est test et ImageId.

Exemple de modèle JSON :

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

Exemple de modèle YAML :

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

Message d’erreur « Unrecognized parameter type: XXXXXXXX » ou « Invalid template parameter property 'XXXXXXXX' »

Si vos modèles JSON et YAML incluent la valeur par défaut de ParameterC en tant que fonction intrinsèque Fn::Sub, le message d'erreur suivant s'affiche :

« Every Default member must be a string. »

Les paramètres ne prennent pas en charge les fonctions intrinsèques. Utilisez la fonction Fn::Sub pour spécifier les valeurs ParameterA et ParameterB. Pour résoudre cette erreur, supprimez ParameterC.

Pour supprimer ParameterC de votre modèle CloudFormation, procédez comme suit :

  1. Définissez Type sur l'une des propriétés prises en charge suivantes, Chaîne, Nombre, Liste ou CommaDelimitedList.
  2. Vérifiez que les paramètres incluent uniquement les propriétés autorisées.
  3. Vérifiez que la section Paramètres ne contient aucune fonction intrinsèque.

Exemple de modèle JSON :

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

Exemple de modèle YAML :

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

Message d’erreur « Every Condition member must be a string »

Les exemples de modèles JSON et YAML suivants peuvent spécifier la condition dans la ressource EC2RouteA sous la forme d’une liste de chaînes au lieu d’une seule chaîne. Dans ce cas, le message d’erreur suivant s’affiche :

« Every Condition member must be a string. »

Pour résoudre cette erreur, ajoutez ConditionaAndB à la section Conditions de votre modèle. Puis, utilisez ConditionAandB comme condition pour la ressource EC2RouteA.

Exemple de modèle 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": {
        ...
      }
    }
  }
}

Exemple de modèle 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:

Message d’erreur « Unrecognized resource types: [XXXXXXXX] »

Tous les types de ressources ne sont pas disponibles dans toutes les régions AWS. Si votre modèle inclut des types de ressources qui ne sont pas disponibles dans votre région, le message d'erreur suivant s'affiche :

« Unrecognized resource types: [XXXXXXXX]. »

Pour résoudre cette erreur, vérifiez que la ressource est disponible dans votre région. Si votre modèle contient des ressources sans serveur, incluez une déclaration Transform.

Exemple de modèle 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"
            }
        }
   }
}

Exemple de modèle 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'

Message d’erreur « The [environmental resource] 'XXXXXXXX' does not exist »

Si la ressource AWS::EC2::Instance de votre pile spécifie un groupe de sécurité, le message d'erreur suivant s'affiche :

« The sg-1234567890 does not exist. »

La pile échoue si le groupe de sécurité n'existe pas ou si le groupe de sécurité n'existe pas dans la région de la pile. Pour résoudre cette erreur, ajoutez les SecurityGroupIds à votre modèle.

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 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 que la pile. Certaines ressources acceptent des propriétés appartenant à des régions ou à des comptes différents.

Message d’erreur « Invalid template property or properties [XXXXXXXX] »

Si vous définissez la ressource du compartiment au même niveau que la section Ressources de vos modèles JSON et YAML, le message d'erreur suivant s'affiche :

« 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. Il est recommandé d'utiliser uniquement les propriétés de modèle autorisées dans votre modèle CloudFormation.

Pour résoudre cette erreur, spécifiez la ressource du compartiment dans la section Ressources.

Exemple de modèle JSON :

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

Remarque : remplacez BucketName par le nom de votre compartiment.

Exemple de modèle YAML :

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

Remarque : remplacez BucketName par le nom de votre compartiment.

Message d’erreur « Invalid policy syntax » ou « MalformedPolicy »

Lorsque vous créez une politique d'identité, une politique de ressources, une politique de contrôle des services ou une politique de contrôle des ressources, la validation est divisée en deux étapes. Ces étapes incluent la validation Gestion des identités et des accès AWS (AWS IAM) et la validation CloudFormation.

Pour valider la politique, créez votre politique, puis exécutez la commande validate-policy de l'AWS CLI suivante :

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

Remarque : remplacez policy-document.json par le chemin d'accès à votre fichier JSON.

Si vous exécutez la commande validate-policy de l'AWS CLI, le message d'erreur « Invalid policy syntax » ou « MalformedPolicy » s'affiche. Pour résoudre ce problème, remplacez l'action par s3:DeleteObject et exécutez à nouveau la commande.

Exemple de modèle JSON :

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

Remarque : remplacez BUCKET_NAME par le nom de votre compartiment.

Ajoutez la politique validée à votre modèle CloudFormation et spécifiez des paramètres ou des ressources.

Si la sous-fonction fait référence à un paramètre qui n'est pas présent dans le modèle, le message d'erreur suivant s'affiche :

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

Pour résoudre cette erreur, mettez à jour la ressource en arn:aws:s3:::${BucketName}/*.

Exemple de modèle 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}/*"
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Remarque : remplacez BucketName par le nom de votre compartiment.

Vérifier manuellement la syntaxe de la politique pour les ressources liées aux politiques IAM

Pour vérifier manuellement la validité de la politique, utilisez le modèle de politique suivant :

{  
    "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 votre service et API_action par votre action d'API pour le service que vous avez sélectionné. Pour plus d’informations, consultez la section Référence de l’élément de politique JSON IAM.

Intégrer votre document de politique JSON au modèle de format YAML

Si vous intégrez un document de politique JSON à un modèle au format YAML pour provisionner CloudFormation, vous pouvez modifier la façon dont le document apparaît dans le modèle. Cela permet d'éviter les blocs mixtes YAML et JSON. Après intégration, les éléments de politique ressemblent à l'exemple de modèle suivant :

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 IamPolicyName par le nom de votre politique IAM.

AWS OFFICIELA mis à jour il y a 2 mois