如何解決 CloudFormation 中的範本驗證或範本格式錯誤?
我想要驗證我的 AWS CloudFormation 範本,以確保沒有語法錯誤。
簡短描述
根據您收到的錯誤訊息,選擇下列其中一個解決方案:
- 對於 "JSON not well-formed" 或 "YAML not well-formed" 錯誤,請參閱驗證範本語法部分。
- 對於 "Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template" 錯誤,請參閱驗證邏輯 ID 和參數部分。
- 對於 "Unrecognized parameter type: XXXXXXXX" 或 "Invalid template parameter property 'XXXXXXXX'" 錯誤,請參閱驗證參數定義部分。
- 對於 "Every Condition member must be a string" 錯誤,請參閱確認條件已指定為字串部分。
- 對於 "Unrecognized resource types: [XXXXXXXX]" 錯誤,請參閱驗證資源類型的可用性部分。
- 對於 "The [environmental resource] 'XXXXXXXX' does not exist" 錯誤,請參閱確認您的資源存在於堆疊之外,或驗證相同堆疊中資源的相依性部分。
- 對於 "Invalid template property or properties [XXXXXXXX]" 錯誤,請參閱驗證範本屬性部分。
- 對於 "Invalid policy syntax" or "MalformedPolicy" 錯誤,請參閱驗證任何 IAM 政策相關資源的政策語法部分。
解決方法
如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請參閱對 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。但是,範本既不包含資源邏輯 ID,也不包含名為 test 的參數。這些範本會傳回下列錯誤: "Unresolved resource dependencies [test] in the Resources block of the template" 如需有關資源定義及其語法的詳細資訊,請參閱資源。
範例 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
驗證參數定義
- 將 Type 設定為下列其中一個支援的屬性:
- String、Number、List 或 CommaDelimitedList
- AWS 特定的參數類型
- SSM 參數類型
- 在 CloudFormation 範本中,確認參數僅包含下列允許的屬性。如需有關允許屬性的詳細資訊,請參閱屬性。
- 在 CloudFormation 範本中,確認 Parameters 區段不包含任何內部函數。
在下列範例 JSON 和 YAML 範本中,ParameterC 的預設值具有內部函數 Fn::Sub。此內部函數會導致驗證錯誤: "Every Default member must be a string"
範例 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
確認將 Conditions 指定為字串
在 CloudFormation 範本中,將 Conditions 指定為字串。
在下列範例 JSON 和 YAML 範本中,資源 EC2RouteA 中的條件指定為字串清單,而不是單一字串。這些範本會導致下列驗證錯誤: "Every Condition member must be a string"
範例 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 區域中不可用資源類型的範本會導致下列錯誤: "Unrecognized resource types: [XXXXXXXX]"
2.如果您的範本包含任何無伺服器資源,則會包含 Transform 聲明。請參閱下列範例 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 區域不存在。
因此,您會收到錯誤訊息: "The sg-1234567890 does not exist" 請參閱下列範例:
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 區段處於相同層級。這將傳回下列錯誤: "Template validation error: Invalid template property or properties [Bucket]" 導致此錯誤的原因是 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
驗證任何 IAM 政策相關資源的政策語法
如果您要在資源屬性中建立 Identity and Access Management (IAM) 政策資源或相關組態,請確認此政策對於此結構基礎有效。
{ "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": "<...>" } } ] } } } } }
**注意:**將 <service> 取代為您選擇的服務名稱。將 <APIaction> 取代為您所選服務的 API 動作。如需詳細資訊,請參閱 IAM JSON 政策。
將 JSON 政策文件與 YAML 格式整合
您可能想要將 JSON 政策文件與 YAML 格式範本整合以佈建 CloudFormation。這需要您變更文件在範本中的顯示方式。
在整合後,政策元素看起來類似下圖所示:
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: <...>
相關內容
- 已提問 5 個月前lg...
- AWS 官方已更新 1 年前