I have an AWS lambda function in a VPC on AWS account A that has a peering connection with a VPC on AWS account B containing a DAX cluster. I'm getting the following error when trying to connect to the DAX cluster from my lambda.
2021-12-17T17:29:34.096Z 279f4ed8-a6ea-4f50-b1d7-31c307cc3f30 ERROR Failed to pull from my-cluster.v3fh7d.dax-clusters.us-east-1.amazonaws.com (11.0.225.143): TimeoutError: ConnectionException: Connection timeout after 10000ms
at SocketTubePool.alloc (/var/task/node_modules/amazon-dax-client/src/Tube.js:244:64)
at /var/task/node_modules/amazon-dax-client/generated-src/Operations.js:215:30 {
time: 1639762164096,
code: 'ConnectionException',
retryable: true,
requestId: null,
statusCode: -1,
_tubeInvalid: false,
waitForRecoveryBeforeRetrying: false
}
The relevant part of my lambda code is here.
let assumedRole;
const sts = new AWS.STS({ region: "us-east-1" });
const params = {
RoleArn:
"arn:aws:iam::<account-b>:role/role-to-access-dax",
RoleSessionName: "testAssumeRoleSession" + Date.now().toString(),
DurationSeconds: 3600,
};
try {
assumedRole = await sts.assumeRole(params).promise();
} catch (error) {
console.log("Failed getting sts assume role: " + error);
}
const dax = new AmazonDaxClient({
endpoint:
"dax://my-cluster.v3fh7d.dax-clusters.us-east-1.amazonaws.com",
region: "us-east-1",
accessKeyId: assumedRole.Credentials.AccessKeyId,
secretAccessKey: assumedRole.Credentials.SecretAccessKey,
sessionToken: assumedRole.Credentials.SessionToken,
httpOptions: { timeout: 150000 },
maxRetries: 1,
});
const dynamodb = new AWS.DynamoDB.DocumentClient({ service: dax });
try {
const params = {
Key: {
userid: requestData.userid,
},
TableName: "my-users-table",
};
const result = await dynamodb.get(params).promise();
if (result.Item == undefined || result.Item == null) {
return createResponse(401, "Unauthorized");
}
return createResponse(200, JSON.stringify(result.Item));
} catch (error) {
return createResponse(500, error);
}
The role arn:aws:iam::<account-b>:role/role-to-access-dax
has the following permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dax:GetItem",
"dax:BatchGetItem",
"dax:Query",
"dax:Scan",
"dax:PutItem",
"dax:UpdateItem",
"dax:DeleteItem",
"dax:BatchWriteItem",
"dax:ConditionCheckItem"
],
"Resource": "arn:aws:dax:us-east-1:<account-b>:cache/my-cluster"
}
]
}
and the following trust relationship.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account-a>:root"
},
"Action": "sts:AssumeRole"
}
]
}
The DAX cluster has the policy AmazonDynamoDBFullAccess
.
The peering connection shows up as Active
in the AWS console.
The DAX cluster's security group has an inbound rule to allow TCP traffic on port 8111
from source <account-a> / <sg-of-lambda>
.
The CIDR of the Account A VPC is 10.0.0.0/24
and the CIDR of the Account B VPC is 11.0.0.0/16
.
The Account A VPC's main route table has a route directing traffic with destination 11.0.0.0/16
to the peering connection. Likewise, the Account B VPC's main route table has a route directing traffic with destination 10.0.0.0/24
to the peering connection.
As an aside, the following lines in the lambda code appear to be ignored as there are quite a few retries on the DAX request and the timeout is not changing from 10000 ms.
httpOptions: { timeout: 150000 },
maxRetries: 1,