如何使用pyplate宏提供大量资源

问题描述 投票:1回答:2

在本学习练习中,除了PyPlate,我想使用BucketA脚本提供BucketBBucketCTestBucket存储桶。

想象一下,此模板的用户可以设置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)响应

amazon-cloudformation
2个回答
1
投票

尽管公认的答案在功能上是正确的,但是有更好的方法来解决此问题。本质上,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"

此方法之所以强大,是因为:

  1. 您可以将资源附加到现有模板,因为您不会篡改整个Resources
  2. 您无需按照Explode的要求使用硬编码的Mappings。您可以在Cloudformation中驱动动态逻辑。
  3. 大多数Cloudformation道具/ KV保留在YAML部分中,并且最少的python部分可增强CFT功能。

请注意通过-PyPlate进行的宏命令,在爆炸之前需要执行PyPlate,这就是为什么命令[PyPlate, Explode]。执行是顺序的。

如果我们遍历PyPlate的源代码,它将为我们提供更多与模板相关的变量的控制权,即

  • 参数(堆栈参数)
  • 模板(整个模板)
  • account_id
  • 区域

在这种情况下,我使用了template变量。

希望这会有所帮助


1
投票

这对我有用:

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对此无效,我必须将其删除)

© www.soinside.com 2019 - 2024. All rights reserved.