boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
8.87k stars 1.85k forks source link

cloudformation.get_template() returns string for TemplateBody #1468

Open stanchanpsu opened 6 years ago

stanchanpsu commented 6 years ago

The cloudformation client's get_template() method returns a string for the TemplateBody even though the documentation specified a dict:

TemplateBody (dict) --

Structure containing the template body. (For more information, go to Template Anatomy in the AWS CloudFormation User Guide.)

AWS CloudFormation returns the same template that was used when the stack was created.
import boto3 # version 1.6.0
cloudformation = boto3.client('cloudformation')
current_template = cloudformation.get_template(
    StackName=stack_name
)
type(current_template['TemplateBody'])
# Returns <str>

In addition, the string is not very helpful as the keys don't have quotes so the string can't even be evaluated into a dict with eval() or something similar.

It seems like a reversal of the issue documented here: https://github.com/boto/botocore/issues/1058

stealthycoin commented 6 years ago

boto3 tries to decode the string that was sent back by the service as JSON. If it fails the raw string is returned. Boto3 does not take a dependency on YAML right now so if you used YAML to upload the template in the first place it will give you a string back when you get it. If we changed this it could be breaking since people could be relying on the current behavior.

eval() is not something you would be able to do to it anyway, if you what a dict you need to pull in a YAML parser and feed it the string you got back.

If you are interested in this feature request I would suggest you go thumbs up #1237 which is where we are currently tracking this. I am closing this one in favor of the #1237.

stanchanpsu commented 6 years ago

@stealthycoin , thank you for the prompt response. Could the documentation of boto3 be updated, at least, to explicitly call out this implementation? It's very confusing.

stealthycoin commented 6 years ago

Yea that seems like a good idea. It does just say dict. I'll change this to a documentation issue for tracking. Be sure to add a thumbs up to #1237 if you want that feature.

stanchanpsu commented 6 years ago

@stealthycoin Do you or your team have any examples on how to parse this stringified yaml TemplateBody in python? I am trying to use PyYaml and I get

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!Equals'
  in "<string>", line 3, column 24:
      CreateSecretsBucket: !Equals [ !Ref

It seems like the python yaml parser is not able to handle the AWS !Function short form syntax.

mikegrima commented 5 years ago

It seems like PyYAML 5.1 has issues with some of the CloudFormation YAML syntax. It's currently breaking moto's tests.