Currently a stack's template cannot be updated if applying the update results in no changes. This creates an edge case where template changes gated behind parameters/conditionals with the intent of changing a parameter later to change behavior are not able to be applied.
It is work around-able by making impact-less changes to the template, but that isn't an ideal solution
N/A. This is more of a feature request than a bug so the working behavior is the expected behavior i think.
N/A
N/A
N/A
Our work-around for this problem is to have a MetaData parameter for the stack (which is passed through as an Output. This parameter contains the template version. Then, even if it's just a parameter/whitespace change to the template, the stack has a change to apply.
We get around this issue by tagging all our CloudFormation stacks with a timestamp (among other things). It seems CFT treats even stack level tags as a change so it will always trigger. Anytime a stack is updated, we just always set the latest timestamp. I like this approach best because it doesn't require changing or adding to the CFT itself and can be applied easily across all template via automation.
The behavior you're describing, while annoying, makes sense if you think about how CloudFormation is designed to work: It has to be deterministic in its evaluation and execution of a template. If nothing changed, then by it's very definition it should be _impossible_ for there to be anything to do.
The same inputs must always create the same outputs. If you've worked with custom resources in CloudFormation you'll see that CloudFormation won't even trigger your Lambda function if none of the properties have changed. By it's deterministic design, there should be no reason to. If the inputs haven't changed, the output shouldn't be changing either, so there's no reason to re-evaluate.
That all said.. that's what it strives for, and we don't always follow that pattern which complicates things. I also often follow @seittema's suggestion of a stack-level tag that contains the template version. In my case, it's actually the git commit sha of the commit that triggered the pipeline that deployed the stack. Helps keep track of where things came from but also gives those other resources a "nudge" to re-evalulate themselves anyways.
@Ricapar It _sounds_ like the original request had to do with updating the template of an existing stack. The problem is that it is possible for a template update to not require any resource changes (i.e. because everything is behind a conditional or all parameters are resolved identically) which means that CloudFormation will not accept the template update.
I think the desired behavior would be for CloudFormation to accept the Template update, and then "do nothing".
Imagine a template that looked like this (in off-the-top-of-my-head pseudocode, but hopefully you get the point)
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
...
MyPolicy:
Type: AWS::S3::BucketPolicy
Properties:
...
Bucket: !Ref MyBucket
And you want to prepare for the future, so you want to update the template to look like this:
Parameters:
PolicySelection:
Type: String
Default: MyPolicy
Conditions:
UseMyPolicy: !Equals [!Ref PolicySelection "MyPolicy"]
UseOtherPolicy: !Not [!Ref UseMyPolicy]
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
...
MyPolicy:
Type: AWS::S3::BucketPolicy
Condition: UseMyPolicy
Properties:
...
Bucket: !Ref MyBucket
OtherPolicy:
Type: AWS::S3::BucketPolicy
Condition: UseOTherPolicy
Properties:
...
Bucket: !Ref MyBucket
If all you wanted was to update to use this template, no Stack Resources would change (assuming you left the parameter PolicySelection at the default value of MyPolicy then the MyPolicy Resource would be used, just as it was before, and OtherPolicy would not).
Most helpful comment
We get around this issue by tagging all our CloudFormation stacks with a timestamp (among other things). It seems CFT treats even stack level tags as a change so it will always trigger. Anytime a stack is updated, we just always set the latest timestamp. I like this approach best because it doesn't require changing or adding to the CFT itself and can be applied easily across all template via automation.