如何解決 CloudFormation 中的範本驗證或範本格式錯誤?

上次更新日期:2021 年 6 月 25 日

我在嘗試建立 AWS CloudFormation 堆疊時收到一則錯誤訊息。

簡短描述

根據您收到的錯誤訊息選擇以下其中一項解決方案:

  • 針對「JSON 格式不正確」或「YAML 格式不正確」錯誤,請參閱驗證範本語法章節。
  • 針對「範本資源區塊中的資源相依性 [XXXXXXXX] 未解析」錯誤,請參閱驗證邏輯和實體 ID 章節。
  • 針對「無法識別的參數類型:XXXXXXXX」或「無效的範本參數屬性 'XXXXXXXX'」錯誤,請參閱驗證參數定義章節。
  • 針對「每個條件成員必須為字串」錯誤,請參閱確認條件已指定為字串章節。
  • 針對「無法識別的資源類型:[XXXXXXXX]」錯誤,請參閱驗證資源類型的可用性章節。
  • 針對「遇到不受支援的屬性 XXXXXXXX」錯誤,請參閱驗證屬性、值和值類型章節。
  • 針對「[環境資源] 'XXXXXXXX' 不存在」錯誤,請參閱驗證您的資源是否存在於堆疊之外,或驗證同一堆疊中資源的相依性章節。
  • 針對「必須定義至少一個資源成員」錯誤,請參閱在範本中包含「資源」區段章節。
  • 針對「無效的範本屬性或屬性 [XXXXXXXX]」錯誤,請參閱驗證範本屬性章節。

解決方案

注意:如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請確保您使用的是最新版 AWS CLI

驗證範本語法

若要在 CloudFormation 範本中遵循正確的 JSON 或 YAML 語法,請考慮以下事項:

驗證邏輯和實體 ID

1.    確認您的範本中定義了資源邏輯 ID。

2.    確認您的環境中存在資源實體 ID。

例如,以下 JSON 和 YAML 範本中的 ImageId 屬性參考了 test。兩個範本均不包含名稱為 test 的資源邏輯 ID 或參數。

以下 JSON 和 YAML 範本中未正確定義資源 ID。這些範本傳回以下錯誤:「範本資源區塊中的資源相依性 [測試] 未解析。」 如需了解資源定義及其語法的詳細資訊,請參閱資源

JSON︰

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

YAML︰

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

驗證參數定義

1.    僅將 Type (類型) 設定為下列屬性之一:StringNumberList<Number>CommaDelimitedList

注意:這些屬性包含 AWS 特定參數類型和 AWS Systems Manager Agent (SSM Agent) 參數類型。

2.    在您的 CloudFormation 範本中,驗證參數是否僅包含以下允許的屬性:

