Skip to content

Unexpected throttling during deployment from UpdateRolesWithIDPFunction #13687

@NickDario

Description

@NickDario

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:

{
    "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

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});
    }
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    authIssues tied to the auth category of the CLIbugSomething isn't workingp3

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions