I'm trying to edit a yaml file but when I write the new file the whole structure of the file is messed up.
Line breaks are wrong, some indentations are wrong as well and it even deletes some of my parameters for some reason. Here's an example:
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
Generator: "user"
Description: "CloudFormation blah blah"
Parameters:
VPCEndpointServiceServiceName:
Description: VPCEndpointServiceServiceName
Type: String
Mappings:
PrivateLink:
EndPoint:
EndPointName: test
EndPointVpcId: vpc-123
SecurityGroupIds: sg-123
SubnetId1: subnet-123
SubnetId2: subnet-123
Resources:
EC2VPCEndpoint:
Type: "AWS::EC2::VPCEndpoint"
Properties:
VpcEndpointType: "Interface"
VpcId: !FindInMap [PrivateLink, EndPoint, EndPointVpcId]
ServiceName: !Ref VPCEndpointServiceServiceName
SubnetIds:
- !FindInMap [PrivateLink, EndPoint, SubnetId1]
- !FindInMap [PrivateLink, EndPoint, SubnetId2]
PrivateDnsEnabled: false
SecurityGroupIds:
- !FindInMap [PrivateLink, EndPoint, SecurityGroupIds]
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
Generator: user
Description: CloudFormation blah blah
Parameters:
VPCEndpointServiceServiceName:
Description: VPCEndpointServiceServiceName
Type: String
Mappings:
PrivateLink:
EndPoint:
EndPointName: test
EndPointVpcId: vpc-123
SecurityGroupIds: sg-123
SubnetId1: subnet-123
SubnetId2: subnet-123
Resources:
EC2VPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
VpcId:
- PrivateLink
- EndPoint
- EndPointVpcId
ServiceName: VPCEndpointServiceServiceName
SubnetIds:
- - PrivateLink
- EndPoint
- SubnetId1
- - PrivateLink
- EndPoint
- SubnetId2
PrivateDnsEnabled: 'false'
SecurityGroupIds:
- - PrivateLink
- EndPoint
- SecurityGroupIds
What's really weird is that it also removes parameters like !FindInMap
and !Ref
.
Here's my function:
def editEndpointTemplate(endpoint_tempplate_path):
#read yaml file
with open(endpoint_tempplate_path) as file:
data = yaml.load(file, Loader=yaml.BaseLoader)
data['Mappings']['PrivateLink']['EndPoint']['EndPointName'] = "New Name"
#write yaml file and overwrite old one.
with open(endpoint_tempplate_path, 'w') as file:
yaml.dump(data, file, sort_keys=False)
I want to preserve the file exactly as it is because all I do is update a few keys.
I also had issues with the file being sorted alphabetically, but a simple sort_keys=False
fixed that. I figured any other of PyYaml
's attributes would solve this but couldn't figure it out.
Any help would be appreciated.
Found a workaround. Instead of using PyYaml
or cfn-tools
, I used ruamel.yaml
.
import sys
from ruamel.yaml import YAML
def editEndpointTemplate(endpoint_template_path):
yaml = YAML()
yaml.indent(mapping=3)
#Load yaml file
with open(endpoint_template_path) as fp:
data = yaml.load(fp)
#Change data
data['Mappings']['PrivateLink']['EndPoint']['EndPointName'] = service_name
#Dump it back to the same file
# yaml.dump(data, sys.stdout)
with open(endpoint_template_path, 'w') as fp:
yaml.dump(data, fp)
The new YAML file is preserved exactly like my template, even after editing.