如何解决SAM模板中AWS::Include转换失败提示S3对象内容需为有效Yaml/JSON的问题
报错根因拆解
你部署时触发的报错为:
Transform AWS::Include failed with: The specified S3 object's content should be valid Yaml/JSON
本质是两个机制的不匹配导致的:
AWS::Include转换的核心逻辑是通过通用标准YAML/JSON解析器读取目标文件的内容,完全不识别CloudFormation定义的!Sub、!Ref这类短标签格式的内部函数- 你在独立的
open-api.yml文件里直接写入带!Sub标记的配置时,整个文件已经不是通用YAML规范认可的合法内容了——YAML解析器遇到没有预先注册的自定义标签!Sub时,会直接判定文件格式非法,最终触发Include的解析失败。
可落地的修复方案
- 第一步:把独立
open-api.yml文件里所有的CloudFormation短标签、内部函数全部移除,把需要动态拼接的参数位置替换成纯文本的自定义占位符,确保文件是完全符合通用YAML规范的纯结构定义,能被常规YAML解析器正常读取。 对应之前的API Gateway扩展配置部分,修改后示例:
这里用纯文本形式的x-amazon-apigateway-integration: uri: '${LambdaIntegrationUri}' responses: default: statusCode: "200" passthroughBehavior: "when_no_templates" httpMethod: "GET" type: "aws_proxy"${LambdaIntegrationUri}作为占位符,没有任何自定义标签,完全符合标准YAML格式。 - 第二步:调整主模板里
DefinitionBody的结构,把AWS::Include拉取到的纯OpenAPI结构作为Fn::Sub的传入对象,在主模板侧完成动态参数的拼接和占位符替换。修改后的主模板示例:MyApi: Type: "AWS::Serverless::Api" Properties: StageName: 'dev' Domain: DomainName: 'mydomain.com' CertificateArn: 'my-arn' EndpointConfiguration: REGIONAL Route53: HostedZoneId: 'HOSTEDZONEID' BasePath: - /api DefinitionBody: Fn::Sub: - Fn::Transform: Name: 'AWS::Include' Parameters: Location: 'open-api.yml' - LambdaIntegrationUri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${FunctionName}/invocations' - 第三步:执行部署前走正常的
sam package流程,这个步骤会自动把本地关联的open-api.yml文件上传到部署用的S3桶,替换模板里的本地路径为对应的S3对象URI,避免后续出现Include找不到S3对象的报错。
额外避坑提示
- 不要指望在被
AWS::Include引用的独立文件里直接写CloudFormation内部函数,这个转换的执行时机早于主模板的函数求值阶段,根本不会处理被引入文件里的函数语法 - 独立OpenAPI文件里所有的自定义扩展、结构配置都要保持纯YAML格式,不能混入CloudFormation专属的语法标记
内容的提问来源于stack exchange,提问作者Alo
相关产品推荐
相关产品推荐

