Reputation: 3080
Hi I'm trying to create a Cloudformation template using Python. I'm using yaml
library to do so.
Here's my code:
import yaml
dict_file = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "ding dong",
"Parameters": {
"Environment":{
"Description": "Environment for Deployment",
"Type": "String"
}
},
"Resources":{
"Queue": {
"Type": "AWS::SQS::Queue",
"Properties":{
"DelaySeconds": 0,
"MaximumMessageSize": 262144,
"MessageRetentionPeriod": 1209600,
"QueueName": '!Sub "${Environment}-Queue"',
"ReceiveMessageWaitTimeSeconds": 0,
"VisibilityTimeout": 150
}
}
}
}
with open(r'TopicName.yml', 'w') as file:
documents = yaml.dump(dict_file, file, sort_keys=False)
The problem is with Cloudformation tags like !Sub
as you can see in the key "QueueName"
. The !Sub
needs to be outside of quote in the resulting yaml. The resulting yaml this gives looks like this QueueName: '!Sub "${LSQRegion}-TelephonyLogCall-Distributor"'
How do I fix this? Any idea? Pleas help!!
Upvotes: 0
Views: 1690
Reputation: 1311
You could try troposphere library too. It supports all the AWS services (which are supported by AWS CloudFormation) and really more pythonic to create CloudFormation template in Python.
I have pasted troposphere code for your CloudFormation template. You can try it out too:
from troposphere import Template, Parameter, Sub
from troposphere.sqs import Queue
def get_cfn_template():
template = Template()
template.set_version("2010-09-09")
template.set_description("ding dong")
template.add_parameter(Parameter(
"Environment",
Type="String",
Description="Environment for Deployment"
))
template.add_resource(
Queue(
'Queue',
DelaySeconds=0,
MaximumMessageSize=262144,
MessageRetentionPeriod=1209600,
QueueName=Sub("${Environment}-Queue"),
ReceiveMessageWaitTimeSeconds=0,
VisibilityTimeout=150
)
)
return template.to_json()
print get_cfn_template()
Output
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "ding dong",
"Parameters": {
"Environment": {
"Description": "Environment for Deployment",
"Type": "String"
}
},
"Resources": {
"Queue": {
"Properties": {
"DelaySeconds": 0,
"MaximumMessageSize": 262144,
"MessageRetentionPeriod": 1209600,
"QueueName": {
"Fn::Sub": "${Environment}-Queue"
},
"ReceiveMessageWaitTimeSeconds": 0,
"VisibilityTimeout": 150
},
"Type": "AWS::SQS::Queue"
}
}
}
Troposphere can convert your code to YAML too.
Upvotes: 1
Reputation: 311713
In YAML, an unquoted value beginning with !
represents a custom type. You're never going to be able to generate that with yaml.dump
from a simple string value. You're going to need to create a custom class and an associated representer to get the output you want. For example:
import yaml
class Sub(object):
def __init__(self, content):
self.content = content
@classmethod
def representer(cls, dumper, data):
return dumper.represent_scalar('!Sub', data.content)
dict_file = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "ding dong",
"Parameters": {
"Environment": {
"Description": "Environment for Deployment",
"Type": "String"
}
},
"Resources": {
"Queue": {
"Type": "AWS::SQS::Queue",
"Properties": {
"DelaySeconds": 0,
"MaximumMessageSize": 262144,
"MessageRetentionPeriod": 1209600,
"QueueName": Sub("${Environment}-Queue"),
"ReceiveMessageWaitTimeSeconds": 0,
"VisibilityTimeout": 150,
},
}
},
}
yaml.add_representer(Sub, Sub.representer)
print(yaml.dump(dict_file))
This will output:
AWSTemplateFormatVersion: '2010-09-09'
Description: ding dong
Parameters:
Environment:
Description: Environment for Deployment
Type: String
Resources:
Queue:
Properties:
DelaySeconds: 0
MaximumMessageSize: 262144
MessageRetentionPeriod: 1209600
QueueName: !Sub '${Environment}-Queue'
ReceiveMessageWaitTimeSeconds: 0
VisibilityTimeout: 150
Type: AWS::SQS::Queue
Upvotes: 3