Can CloudFormation show me what the invalid value *is*?

I haven't been working with CloudFormation long, but I think I get the idea, mostly. But now I'm having an issue where I'm trying to build out different names for resources depending on whether they're in a production environment or not, and the conditional logic is a bit tricky in JSON or YAML. So I'm getting a lot of errors when I run

aws cloudformation validate-template

or when I try to deploy a stack through the console.

The errors vary greatly, so I'm not looking for help on any particular one, but they all have in common that some parameter or other has invalid characters or an invalid value. Fair enough: I'm working out a syntax that's new to me. But the error message never shows what the invalid value that CloudFormation received *is*, so I can't tell what I did wrong.

I've tried digging through CloudTrail and CloudWatch Logs to see if the bad value shows up there, and jumped back and forth all through the CF documentation, so far without success. This seems like such a basic troubleshooting thing that I can't believe it's not in there somewhere, so I feel like I must be overlooking something easy or simple.

Anyone know what I'm missing? Failing that, anyone know a way to render a template offline so you can capture the values passed?

Thanks in advance for any insight.

11 comments · 71% upvoted · other discussions

comments

almorelle

Yeah CF is a pain to debug. Best friends are cfn-lint, yamllint, cfn-nag. I've never really liked the cloudformation validate template command but it can help. Look at the parameters that were passed to your stack and "manually" debug it.

If you go as far as to create a stack changeset, it's a good practice but I would advice to wait until you figure out most of the issues you have before having such a step in your pipeline.

Edit: oh and I forgot you could also think about using stuff like troposphere to work on CF with real dev tools.

badoopbadoopbadoop

cfn-lint does a good job of pointing out value format issues.

https://github.com/aws-cloudformation/cfn-python-lint

daveidfx [OP]

Thanks for the reply. I left cfn-lint out of my OP by mistake. Whatever my current error is, it's skating past cfn-lint without any problem, too. And previous errors caught by cfn-lint have had the same problem - it'll tell me which value is wrong, but not what the value was.

[deleted]

Unfortunately validate-template just makes sure your JSON is valid :) super useful! Why bother validating my inputs/variable types

whtevn

the answer would depend on the service and where errors for that particular service go. debugging cloudformation can be a huge pain. maybe an example helps?

"Conditions" : {

"is_production" : { "Fn::Equals" : [ { "Ref" : "Environment" }, "production" ] },

}

...

{

Param: { "Fn::If": [

"is_production",

"example.com",

{ "Fn::Sub": "${Environment}.example.com"}

]}

},

daveidfx [OP]

Thanks for the reply. I intentionally left out any example code because my question isn't really about getting this current code to run, it's about how to get useful info out of CloudFormation (or logging!) when writing any future code.

But for what it's worth, the current hiccup is on creating a CloudFront CDN:

Conditions:
  ThisIsProd: !Equals [ !Ref Environment, "prod" ] 
... 
Resources: 
... 
  AppCDN: 
    Type: AWS::CloudFront::Distribution 
    Properties: 
      DistributionConfig: 
        Aliases: 
        - | 
          !If 
            - ThisIsProd 
            - !Sub "cdn.${!Ref AppDomain}" 
            - !Sub 
              - "cdn-${Env}.${Domain}" 
              - Env: !Ref Environment 
                Domain: !Ref AppDomain

At least, I assume that's the critical part. The latest error kicked back is:

The parameter CNAME contains one or more parameters that are not valid. (Service: AmazonCloudFront; Status Code: 400; Error Code: InvalidArgument; Request ID: xxxxxxxx-yyyy-zzzz-aaaa-123456789012)

Which is fun, because there is no such thing as a CNAME parameter. So I assume it's talking about the Aliases parameter.

I'm definitely seeing what you're saying about debugging being a pain. But this should be a pretty easy fix if I could just see the malformed value to let me figure out how it went wrong.

badoopbadoopbadoop

Try taking your Alias definition and throwing it into a stack Output field. This way the value is recorded in the stack execution upon completion. You’ll have to comment out any resources that are failing so the stack can complete.

daveidfx [OP]

Great minds! This ended up being what I came up with, almost precisely. It also allowed me to take several attempts at the proper approah per template and compare the results.

Hooray brute-forcing. Still feels like there really should be an easier way, but this is approach did enable me to fix my code, so I'm gonna hang the answer on this one.

Thanks for your help!

whtevn

If it's so malformed that cloudfront doesn't register an attempt, then I don't know if you will be able to find that out. Good luck to you, but I fear the worst. Sometimes events have decent information in them, sometimes the outputs will have information, sometimes you can see evidence in the individual services being created. There is no uniform place for logs to go with cloudformation outside of the events listing

As nice as yaml is for simple documents, I have the worst time reading it for complex things, so I can't really tell you what is right or wrong about what you've sent.

However, the easiest way to build it up is to start with the simplest case you know works, show it works, and then make one small change at a time until the whole stack is working as you like. Not trying to be condescending, that's just how I've found I have to work with CF when it isn't cooperating.

Cloudformation has been an incredible asset but holy shit it can be infuriating to work with. I definitely remember building up my first if statement and then clinging onto that code desperately so I didn't have to remake the magic. Now it all makes sense and I barely remember what the confusion was, but that's how it goes

daveidfx [OP]

Yeah, I've been going layer by layer, building up, so no offense taken. I think it may be the only sane approach. And on several of those layers, I hit these unhelpful errors, hence my meta-question.

Thanks for taking a stab, though. I do appreciate it.

whtevn

no sweat. once you do get that stack built it's a dream. good luck