"Parameters" : {
  "ParameterName" : {
    "AllowedPattern" : "A regular expression that represents the patterns to allow for String types.",
    "AllowedValues" : "An array containing the list of values allowed for the parameter",
    "ConstraintDescription" : "A string that explains a constraint when the constraint is violated"
    "Default" : "A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints",
    "Description" : "A string of up to 4000 characters that describes the parameter",
    "MaxLength" : "An integer value that determines the largest number of characters you want to allow for String types",
    "MaxValue" : "A numeric value that determines the largest numeric value you want to allow for Number types.",
    "MinLength" : "An integer value that determines the smallest number of characters you want to allow for String types.",
    "MinValue" : "A numeric value that determines the smallest numeric value you want to allow for Number types.",
    "NoEcho" : "Whether to mask the parameter value when a call is made that describes the stack.
                 If you set the value to true, the parameter value is masked with asterisks (*****).",
    "Type" : "The data type for the parameter (DataType)."
 },

3.    在您的 CloudFormation 範本中,確認 Parameters (參數) 區段不含任何內部函數

例如,以下 JSON 和 YAML 範本中 ParameterC 的預設值具有內部函數 Fn::Sub。此內部函數會導致驗證錯誤:「每個預設成員均必須為字串。」

JSON︰

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

YAML︰

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

確認將條件指定為字串

在您的 CloudFormation 範本中,將 Conditions (條件) 指定為字串。

例如,資源 EC2RouteA 中的條件指定為字串清單,而不是以下範例 JSON 和 YAML 範本中的單一字串。這些範本會導致以下驗證錯誤:「每個預設成員均必須為字串。」

JSON︰

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

YAML︰

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

若要解決此錯誤,請將 ConditionAandB 新增至您的範本,然後使用 ConditionAandB 作為 EC2RouteA 資源的條件。請參閱以下範例 JSON 和 YAML 範本。

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

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:

驗證您的資源類型的可用性

1.    驗證您的資源在您的 AWS 區域中是否可用。

並非所有資源類型在每個 AWS 區域均可使用。例如,以下 JSON 和 YAML 範本中的資源類型 AWS::WAFRegional::IPSet 目前在 ap-south-1 中不可用。這些範本會導致以下錯誤:「無法識別的資源類型:[XXXXXXXX]。」

JSON︰

{
  "IPSetlistA": {
    "Type": "AWS::WAFRegional::IPSet",
    "Properties": {
      "Name": "IPSet for IP addresses that are not allowed",
      "IPSetDescriptors": [
        {
          "Type": "IPV4",
          "Value": "x.x.x.x/x"
        },
        {
          "Type": "IPV4",
          "Value": "x.x.x.x/x"
        }
      ]
    }
  }
}

YAML︰

IPSetlistA:
 Type: 'AWS::WAFRegional::IPSet'
 Properties:
  Name: IPSet for IP addresses that are not allowed
  IPSetDescriptors:
   - Type: IPV4
    Value: x.x.x.x/x
   - Type: IPV4
    Value: x.x.x.x/x

注意:CloudFormation 範本使用符合 JSON 或 YAML 標準的格式以文字檔案存放。上述 JSON 和 YAML 範本使用相同的範本,但格式不同。如需 YAML 支援的詳細資訊,請參閱了解範本基礎知識AWS CloudFormation 更新 – YAML、跨堆疊參考、簡化替換

2.    如果您的範本包含任何無伺服器資源,則會包含轉換聲明。請參閱以下 JSON 和 YAML 範例。

JSON︰

{
    "Transform": "AWS::Serverless-2016-10-31",
    "Resources": {
        "MyServerlessFunctionLogicalID": {
            "Type": "AWS::Serverless::Function",
            "Properties": {
                "Handler": "index.handler",
                "Runtime": "nodejs8.10",
                "CodeUri": "s3://testBucket/mySourceCode.zip"
            }
        }
    }
}

YAML︰

Transform: AWS::Serverless-2016-10-31
Resources:
  MyServerlessFunctionLogicalID:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://testBucket/mySourceCode.zip'

驗證屬性、值和值類型

在範本區段和資源定義中使用有效的屬性、值和值類型

驗證您的資源是否存在於堆疊之外,或驗證同一堆疊中資源的相依性

如果您針對存在於 CloudFormation 堆疊之外的資源,對資源或 Amazon 資源名稱 (ARN) 硬編碼至您的其中一個堆疊資源,請驗證以下內容:

  • 資源名稱或 ARN 正確無誤。
  • 資源已存在。
  • 資源與堆疊位於同一 AWS 區域。考慮到某些資源接受跨 AWS 區域或帳戶的屬性。

例如,如果在指定安全群組 (sg-1234567890) 的堆疊中,AWS::EC2::Instance 資源的安全群組不存在或不存在於堆疊的 AWS 區域中,則 AWS::EC2::Instance 資源會失敗。您會收到以下錯誤訊息:「sg-1234567890 不存在。」 請參閱以下範例:

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

在您的範本中包含「資源」區段

您必須在 CloudFormation 範本中包含 Resources (資源) 區段,否則會收到錯誤訊息。

驗證範本屬性

在您的 CloudFormation 範本中僅使用允許的範本屬性

在以下 JSON 和 YAML 範例中,儲存貯體資源與 Resources (資源) 區段處於同一級別。這將傳回以下錯誤:「範本驗證錯誤:無效的範本屬性或屬性 [儲存貯體]。」 導致該錯誤的原因是 CloudFormation 範本驗證程式將儲存貯體資源視為區段級規範,而不允許將其作為範本屬性。

JSON︰

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

YAML︰

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

注意:在上述 JSON 和 YAML 範本中,將 BucketName 替換為您的儲存貯體名稱。


此文章是否有幫助?


您是否需要帳單或技術支援?