aws-amplify / aws-amplify/amplify-cli

Unexpected throttling during deployment from UpdateRolesWithIDPFunction

Open
#13,687 4 comments 0 reactions 0 assignees View on GitHub
auth bug p3
Dominant language
TypeScript
Stars
2.9k
Forks
825
Avg merge
11d 23h
Merged PRs (30d)
2

Description

### Amplify CLI Version

12.10.1

### Question

`amplify push` fails as we create new environments.
We examine our cloud formation logs see the `UpdateRolesWithIDPFunctionOutputs` lambda function for amplify environment is the source of the error. We visit the cloudwatch logs and find this error.

Previously we used amplify v9.2.1 and deployed environments without issue, however after upgrading to v12.10.1 we are seeing this issue. This appears to occur intermittently as we have deployed some environments successfully.

Error in cloud watch:
```json
{
"Status": "FAILED",
"Reason": "See the details in CloudWatch Log Stream: 2024/04/01/[$LATEST]80d0d2816e064b43824d00206af9b1b7",
"PhysicalResourceId": "2024/04/01/[$LATEST]80d0d2816e064b43824d00206af9b1b7",
"StackId": "arn:aws:cloudformation:us-west-2:370837355406:stack/amplify-www-lemona-140512/88476010-f06b-11ee-b2a3-02b61020254d",
"RequestId": "c5c4f4fe-99b3-45eb-9d8f-d88fe8582fd0",
"LogicalResourceId": "UpdateRolesWithIDPFunctionOutputs",
"NoEcho": false,
"Data": {
"Error": {
"name": "Throttling",
"$fault": "client",
"$metadata": {
"httpStatusCode": 400,
"requestId": "63175dcc-b2a1-4a43-85e3-806b74e7a9cd",
"attempts": 3,
"totalRetryDelay": 134
},
"Type": "Sender",
"Code": "Throttling",
"message": "Rate exceeded"
}
}
}
```

error.stack
```
2024-04-01T21:23:29.839Z 101336b9-30e1-45d2-84f6-68ca61681f54 INFO Throttling: Rate exceeded
at throwDefaultError (/var/runtime/node_modules/@aws-sdk/node_modules/@smithy/smithy-client/dist-cjs/index.js:838:20)
at /var/runtime/node_modules/@aws-sdk/node_modules/@smithy/smithy-client/dist-cjs/index.js:847:5
at de_CommandError (/var/runtime/node_modules/@aws-sdk/client-iam/dist-cjs/index.js:4635:14)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /var/runtime/node_modules/@aws-sdk/node_modules/@smithy/middleware-serde/dist-cjs/index.js:35:20
at async /var/runtime/node_modules/@aws-sdk/node_modules/@smithy/core/dist-cjs/index.js:165:18
at async /var/runtime/node_modules/@aws-sdk/node_modules/@smithy/middleware-retry/dist-cjs/index.js:320:38
at async /var/runtime/node_modules/@aws-sdk/middleware-logger/dist-cjs/index.js:33:22
at async Promise.all (index 0)
at async handleEvent (/var/task/index.js:62:25)
```
[Lambda source](https://github.com/aws-amplify/amplify-cli/blob/47e4100cab77c546f5d2746bfbd2480295674da6/packages/amplify-provider-awscloudformation/resources/update-idp-roles-cfn.json#L10)
```
const response = require('cfn-response');
const { IAMClient, GetRoleCommand, UpdateAssumeRolePolicyCommand } = require('@aws-sdk/client-iam');
exports.handler = function(event, context) {
// Don't return promise, response.send() marks context as done internally
const ignoredPromise = handleEvent(event, context)
};
async function handleEvent(event, context) {
try {
let authRoleName = event.ResourceProperties.authRoleName;
let unauthRoleName = event.ResourceProperties.unauthRoleName;
let idpId = event.ResourceProperties.idpId;
let authParamsJson = {
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Principal': {'Federated': 'cognito-identity.amazonaws.com'},
'Action': 'sts:AssumeRoleWithWebIdentity',
'Condition': {
'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},
'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'authenticated'}
}
}]
};
let unauthParamsJson = {
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Principal': {'Federated': 'cognito-identity.amazonaws.com'},
'Action': 'sts:AssumeRoleWithWebIdentity',
'Condition': {
'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},
'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'unauthenticated'}
}
}]
};
if (event.RequestType === 'Delete') {
try {
delete authParamsJson.Statement[0].Condition;
delete unauthParamsJson.Statement[0].Condition;
authParamsJson.Statement[0].Effect = 'Deny'
unauthParamsJson.Statement[0].Effect = 'Deny'
let authParams = {PolicyDocument: JSON.stringify(authParamsJson), RoleName: authRoleName};
let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson), RoleName: unauthRoleName};
const iam = new IAMClient({region: event.ResourceProperties.region});
let res = await Promise.all([
iam.send(new GetRoleCommand({RoleName: authParams.RoleName})),
iam.send(new GetRoleCommand({RoleName: unauthParams.RoleName}))
]);
res = await Promise.all([
iam.send(new UpdateAssumeRolePolicyCommand(authParams)),
iam.send(new UpdateAssumeRolePolicyCommand(unauthParams))
]);
response.send(event, context, response.SUCCESS, {});
} catch (err) {
console.log(err.stack);
response.send(event, context, response.SUCCESS, {Error: err});
}
} else if (event.RequestType === 'Update' || event.RequestType === 'Create') {
const iam = new IAMClient({region: event.ResourceProperties.region});
let authParams = {PolicyDocument: JSON.stringify(authParamsJson), RoleName: authRoleName};
let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson), RoleName: unauthRoleName};
const res = await Promise.all([
iam.send(new UpdateAssumeRolePolicyCommand(authParams)),
iam.send(new UpdateAssumeRolePolicyCommand(unauthParams))
]);
response.send(event, context, response.SUCCESS, {});
}
} catch (err) {
console.log(err.stack);
response.send(event, context, response.FAILED, {Error: err});
}
};
```

Contributor guide

Open the contributing guide

Research direction

Start with packages/amplify-provider-awscloudformation/resources/update-idp-roles-cfn.json and the UpdateRolesWithIDPFunction source shown in the issue. Run or inspect an amplify push that creates an environment, then trace the concurrent IAM calls in handleEvent and the CloudWatch failure; done means environment creation no longer fails with Rate exceeded.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, javascript, node.js
Domain
authorization, cli, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.