TooManyRequestsException when creating a lot of resources

I am creating 14 user pools and 14 user pool clients through serverless and every time I try to deploy, I’m getting this error

An error occurred: userpoolClient - Rate exceeded (Service: AWSCognitoIdentityProvider; Status Code: 400; Error Code: TooManyRequestsException; Request ID: 5872acf5-d84a-11e8-8b3b-e7b5da027444).

Most of the user pools and their clients are created successfully, because I’ve made sure to use DependsOn, so that each resource is created sequentially and depends on the previous one, but it’s still not reliable enough.

This is an example of a set of resources in my serverless.js (this is repeated 14 times)

"userpool": {
  "Type": "AWS::Cognito::UserPool",
  "Properties": {
    "UserPoolName": "userpool",
    "Policies": {
      "PasswordPolicy": {
        "MinimumLength": 6,
        "RequireLowercase": false,
        "RequireNumbers": false,
        "RequireSymbols": false,
        "RequireUppercase": false
      }
    },
    "Schema": [
      {
        "AttributeDataType": "String",
        "Mutable": true,
        "Name": "user_id",
        "StringAttributeConstraints": {
          "MinLength": "1",
          "MaxLength": "256"
        }
      }
    ]
  }
},
"userpoolClient": {
  "Type": "AWS::Cognito::UserPoolClient",
  "Properties": {
    "ClientName": "userpool-client",
    "UserPoolId": {
      "Ref": "userpool"
    },
    "ExplicitAuthFlows": [
      "ADMIN_NO_SRP_AUTH",
      "USER_PASSWORD_AUTH"
    ],
    "ReadAttributes": [
      "email",
      "email_verified",
      "phone_number",
      "phone_number_verified",
      "custom:user_id"
    ],
    "WriteAttributes": [
      "email",
      "phone_number"
    ]
  },
  "DependsOn": "userpool"
},

Any help would be much appreciated. Is there anything I’m missing from the serverless config?

It seems like you’re exceeding the API rate limits for Cognito User Pool. https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html

Your only option might be to split the user pool creation into multiple stacks to get it down.

In the end I resolved it by making sure each resource DependsOn the resource before it, so they are created in sequence. But that’s not really ideal and I believe there should be a better way of doing this.
But it appears that the rate limit error is not retryable.

I solved this using WaitConditions and a script in our deploy process to signal the wait condition to complete. Basically, I created a plugin (yet to be published) which creates the WaitCondition resources during the packaging process. It adds resources to the depends on array of the wait condition. A script monitors the deploy process and sends a signal to the wait condition when it is created (which will happen after the dependencies are created) so the process can continue. If the wait condition is not yet created, the script sleeps for a configurable amount of time before signalling again. When I get a chance to publish this to npm, I’ll update here.