Mat*_*ton 7 aws-cloudformation ruamel.yaml
这与问题/ 44786412非常相似,但我的似乎是由YAML safe_load()触发的.我正在使用Ruamel的库和YamlReader将一堆CloudFormation部分粘合到一个合并的模板中.砰砰声是不是正确的YAML?
Outputs:
Vpc:
Value: !Ref vpc
Export:
Name: !Sub "${AWS::StackName}-Vpc"
Run Code Online (Sandbox Code Playgroud)
没问题
Outputs:
Vpc:
Value:
Ref: vpc
Export:
Name:
Fn::Sub: "${AWS::StackName}-Vpc"
Resources:
vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock:
Fn::FindInMap: [ CidrBlock, !Ref "AWS::Region", Vpc ]
Run Code Online (Sandbox Code Playgroud)
第2部分; 如何让load()单独留下'Fn :: Select:'的权利.
FromPort:
Fn::Select: [ 0, Fn::FindInMap: [ Service, https, Ports ] ]
Run Code Online (Sandbox Code Playgroud)
转换成这个,现在CF不喜欢.
FromPort:
Fn::Select: [0, {Fn::FindInMap: [Service, https, Ports]}]
Run Code Online (Sandbox Code Playgroud)
如果我完全展开声明,那么没有问题.我想速记只是有问题的.
FromPort:
Fn::Select:
- 0
- Fn::FindInMap: [Service, ssh, Ports]
Run Code Online (Sandbox Code Playgroud)
您的“爆炸符号”是正确的YAML,通常称为标记。如果要与一起使用,则safe_load()必须为!Ref和!Sub标记提供构造函数,例如,使用:
ruamel.yaml.add_constructor(u'!Ref', your_ref_constructor, constructor=ruamel.yaml.SafeConstructor)
Run Code Online (Sandbox Code Playgroud)
对于两个标签,您应该期望在哪里处理标量值。而不是更常见的映射。
我建议您使用RoundTripLoader代替SafeLoader,也可以保留顺序,注释等。该RoundTripLoader是的一个子类SafeLoader。
如果您使用的是支持往返标量的ruamel.yaml> = 0.15.33,则可以这样做(使用新的ruamel.yaml API):
import sys
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
data = yaml.load("""\
Outputs:
Vpc:
Value: !Ref: vpc # first tag
Export:
Name: !Sub "${AWS::StackName}-Vpc" # second tag
""")
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)
要得到:
Outputs:
Vpc:
Value: !Ref: vpc # first tag
Export:
Name: !Sub "${AWS::StackName}-Vpc" # second tag
Run Code Online (Sandbox Code Playgroud)
在较旧的0.15.X版本中,您必须自己指定标量对象的类。如果您有许多对象,那么会很麻烦,但是它允许其他功能:
import sys
from ruamel.yaml import YAML
class Ref:
yaml_tag = u'!Ref:'
def __init__(self, value, style=None):
self.value = value
self.style = style
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(cls.yaml_tag,
u'{.value}'.format(node), node.style)
@classmethod
def from_yaml(cls, constructor, node):
return cls(node.value, node.style)
def __iadd__(self, v):
self.value += str(v)
return self
class Sub:
yaml_tag = u'!Sub'
def __init__(self, value, style=None):
self.value = value
self.style = style
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_scalar(cls.yaml_tag,
u'{.value}'.format(node), node.style)
@classmethod
def from_yaml(cls, constructor, node):
return cls(node.value, node.style)
yaml = YAML(typ='rt')
yaml.register_class(Ref)
yaml.register_class(Sub)
data = yaml.load("""\
Outputs:
Vpc:
Value: !Ref: vpc # first tag
Export:
Name: !Sub "${AWS::StackName}-Vpc" # second tag
""")
data['Outputs']['Vpc']['Value'] += '123'
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)
这使:
Outputs:
Vpc:
Value: !Ref: vpc123 # first tag
Export:
Name: !Sub "${AWS::StackName}-Vpc" # second tag
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6677 次 |
| 最近记录: |