AWS CloudFormation包括对许多本征函数的支持,这些值只能在运行时堆栈中可用的值上操作。这些函数包括Split
、Join
和Ref
。
在JSON中编写模板时,这些函数被表示为键值对,其中键是Ref
、Fn::Split
或Fn::Join
。值取决于所使用的函数,可能是字符串、数组等。
在YAML中编写模板时,有一些简短的表单可用于这些函数,如!Ref
、!Split
和!Join
。它们利用了YAML的一部分自定义标记功能,它允许在YAML文档中定义本机类型之外的新类型(字符串、数字、null等)。
是否可以使用CloudFormation 模板宏创建包含其他用户定义的自定义标记的YAML模板?例如,模板是否包括由宏处理到SOME-STRING
中的SOME-STRING
发布于 2022-07-31 20:10:53
不,即使在使用模板宏时,也不可能使用额外的自定义标记创建YAML模板。
可以安全地假设CloudFormation的本机模板格式是JSON,而且在服务对其进行任何实际工作之前,YAML模板总是被转换为JSON。模板宏也是如此。宏的Lambda函数接收的fragment
数据将始终是一个类似JSON的对象,即使模板是用YAML编写的。
例如,如果一个模板包含Value: !Ref MyResource
(它使用Ref
内禀函数的简短形式),则宏Lambda函数将接收"Value": { "Ref": "Foo" }
。对于模板中存在的任何YAML短格式语法,这都是正确的。在传递给宏之前,简短的语法被扩展为对JSON友好的长表单语法。
如果模板中存在任何未知的YAML标记,则解析YAML模板的CloudFormation服务部分将返回错误,即使模板是由宏转换的。它不会一般地尝试将它们扩展到长形式语法。因此,!Uppercase
会在CloudFormation的模板处理链中很早就导致一个错误。
此外,如果存在任何未知的内部函数,模板解析器也将返回一个错误(也就是说,类似于本机固有函数的内容)。例如,在宏处理模板之前,包括"Value": { "Fn::Uppercase": "Foo" }
将返回一个Encountered unsupported function
错误。似乎以Fn::
开头的JSON键是由CloudFormation专门处理的。
不过,有几种方法可以使用模板宏来模拟内部函数。
本机Ref
内部函数需要一个字符串值,可以创建自定义的伪参数,然后由模板宏进行处理和替换。例如,可以使用宏来支持像!Ref AcmeCo::Timestamp
这样的伪参数,类似于本机!Ref AWS::AccountId
。正如预期的那样,当传递到Lambda函数时,它将被扩展到{ "Ref": "AcmeCo::Timestamp" }
,但是函数将有机会找到这个伪参数,并将其替换为一些静态值(在本例中是一个时间戳)。不需要定制伪参数遵循Namespace::ParameterName
格式,但您需要确保您引入的任何自定义伪参数都不可能与可能传递给Ref
的实际资源逻辑ID发生冲突。
也可以创建类似于内部函数的东西,只要它们不是从Fn::
开始。例如,您可以将Join
函数重新实现为AcmeFn::Join
,或者创建类似于AcmeFn::Uppercase
的新函数。它们将以一种可以处理的方式将其转化为宏Lambda函数。但是,重要的是要记住,宏函数从未接收或访问其他函数的运行时值,因此,虽然可以执行Value: { "AcmeFm::Uppercase": "hello world" }
并将宏转换为Value: "HELLO WORLD"
,但不可能执行Value: { "AcmeFm::Uppercase": !Ref MyS3Bucket }
,并将其解析为某些S3桶的上界名称。由宏转换或操作的任何数据或值都必须将直接作为文字值传递到宏中。同样重要的是要记住,这些自定义函数总是需要使用长形式语法,因为不允许使用自定义YAML标记。
https://stackoverflow.com/questions/73186586
复制相似问题