AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
如何解决 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 策略名称。
- 语言
- 中文 (简体)

