Salta al contenuto

Come posso risolvere gli errori di convalida o di formato del modello in CloudFormation?

8 minuti di lettura
0

Desidero convalidare il mio modello AWS CloudFormation per assicurarmi di non avere errori di sintassi.

Risoluzione

Nota: se ricevi errori quando esegui i comandi dell'Interfaccia della linea di comando AWS (AWS CLI), consulta Risoluzione degli errori per AWS CLI. Inoltre, assicurati di utilizzare la versione più recente di AWS CLI.

Completa le seguenti attività in base al messaggio di errore che ricevi.

Errore "JSON not well-formed" o "YAML not well-formed"

Se non hai formattato correttamente il modello CloudFormation, ricevi uno dei seguenti messaggi di errore:

"JSON not well-formed"

"YAML not well-formed"

Assicurati di seguire le best practice sulla sintassi JSON o YAML nel modello CloudFormation. Per risolvere il problema, intraprendi le seguenti azioni:

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

Se il modello CloudFormation non specifica un ID logico della risorsa o un parametro, ricevi il seguente messaggio di errore:

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

Per risolvere il problema, specifica un ID logico della risorsa. In alternativa, crea un parametro denominato test in cui il riferimento restituisca il valore ImageId. I modelli JSON e YAML di esempio seguenti includono un parametro denominato test con valore ImageId.

Esempio per JSON:

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

Esempio per YAML:

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

Errore "Unrecognized parameter type: XXXXXXXX" o "Invalid template parameter property 'XXXXXXXX'"

Se i modelli JSON e YAML includono il valore predefinito per ParameterC come funzione intrinseca Fn::Sub, ricevi il seguente messaggio di errore:

"Every Default member must be a string."

I parametri non supportano le funzioni intrinseche. Utilizza la funzione Fn::Sub per specificare i valori ParameterA e ParameterB. Per risolvere il problema, rimuovi ParameterC.

Per rimuovere ParameterC dal modello CloudFormation, completa i seguenti passaggi:

  1. Imposta Type su una delle seguenti proprietà supportate: String, Number, List o CommaDelimitedList.
  2. Verifica che i parametri includano solo le proprietà consentite.
  3. Verifica che la sezione Parametri non contenga funzioni intrinseche.

Esempio per JSON:

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

Esempio per YAML:

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

Errore "Every Condition member must be a string"

I modelli JSON e YAML potrebbero specificare la condizione nella risorsa EC2RouteA come elenco di stringhe anziché singola stringa. In tal caso, ricevi il seguente errore:

"Every Condition member must be a string."

Per risolvere il problema, aggiungi ** ConditionAandB** alla sezione Condizioni del modello. Quindi utilizza ConditionAandB come condizione per la risorsa EC2RouteA.

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

Esempio per 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:

Errore "Unrecognized resource types: [XXXXXXXX]"

Non tutti i tipi di risorse sono disponibili in tutte le Regioni AWS. Se il modello include tipi di risorse che non sono disponibili in una determinata Regione, ricevi il seguente messaggio di errore:

"Unrecognized resource types: [XXXXXXXX]."

Per risolvere il problema, verifica che la risorsa sia disponibile nella Regione. Se il modello è costituito da risorse serverless, includi una dichiarazione Transform.

Esempio per 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"
            }
        }
   }
}

Esempio per 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'

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

Se la risorsa AWS::EC2::Instance nello stack specifica un gruppo di sicurezza, ricevi il seguente messaggio di errore:

"The sg-1234567890 does not exist."

Lo stack genera un errore se il gruppo di sicurezza non esiste, oppure se non esiste nella Regione dello stack. Per risolvere il problema, aggiungi al modello il parametro SecurityGroupIDs.

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 codifichi una risorsa o un nome della risorsa Amazon (ARN) in una delle risorse dello stack per una risorsa esterna allo stack di CloudFormation, verifica che:

  • Il nome della risorsa o l'ARN sia corretto.
  • La risorsa esista.
  • La risorsa esista nella stessa Regione AWS dello stack. Alcune risorse accettano proprietà in diverse Regioni o account.

Errore "Invalid template property or properties [XXXXXXXX]"

Se imposti la risorsa bucket sullo stesso livello della sezione Risorse nei modelli JSON e YAML, ricevi il seguente messaggio di errore:

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

Questo errore si verifica quando il validatore del modello CloudFormation identifica la risorsa bucket come specifica a livello di sezione. Una specifica a livello di sezione non è consentita come proprietà del modello. È consigliabile utilizzare solo le proprietà del modello consentite nel modello CloudFormation.

Per risolvere il problema, specifica la risorsa bucket nella sezione Risorse.

Esempio per JSON:

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

Nota: sostituisci BucketName con il nome del tuo bucket.

Esempio per YAML:

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

Nota: sostituisci BucketName con il nome del tuo bucket.

Errore "Invalid policy syntax" o "MalformedPolicy"

Quando crei una policy basata sull'identità, una policy basata sulle risorse, una policy di controllo dei servizi o una policy di controllo delle risorse, la convalida viene suddivisa in due fasi. La procedura include la convalida di AWS Identity and Access Management (AWS IAM) e la convalida di CloudFormation.

Per convalidare la policy, creala ed esegui questo comando AWS CLI validate-policy:

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

Nota: sostituisci policy-document.json con il percorso del tuo file JSON.

Se esegui il comando AWS CLI validate-policy, ricevi il messaggio di errore "Invalid policy syntax" o "MalformedPolicy". Per risolvere il problema, cambia l'Azione in s3:DeleteObject ed esegui nuovamente il comando.

Esempio per JSON:

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

Nota: sostituisci BUCKET_NAME con il nome del tuo bucket.

Aggiungi la policy convalidata al modello CloudFormation e specifica parametri o risorse.

Se la sottofunzione fa riferimento a un parametro che non è presente nel modello, ricevi il seguente messaggio di errore:

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

Per risolvere il problema, aggiorna la Risorsa inserendo arn:aws:s3:::${BucketName}/* nel modello.

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

Nota: sostituisci BucketName con il nome del tuo bucket.

Verifica manualmente la sintassi della policy per le risorse relative alla policy IAM

Per verificare manualmente la validità della policy, utilizza il seguente modello di policy:

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

Nota: sostituisci service con il nome del tuo servizio e API_action con l'azione API per il servizio selezionato. Per ulteriori informazioni, consulta Documentazione di riferimento degli elementi delle policy JSON IAM.

Integra il documento di policy JSON con un modello in formato YAML

Se integri un documento di policy JSON con un modello in formato YAML per il provisioning di CloudFormation, puoi modificare la modalità di visualizzazione del documento nel modello. Questo evita blocchi misti YAML e JSON. Dopo l'integrazione, gli elementi della policy sono simili al seguente esempio di modello:

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

Nota: sostituisci IamPolicyName con il nome della tua policy IAM.