如何解决 CloudFormation 中的模板验证或模板格式错误?
我想验证 AWS CloudFormation 模板以确保没有语法错误。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
根据您收到的错误消息完成以下任务。
"JSON not well-formed" 或 "YAML not well-formed" 错误
如果您未正确格式化 CloudFormation 模板,则会收到以下错误消息之一:
"JSON not well-formed"
"YAML not well-formed"
请务必遵循 CloudFormation 模板中的 JSON 或 YAML 语法最佳实践。要解决此错误,请执行以下操作:
- 使用基础架构编辑器创建堆栈。
- 使用 AWS CLI 命令 validate-template 验证 JSON 和 YAML 语法。
- 要使用 AWS CloudFormation linter 验证 JSON 或 YAML 模板,请参阅 GitHub 网站上的 cfn-lint。
"Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template" 错误
如果您的 CloudFormation 模板未指定资源逻辑 ID 或参数,则会收到以下错误消息:
"Unresolved resource dependencies [test] in the Resources block of the template."。
要解决此错误,请指定资源逻辑 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
"Unrecognized parameter type: XXXXXXXX" 或 "Invalid template parameter property 'XXXXXXXX'" 错误
如果您的 JSON 和 YAML 模板将 ParameterC 的默认值作为内置函数 Fn::Sub 包含在内,则会收到以下错误消息:
"Every Default member must be a string."
参数不支持内置函数。使用 Fn::Sub 函数指定 ParameterA 和 ParameterB 的值。要解决此错误,请移除 ParameterC。
要移除 CloudFormation 模板中的 ParameterC,请完成以下步骤:
JSON 示例:
{ "Parameters": { "ParameterA": { "Type": "String", "Default": "abc" }, "ParameterB": { "Type": "String", "Default": "def" } }, "Resources": { "MyS3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { "Fn::Sub": "${ParameterA}-${ParameterB}" } } } } }
YAML 示例:
Parameters: ParameterA: Type: String Default: abc ParameterB: Type: String Default: def Resources: MyS3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: !Sub ${ParameterA}-${ParameterB}
"Every Condition member must be a string" 错误
您的 JSON 和 YAML 模板可能将资源 EC2RouteA 中的条件指定为一系列字符串,而不是单个字符串。如果是,您会收到以下错误消息:
"Every Condition member must be a string."
要解决此错误,请将 ConditionAandB 添加到模板的条件部分。然后,使用 ConditionAandB 作为 EC2RouteA 资源的条件。
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:
"Unrecognized resource types: [XXXXXXXX]" 错误
并非所有资源类型在每个 AWS 区域都可用。如果您的模板包含在您的区域中不可用的资源类型,则会收到以下错误消息:
"Unrecognized resource types: [XXXXXXXX]."
要解决此错误,请验证您的资源是否在您的区域可用。如果您的模板包含任何无服务器资源,则应包含一个转换声明。
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" } } } }
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'
"The [environmental resource] 'XXXXXXXX' does not exist" 错误
如果堆栈中的 AWS::EC2::Instance 资源指定了安全组,您会收到以下错误消息:
"The sg-1234567890 does not exist."
如果安全组不存在或堆栈所在区域中不存在安全组,则堆栈将失败。要解决此错误,请将 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.>
如果您将资源或 Amazon 资源名称 (ARN) 硬编码为位于 CloudFormation 堆栈之外的堆栈资源,请验证以下内容:
- 资源名称或 ARN 正确无误。
- 该资源确实存在。
- 该资源与堆栈位于同一 区域中。某些资源接受跨区域或跨账户的属性。
"Invalid template property or properties [XXXXXXXX]" 错误
如果您将存储桶资源设置为与 JSON 和 YAML 模板中的资源部分相同的层级,则会收到以下错误消息:
"Template validation error: Invalid template property or properties [Bucket]."
当 CloudFormation 模板验证器将存储桶资源识别为部分层级规范时,就会出现此错误。不允许将部分层级规范作为模板属性。最佳做法是在 CloudFormation 模板中仅使用允许的模板属性。
要解决此错误,请在资源部分中指定存储桶资源。
JSON 示例:
{ "Resources": { "WaitCondition": { "Type": "AWS::CloudFormation::WaitCondition" }, "Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "Name": "BucketName" } } } }
**注意:**请将 BucketName 替换为您的存储桶名称。
YAML 示例:
Resources: WaitCondition: Type: 'AWS::CloudFormation::WaitCondition' Bucket: Type: 'AWS::S3::Bucket' Properties: Name: BucketName
**注意:**请将 BucketName 替换为您的存储桶名称。
"Invalid policy syntax" 或 "MalformedPolicy" 错误
当您创建身份策略、资源策略、服务控制策略或资源控制策略时,验证分为两个步骤。这些步骤包括 AWS Identity and Access Management (IAM) 验证和 CloudFormation 验证。
要验证策略,请创建您的策略,然后运行以下 AWS CLI 命令 validate-policy:
➜ aws accessanalyzer validate-policy --policy-document file://policy-document.json --policy-type IDENTITY_POLICY
**注意:**请将 policy-document.json 替换为 JSON 文件的文件路径。
如果您运行 AWS CLI 命令 validate-policy,则会收到 "Invalid policy syntax" 或 "MalformedPolicy" 错误消息。要解决此问题,请将操作更改为 s3:DeleteObject,然后再次运行该命令。
JSON 示例:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyObjectDeletionForAllExceptRolePrefix", "Effect": "Deny", "Action": [ "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:PutLifecycleConfiguration" ], "Resource": ["arn:aws:s3:::BUCKET_NAME/*"] } ] }
**注意:**请将 BUCKET_NAME 替换为您的存储桶名称。
将经过验证的策略添加到您的 CloudFormation 模板中,并指定参数或资源。
如果子函数引用的参数不在模板中,则会收到以下错误消息:
"An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [Bucket] in the Resources block of the template"
要解决此错误,请将模板中的资源更新为 arn:aws:s3:::${BucketName}/*。
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}/*" } ] } ] } } } } }
**注意:**请将 BucketName 替换为您的存储桶名称。
手动验证 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 替换为您的服务名称,并将 API_action 替换为适用于您所选服务的 API 操作。有关详细信息,请参阅 IAM JSON 策略元素参考。
将您的 JSON 策略文档与 YAML 格式模板集成
如果您将 JSON 策略文档与用于预置 CloudFormation 的 YAML 格式模板集成,则可以更改该文档在模板中的显示方式。这样可以避免 YAML 和 JSON 混合块。集成后,策略元素与以下示例模板类似:
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: <...>
**注意:**请将 IamPolicyName 替换为您的 IAM 策略名称。
- 语言
- 中文 (简体)

