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

9 minuti di lettura
0

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

Breve descrizione

Scegli una delle seguenti soluzioni in base al messaggio di errore ricevuto:

  • Per gli errori "JSON not well-formed" o "YAML not well-formed", consulta la sezione Convalidare la sintassi del modello.
  • Per gli errori "Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template", consulta la sezione Convalidare i parametri e gli ID logici.
  • Per gli errori "Unrecognized parameter type: XXXXXXXX" o "Invalid template parameter property 'XXXXXXXX'", consulta la sezione Convalidare le definizioni dei parametri.
  • Per gli errori "Every Condition member must be a string", consulta la sezione Confermare che Condizioni sia specificato come stringa.
  • Per gli errori "Tipi di risorse non riconosciute: [XXXXXXXX]", consulta la sezione Verificare la disponibilità del proprio tipo di risorsa.
  • Per gli errori "[risorsa ambientale] 'XXXXXXXX' non esiste", consulta la sezione Verificare che la risorsa esista fuori dallo stack o convalidare le dipendenze per le risorse nello stesso stack.
  • Per gli errori "Invalid template property or properties [XXXXXXXX]", consulta la sezione Verificare le proprietà del modello.
  • Per gli errori "Invalid policy syntax" o "MalformedPolicy", consulta la sezione Verificare la sintassi della policy per tutte le risorse associate alla policy IAM.

Risoluzione

Se ricevi messaggi di errore durante l'esecuzione dei comandi dell'Interfaccia della linea di comando AWS (AWS CLI), consulta la pagina Troubleshoot AWS CLI errors. Inoltre, assicurati di utilizzare la versione più recente di AWS CLI.

Convalidare la sintassi del modello

Per seguire la sintassi JSON o YAML corretta nel tuo modello CloudFormation, considera quanto segue:

Convalidare i parametri e gli ID logici

Verifica che i parametri e gli ID logici della risorsa siano definiti nel tuo modello.

Nei seguenti modelli JSON e YAML, test fa riferimento alla proprietà ImageId. Tuttavia, nessuno dei modelli include un ID logico della risorsa né un parametro denominato test. Questi modelli restituiscono il seguente errore: "Unresolved resource dependencies [test] in the Resources block of the template". Per ulteriori informazioni sulle definizioni delle risorse e sulla loro sintassi, consulta la sezione Resources.

Esempio JSON (errato):

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

Esempio YAML (errato):

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

Per risolvere questo problema, aggiungi un ID logico della risorsa denominato test. In alternativa, crea un parametro denominato test in cui il riferimento restituisca il valore ImageId. I modelli JSON e YAML nell'esempio seguente includono un parametro con il nome test e ImageId come valore.

Esempio JSON (corretto):

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

Esempio YAML (corretto):

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

Convalidare le definizioni dei parametri

  1. Imposta Tipo su una delle seguenti proprietà supportate:
  2. Nel tuo modello CloudFormation verifica che i parametri includano solo le seguenti proprietà consentite. Per ulteriori informazioni sulle proprietà consentite, consulta la sezione Properties.
  3. Nel tuo modello CloudFormation conferma che la sezione Parametri non contenga funzioni intrinseche.

Nei modelli JSON e YAML dell'esempio seguente, il valore predefinito per ParameterC ha la funzione intrinseca Fn::Sub. Questa funzione intrinseca causa l'errore di convalida: "Every Default member must be a string".

Esempio JSON (errato):

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

Esempio YAML (errato):

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

Confermare che Condizioni sia specificato come stringa

Nel tuo modello CloudFormation, specifica Condizioni come una stringa.

I modelli JSON e YAML nell'esempio seguente specificano la condizione nella risorsa EC2RouteA come un elenco di stringhe anziché una stringa singola. Questi modelli generano il seguente errore di convalida: "Every Condition member must be a string".

Esempio JSON (errato):

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

Esempio YAML (errato):

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

Per risolvere questo errore, aggiungi ConditionAandB alla sezione Condizioni del tuo modello, quindi usa ConditionAandB come condizione per la risorsa EC2RouteA. Consulta i modelli JSON e YAML nell'esempio seguente.

Esempio JSON (corretto):

{
  "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 YAML (corretto):

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:

Verificare la disponibilità del tipo di risorsa

1. Verifica che la risorsa sia disponibile nella tua Regione AWS.

Non tutti i tipi di risorse sono disponibili in tutte le Regioni AWS. I modelli che includono tipi di risorse che non sono disponibili nella tua Regione AWS generano il seguente errore: "Tipi di risorse non riconosciute: [XXXXXXXX]".

2. Se il modello è costituito da risorse serverless, includi una dichiarazione Transform. Consulta i modelli JSON e YAML nell'esempio seguente.

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

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

Verificare che la risorsa esista fuori dallo stack o convalidare le dipendenze per le risorse nello stesso stack

Se stai codificando una risorsa o il nome della risorsa Amazon (ARN) in una delle risorse del tuo 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. Considera che alcune risorse accettano proprietà in vari account e Regioni AWS.

Ad esempio, una risorsa AWS::EC2::Instance nel tuo stack che specifica un gruppo di sicurezza (sg-1234567890) ha esito negativo se:

  • Il gruppo di sicurezza non esiste.
  • Il gruppo di sicurezza non esiste nella Regione AWS dello stack.

Di conseguenza, riceverai il messaggio di errore: "The sg-1234567890 does not exist". Considera l'esempio seguente:

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

Verificare le proprietà del modello

Utilizza solo le proprietà del modello consentite nel tuo modello CloudFormation.

I modelli JSON e YAML nell'esempio seguente impostano la risorsa del bucket allo stesso livello della sezione Risorse. Ciò restituisce il seguente errore: "Template validation error: Invalid template property or properties [Bucket]." Questo errore si verifica quando il validatore del modello CloudFormation considera la risorsa del bucket come una specifica a livello di sezione. Una specifica a livello di sezione non è consentita come proprietà del modello.

Esempio JSON (errato):

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

Esempio YAML (errato):

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

Per risolvere questo problema, correggi la formattazione in modo che la risorsa del bucket sia specificata all'interno della sezione Risorse. Consulta l'esempio seguente con i modelli JSON e YAML formattati correttamente.

Esempio JSON (corretto):

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

Esempio YAML (corretto):

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

Verificare la sintassi della policy per tutte le risorse associate alla policy IAM

Se stai creando una risorsa per una policy IAM (Identity and Access Management) o una configurazione correlata nelle proprietà della risorsa, verifica che la policy sia valida con questa struttura di base.

{  
    "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 un nome del servizio a tua scelta. Sostituisci <APIaction> con l'azione API per il servizio selezionato. Per ulteriori informazioni, consulta la sezione IAM JSON policy.

Integrare il documento della policy JSON con un formato YAML

Potrebbe essere necessario integrare un documento della policy JSON con un modello in formato YAML per il provisioning di CloudFormation. Ciò richiede di modificare la modalità in cui si presenta il documento nel modello.

Dopo l'integrazione, gli elementi della policy saranno simili a quelli mostrati di seguito:

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 UFFICIALE
AWS UFFICIALEAggiornata 2 mesi fa