使用 Python 加载 CloudFormation YAML

Loading CloudFormation YAML using Python

我有一组 YAML AWS Cloud Formation 模板,我最近从 JSON 转换而来。

当使用 JSON 时,我能够加载这些模板并使用 jinja 转换它们以从中生成一些降价文档。我正在尝试对 python.

中的 YAML 做同样的事情

我在使用 YAML 标签的 cloudformation 模板中使用 shorthand 函数语法。例如

Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize

当尝试使用 ruamel.yaml 包加载这些时,构造函数失败,因为它无法处理标签,因为它不知道它们。

有什么方法可以解决这个问题,以便我能够加载 YAML 文档,以便 retrieve/query 输出和资源?

您误认为 ruamel.yaml 无法处理标签。但是当然你必须提供关于如何处理任何未知标签的信息,它无法猜测你想要加载什么样的数据 !Ref:

import ruamel.yaml

yaml_str = """\
Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize
"""


class Blob(object):
    def update(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)


def my_constructor(self, node):
    data = Blob()
    yield data
    value = self.construct_scalar(node)
    data.update(value)

ruamel.yaml.SafeLoader.add_constructor(u'!Ref', my_constructor)

data = ruamel.yaml.safe_load(yaml_str)
print('data', data['Properties']['MinSize'])

打印:

ClusterSize

如果你想摆脱许多不同的标签,而不关心 "everything being a string" 你也可以这样做:

import ruamel.yaml

yaml_str = """\
Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize
  SizeList:
     - !abc 1
     - !xyz 3
"""


def general_constructor(loader, tag_suffix, node):
    return node.value


ruamel.yaml.SafeLoader.add_multi_constructor(u'!', general_constructor)


data = ruamel.yaml.safe_load(yaml_str)
print(data)

给出:

{'Properties': {'SizeList': ['1', '3'], 'MinSize': 'ClusterSize', 'MaxSize': 'ClusterSize'}}

(请注意标量 13 被加载为字符串而不是普通整数)