aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap

AWS::CloudFormation - General Capability: Better handling of API limits and throttling.

Open
#573 10 comments 32 reactions 0 assignees View on GitHub
Coverage enhancement
Dominant language
No language data
Stars
1.1k
Forks
62
PR merge metrics
No merged PRs in 30d

Description

## 1. AWS::CloudFormation - General Capability: Better handling of API limits and throttling.

This is a general feature/capability request, and not limited to any specific resource type.

## 2. Scope of request

CloudFormation supports up to 200 resources per Stack under the normal AWS account limits. It is possible to perform a stack update where a large majority (or all) of the resources in the stack have an update that needs to be applied.

Presently, depending on the types of resources being updated, it's possible that CloudFormation will fail to update one or more resources due to self-inflicted API throttling and result in rolling back the entire stack.

Samples:
#### AWS::SSM::Parameter
I could have a programatically generated CloudFormation stack that creates up to 200 `AWS::SSM::Parameter` resources based on output from a CI/CD process. One of the properties in the Parameter's value may be a last-updated timestamp or something to that effect:

```
ExampleParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: !Sub "/${AWS::StackName}/db-connection"
Value: !Sub |
{
"last_updated": "${timestamp}",
"host": "db.example.com",
"port": "5432"
}

# (repeat above x200)
```

#### AWS::ServiceCatalog::CloudFormationProvisionedProduct
I could have a stack with a large number of `AWS::ServiceCatalog::CloudFormationProvisionedProduct` resources that all have an update to a parameter or two, or perhaps all share a common parameter from the stack's input that is changing.

## 3. Expected behavior

If there's a situation created where CloudFormation is scheduled to do a large amount of resource updates, especially in cases where they are all resources of the same type, CloudFormation should be aware of API limitations and throttling limits and self-manage the rate at which the resources are updated in order to ensure that a stack update failure does not occur due to a service returning throttling errors.

In the `AWS::SSM:Parameter` example above, none of the parameters contain any explicit dependencies (`DependsOn`) or implicit (`!Ref`s and such) to each other. If the `${timestamp}` parameter changes CloudFormation should be smart enough to realize that it shouldn't do 200 calls to the SSM APIs at the same time as that would cause throttling.

### 3.1 Current Behavior

I experienced this with the `AWS::ServiceCatalog::CloudFormationProvisionedProduct` resource most recently, but it has also affected others as well.

CloudFormation will see that all of the resources need updating and proceed to update all of them at the same time (in parallel) as they do not have inter-dependencies. This results in API throttling from the service that provides those resources. CloudFormation and the APIs seem to have their own incremental back-off/retry logic and will continue to try to update those resources. Depending on how long the resources take to update, throttling won't resolve itself fast enough and CloudFormation will mark all of the resources as `UPDATE_FAILED` and then proceed to roll back the rest of the stack.

The failure would not happen if CloudFormation would self-throttle before the backend API throttling even becomes an issue.

## 4. Suggest specific test cases

Make a stack with 50 `AWS::ServiceCatalog::CloudFormationProvisionedProduct` resources. Trigger a stack update that forces all of them to update.

Make a stack with 200 `AWS::SSM::Parameters` . Trigger a stack update that forces them all to update.

## 6. Category

Management - CloudFormation

## 7. Any additional context (optional)

I'm well aware I can work around this issue by setting up a bunch of DependsOn conditions to "trick" CloudFormation into batching together updates of resources that would otherwise be done in bulk. Likewise I could refactor the stacks (easier said than done for resources that can't be imported because they don't support drift detection) into smaller stacks. However, regardless of the work-around options available I don't think these are the right solution.

When a stack is well within the out-of-box resource limits for a single stack, CloudFormation should behave properly as to not self-inflict throttling issues that cause a rollback.

Similarly, as tools like CDK evolve and mature more, having a for-loop that generates a ton of resources won't be unheard of, and the risk of creating a situation where a ton of resources of the same type update simultaneously becomes a lot more common.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.