如何解決 CloudFormation 中的範本驗證或範本格式錯誤?
我在嘗試建立 AWS CloudFormation 堆疊時收到一則錯誤訊息。
簡短描述
根據您收到的錯誤訊息選擇以下其中一項解決方案:
- 針對「JSON 格式不正確」或「YAML 格式不正確」錯誤,請參閱驗證範本語法章節。
- 針對「範本資源區塊中的資源相依性 [XXXXXXXX] 未解析」錯誤,請參閱驗證邏輯 ID 和參數章節。
- 針對「無法識別的參數類型:XXXXXXXX」或「無效的範本參數屬性 'XXXXXXXX'」錯誤,請參閱驗證參數定義章節。
- 針對「每個條件成員必須為字串」錯誤,請參閱確認條件已指定為字串章節。
- 針對「無法識別的資源類型:[XXXXXXXX]」錯誤,請參閱驗證資源類型的可用性章節。
- 針對「[環境資源] 'XXXXXXXX' 不存在」錯誤,請參閱驗證您的資源是否存在於堆疊之外,或驗證同一堆疊中資源的相依性章節。
- 針對「無效的範本屬性或屬性 [XXXXXXXX]」錯誤,請參閱驗證範本屬性章節。
解決方案
**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請確保您使用的是最新版 AWS CLI。
驗證範本語法
若要在 CloudFormation 範本中遵循正確的 JSON 或 YAML 語法,請考慮以下事項:
- 使用 AWS CloudFormation Designer 建立您的堆疊。
- 使用文字編輯器或命令列工具 (如 AWS CLI 範本驗證程式) 來驗證您的 JSON 語法。
- 使用 aws cloudformation validate-template 命令來驗證您的 YAML 語法。
- 使用 GitHub 網站上的 AWS CloudFormation linter 來驗證您的 JSON 或 YAML 範本。
驗證邏輯 ID 和參數
確認您的範本中定義了資源邏輯 ID 和參數。
以下 JSON 和 YAML 範本中的 ImageId 屬性參考了 test。然而,兩個範本均不包含名稱為 test 的資源邏輯 ID 或參數。這些範本傳回以下錯誤:「範本資源區塊中的資源相依性 [測試] 未解析。」 如需了解資源定義及其語法的詳細資訊,請參閱資源。
範例 JSON (不正確):
{ "Resources" : { "EC2Instance01" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : {"Ref": "test"} } } } }
範例 YAML (不正確):
Resources: EC2Instance01: Type: AWS::EC2::Instance Properties: ImageId: !Ref test
若要解決此問題,請新增名稱為 test 的資源邏輯 ID。或者,建立一個名稱為 test 的參數,其中的參考會傳回 imageId 值。以下範例 JSON 和 YAML 範本額包含一個參數,其中包含名稱為 test 和 imageId 的參數作為值。
範例 JSON (正確):
{ "Parameters": { "test": { "Type": "String", "Default": "ami-xxx" } }, "Resources" : { "EC2Instance01" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : {"Ref": "test"} } } } }
範例 YAML (正確):
Parameters: test: Type: String Default: ami-xxx Resources: EC2Instance01: Type: 'AWS::EC2::Instance' Properties: ImageId: !Ref test
驗證參數定義
1. 將 Type 設定為以下其中一項支援的屬性:
- String、Number、List ,或 CommaDelimitedList
- AWS 特定的參數類型
- SSM 參數類型
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 (條件) 指定為字串。
在以下範例 JSON 和 YAML 範本中,資源 EC2RouteA 中的條件指定為字串清單,而不是單一字串。這些範本會導致以下驗證錯誤:「每個條件成員均必須為字串。」
範例 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 新增至您的範本的 Conditions (條件) 區段,然後使用 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 區域均可使用。包含 AWS 區域中不可用資源類型的範本會導致以下錯誤:「無法識別的資源類型:[XXXXXXXX]。」
2. 如果您的範本包含任何無伺服器資源,則會包含轉換聲明。請參閱以下範例 JSON 和 YAML 範本。
範例 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" } } } }
範例 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'
驗證您的資源是否存在於堆疊之外,或驗證同一堆疊中資源的相依性
如果您將資源或 Amazon Resource Name (ARN) 硬編碼至 CloudFormation 堆疊之外的其中一個堆疊資源,請驗證以下內容:
- 資源名稱或 ARN 正確無誤。
- 資源已存在。
- 資源與堆疊位於同一 AWS 區域。考慮到某些資源接受跨 AWS 區域或帳戶的屬性。
例如,您的堆疊中指定安全群組 (sg-1234567890) 的 AWS::EC2::Instance 的資源在以下情況下會失敗:
- 安全群組不存在。
- 安全群組在堆疊的 AWS 區域中不存在。
因此,您會收到錯誤訊息:「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 範本中僅使用允許的範本屬性。
在以下範例 JSON 和 YAML 範本中,儲存貯體資源與 Resources (資源) 區段處於同一級別。這將傳回以下錯誤:「範本驗證錯誤:無效的範本屬性或屬性 [儲存貯體]。」 導致此錯誤的原因是 CloudFormation 範本驗證程式將儲存貯體資源視為區段級規範。不允許將區段級規範作為範本屬性。
範例 JSON (不正確):
{ "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" } } }
範例 YAML (不正確):
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
若要解決此問題,請更正格式,以便在 Resources (資源) 區段內指定儲存貯體資源。請參閲以下正確格式化的範例 JSON 和 YAML 範本。
範例 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
相關內容
- 已提問 5 個月前lg...
- 已提問 4 個月前lg...
- 已提問 5 個月前lg...
- 已提問 5 個月前lg...
- 已提問 5 個月前lg...
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 8 個月前
- AWS 官方已更新 2 個月前