在本学习练习中,除了PyPlate,我想使用BucketA
脚本提供BucketB
,BucketC
和TestBucket
存储桶。
想象一下,此模板的用户可以设置BucketNames参数,例如,该用户将使用UUID指定一百个存储桶名称。
AWSTemplateFormatVersion: "2010-09-09"
Transform: [PyPlate]
Description: A stack that provisions a bunch of s3 buckets based on param names
Parameters:
BucketNames:
Type: CommaDelimitedList
Description: All bucket names that should be created
Default: BucketA,BucketB,BucketC
Resources:
TestBucket:
Type: "AWS::S3::Bucket"
#!PyPlate
output = []
bucket_names = params['BucketNames']
for name in bucket_names:
output.append('"' + name + '": {"Type": "AWS::S3::Bucket"}')
以上在部署时以Template format error: YAML not well-formed. (line 15, column 3)
响应
尽管公认的答案在功能上是正确的,但是有更好的方法来解决此问题。本质上,PyPlate代码以递归方式读取堆栈中的所有键值对,并将其值替换为其Python计算值(即,它们与#!PyPlate
正则表达式匹配)。因此,我们需要一个与PyPlate代码相对应的密钥。
这是PyPlate和Explode的组合将如何解决上述问题。
AWSTemplateFormatVersion: "2010-09-09"
Transform: [PyPlate, Explode]
Description: A stack that provisions a bunch of s3 buckets based on param names
Parameters:
BucketNames:
Type: CommaDelimitedList
Description: All bucket names that should be created
Default: BucketA,BucketB,BucketC
Mappings: {}
Resources:
MacroWrapper:
ExplodeMap: |
#!PyPlate
param = "BucketNames"
mapNamespace = param + "Map"
template["Mappings"][mapNamespace] = {}
for bucket in params[param]:
template["Mappings"][mapNamespace][bucket] = {
"ResourceName": bucket
}
output = mapNamespace
Type: "AWS::S3::Bucket"
TestBucket:
Type: "AWS::S3::Bucket"
此方法之所以强大,是因为:
Resources
块Mappings
。您可以在Cloudformation中驱动动态逻辑。请注意通过-PyPlate进行的宏命令,在爆炸之前需要执行PyPlate,这就是为什么命令[PyPlate, Explode]
。执行是顺序的。
如果我们遍历PyPlate的源代码,它将为我们提供更多与模板相关的变量的控制权,即
在这种情况下,我使用了template
变量。
希望这会有所帮助
这对我有用:
AWSTemplateFormatVersion: "2010-09-09"
Transform: [PyPlate]
Description: A stack that provisions a bunch of s3 buckets based on param names
Parameters:
BucketNames:
Type: CommaDelimitedList
Description: All bucket names that should be created
Default: BucketA,BucketB,BucketC
Resources:
|
#!PyPlate
output = {}
bucket_names = params['BucketNames']
for name in bucket_names:
output[name] = {"Type": "AWS::S3::Bucket"}
说明:
Python代码输出一个dict
对象,其中键是存储桶名称,值是其配置:
{'BucketA': {'Type': 'AWS::S3::Bucket'}, 'BucketB': {'Type': 'AWS::S3::Bucket'}}
在执行宏之前,YAML模板已转换为JSON格式,并且由于以上是有效的JSON数据,我可以将其作为Resources
的值插入。
((请注意,使用硬编码的TestBucket
对此无效,我必须将其删除)