5

I have a Lambda trigger on my cognito resource for the presignup trigger.

I am following this example https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html#aws-lambda-triggers-pre-registration-example

I am getting a socket timeout and not finding much documentation on this

{
    "err": {
        "code": "UnexpectedLambdaException",
        "name": "UnexpectedLambdaException",
        "message": "arn:aws:lambda:region-arn:function:confirm failed with error Socket timeout while invoking Lambda function."
    }
}

My resources are defined as so:

"ConfirmPermission" : {
    "Type" : "AWS::Lambda::Permission",
    "Properties" : {
        "Action" : "lambda:InvokeFunction",
        "FunctionName" : { "Fn::GetAtt" : [ "confirm", "Arn" ] },
        "Principal" : "cognito-idp.amazonaws.com",
        "SourceArn" : { "Fn::GetAtt" : [ "Auth", "Arn" ] }
        }
},
"confirm" : {
    "Type": "AWS::Serverless::Function",
    "Properties": {
        "Handler": "index.confirm",
        "Runtime": "nodejs8.10",
        "CodeUri": "./src",
        "FunctionName": "confirm",
        "ReservedConcurrentExecutions" : 15,
        "Timeout": 50,
        "Role": "arn:aws:iam::arn:role/lambda-vpc-role"
    }
},
"AuthApp" : {
    "Type" : "AWS::Cognito::UserPoolClient",
    "Properties" : {
        "UserPoolId" : {"Ref" : "Auth"}
    }
},
"Auth" : {
    "Type" : "AWS::Cognito::UserPool",
    "Properties": {
        "LambdaConfig" : {
            "PreSignUp" :  { "Fn::GetAtt" : [ "confirm", "Arn" ] }
        },
        "Schema" : [
            {
                "AttributeDataType": "String",
                "Name": "email",
                "Mutable": true,
                "Required": true
            },
            {
                "AttributeDataType": "String",
                "Name": "family_name",
                "Mutable": true,
                "Required": true
            },
            {
                "AttributeDataType": "String",
                "Name": "given_name",
                "Mutable": true,
                "Required": true
            }
        ],
        "UsernameAttributes": ["email"]
    }
}

Lambda Functions:

index.js

let signIn = require('Auth/Auth.js');
exports.signIn = signIn.signIn;
exports.signUp = signIn.signUp;
exports.confirm = signIn.confirm;

sign up / confirm

exports.signUp = async (event, context) => {
    var body = JSON.parse(event.body);
    var emailAttribute = {
        Name : 'email',
        Value: body.email
    };
    var firstNameAttribute = {
        Name: 'given_name',
        Value: body.firstName
    };
    var lastNameAttribute = {
        Name: 'family_name',
        Value: body.lastName
    };

    var attributeList = [emailAttribute, firstNameAttribute, lastNameAttribute];
    try {
        var cognitoUser = await cognitoSignUp(body, attributeList);
        return {
            statusCode : 200,
            body : JSON.stringify({res : cognitoUser})
        };
    } catch(e) {
        return {
            statusCode : 500,
            body : JSON.stringify({err : e})
        };
    }
}

exports.confirm = (event, context, callback) => {
    event.response.autoConfirmUser = true;
    callback(null, event);
    return;
}

var cognitoSignUp = (body, attributeList) => new Promise((acc, rej) => {
    userPool.signUp(body.email, body.password, attributeList, null, function(err, res) {
        if (err) {
            console.log('ERROR');
            console.log(err);
            rej(err);
        } else {
            console.log('SUCCSSS');
            acc(res);
        }
    });
});

Any idea on what is causing this?

jkeys
  • 3,803
  • 11
  • 39
  • 63
TemporaryFix
  • 2,008
  • 3
  • 30
  • 54
  • Post the trigger code – Brian Winant Jan 21 '19 at 01:20
  • Copy pasta from the example. – TemporaryFix Jan 21 '19 at 02:50
  • @BrianWinant updated question and provided the source code. Do you think my lambda function is performing an external request? When I setup lambda to connect to my RDS I had to configure an IAM role. When doing that it said if I make external requests I need to do those through a gateway? Though the cognito signup functionality works... – TemporaryFix Jan 21 '19 at 15:18
  • 1
    As it turns out, it's because this confirm function has an IAM role for aws resources which blocks network requests. I don't need the IAM role on this function. After removing it, it works perfectly. If you do need resource access then you have to use a nat gateway – TemporaryFix Jan 22 '19 at 02:41

2 Answers2

2

As it turns out, it's because the confirm function has an IAM role for aws resources which blocks network requests. I don't need the IAM role on this function. After removing it, it works perfectly. If you do need resource access, then you have to use a nat gateway

See more here:

AWS Lambda can't call Cognito Identity - IAM Role

https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7

TemporaryFix
  • 2,008
  • 3
  • 30
  • 54
0

You can increase the timeout of your function up to 15 minutes 900 seconds as shown below...

"confirm" : {
    "Type": "AWS::Serverless::Function",
    "Properties": {
        "Handler": "index.confirm",
        "Runtime": "nodejs8.10",
        "CodeUri": "./src",
        "FunctionName": "confirm",
        "ReservedConcurrentExecutions" : 15,
        "Timeout": 900,
        "Role": "arn:aws:iam::arn:role/lambda-vpc-role"
    }
},

Unless you're encoding something running some long analytics you probably shouldn't even need the to 50 seconds let alone 15 minutes though. you should check your logs for an error somewhere and make sure you're calling...

callback(null, event);

To return response from the Lambda.

cantuket
  • 1,582
  • 10
  • 19
  • I updated my question with my lambda source code and I am using the callback. Do you think Lambda is performing a request outside of my vpc? When I setup my RDS instance I had to add an IAM role to my lambda functions to access the RDS instance and it said to perform outside requests it needs to be done through a gateway. – TemporaryFix Jan 21 '19 at 15:16
  • Yes that could definitely be an issue, which I've experienced before as well, but it would be your RDS Security Group preventing connections, not the IAM Role. It would be most helpful to see your logs and Lambda code to help any further especially since the 'example tutorial you're following doesn't appear to call an RDS resource. – cantuket Jan 21 '19 at 16:01
  • If you;'re not handling errors correctly in the Lambda code the the logs won't tell us much – cantuket Jan 21 '19 at 16:02
  • https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-logs.html – cantuket Jan 21 '19 at 16:02
  • I think it's because of my lambda vpc role I added. This looks promising: https://stackoverflow.com/questions/36067080/aws-lambda-cant-call-cognito-identity-iam-role. Im going to try this later and if it fixes it I'll close out this post as a duplicate. Thanks for answering on it – TemporaryFix Jan 21 '19 at 16:13
  • Ok I see your Lambda code now, but there is no request to an RDS instance? If you had mentioned Cognito network request I could have helped you with that. – cantuket Jan 21 '19 at 16:26
  • There is RDS access in other parts of the code base, and my next task after setting up cognito is to create user records in RDS, sorry for not stating there is RDS access. I didn't think it was relevant to this issue. – TemporaryFix Jan 21 '19 at 16:32