AWS Credentials not passed in ecs task with dynamodb nodejs

0

Hi, There is a weird problem statement. So I have a ECS Task attached with RoleName called MyRole . This ECS Tasks has a nodejs script which queries a dynamodb Table.

Nodejs script:

const AWS = require('aws-sdk');

async function GetCredentials(){
var docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-2'});

var identifier = "test-asassa";

var params3 = {
  TableName: 'MyTable',
  ExpressionAttributeNames: { '#var1': 'var1' },
  KeyConditionExpression: '#var1 = :var1',
  ExpressionAttributeValues: {
    ':var1': 'ValueToBeQueried'
  }
}

await docClient.query(params3,( () => {
    })).promise().then(async (data1) => {
	console.log(data1);
});
};

GetCredentials().then(data => {
            console.log(data);
});

This code when ran simply in docker container doesnt fetch the AWS credentials from Role and errors out saying ValidationException. At same time, if I export the credentials as AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN, the script works.

Can anyone help me understand wth is going on here? How do i make sure code takes the role attached to the ECS Task?

Trust relationship and all other misc are correct. The query is also correct. To reproduce this, you can create a table called "MyTable" with primary key as "var1" . Now use the same code as shared above and in the same terminal, export the AWS access keys. The code will work. Now, in any ecs task, attach iam role to the task with sufficient permissions and it will not work and error out saying ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type which is completely mis-leading error.

  • I dont wanna use User access keys, I would prefer to use the Role Credentials

asked 2 years ago1647 views
4 Answers
2
Accepted Answer

It is YOUR code that is faulty.

If you run as is in nodejs v16.13.2 in EC2 with instance profile, it through the exact same error.

The issue with your code lies in you use both callback function in its own wired closure and somehow you then chained a promise.

You should not use both callback and promise as the function signature does not match.

Please clean up your code, remove unnecessary await, async, most importantly remove your callback closure and I recommend you add error handling logic otherwise it might crash your application.

docClient.query(params3).promise().then((data1) => {
	console.log(data1);
}, (err) => {
    console.error((err));
});

You can refer how to properly use promise in AWS SDK here.

Laslty, I recommend you take the time and read about Promise. Because even if you fixed the issue I pointed out, your code still won't function because you make an API call to GetCredentials() which you seem to expect returning an promise, but you failed to do so.

If you expect to call GetCredentials().then(), you should do this within your GetCredentials function instead of the previous code block -

return docClient.query(params3).promise();

For your reference, your code should look like this (I did not fix your naming, which you should also do)

const AWS = require('aws-sdk');

var docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});

async function GetCredentials(){

//var identifier = "test-asassa";

var params3 = {
  TableName: 'MyTable',
  ExpressionAttributeNames: { '#var1': 'var1' },
  KeyConditionExpression: '#var1 = :var1',
  ExpressionAttributeValues: {
    ':var1': 'test'
  }
}

return docClient.query(params3).promise();

};

GetCredentials().then( (data) => {
    console.log(data);
}, (err) => {
    console.error(err);
});
Jason_S
answered 2 years ago
1

First of all, lets narrow down the issue. Lets understand which credentials are being picked up by the client. Run the below code snippet before you interact with DynamoDB:

const sts = new AWS.STS();
sts.getCallerIdentity().promise().then(data =>{
    console.log(data);
})
profile pictureAWS
EXPERT
answered 2 years ago
0

Did you specify the correct trust relationship for your IAM role?


{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Also what exactly the "ValidationException" message say??

Jason_S
answered 2 years ago
  • Yes, Trust relationship is correct. Exact error is ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type

    Dont let the error make u think that schema is wrong in query. That is not the case. You can literally copy the same query and run it and it will work. The error is mis-leading.

        at Request.extractError (/backend/node_modules/aws-sdk/lib/protocol/json.js:52:27)
        at Request.callListeners (/backend/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
        at Request.emit (/backend/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
        at Request.emit (/backend/node_modules/aws-sdk/lib/request.js:686:14)
        at Request.transition (/backend/node_modules/aws-sdk/lib/request.js:22:10)
        at AcceptorStateMachine.runTo (/backend/node_modules/aws-sdk/lib/state_machine.js:14:12)
        at /backend/node_modules/aws-sdk/lib/state_machine.js:26:10
        at Request.<anonymous> (/backend/node_modules/aws-sdk/lib/request.js:38:9)
        at Request.<anonymous> (/backend/node_modules/aws-sdk/lib/request.js:688:12)
        at Request.callListeners (/backend/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
    
  • Unfortunately if you keep down voting best-efforts answers that the author volunteer their time helping you with clarification questions, it's not being respectful for their time or incentivize the community.

    That said, if you can execute the command within the container and validate you can get the role credentials, by query the credential endpoint, it should be clear the IAM role has been successfully passed on to the task from ECS standpoint. This is also helpful to ensure the correct role is being passed on.

    It could either be issue with your code, or nodejs SDK if IAM role is indeed passed to ECS task.

0

That error has nothing to do with credentials. It's about DynamoDB query problem. most likely type passed in query doesn't match with type of attribute definition. E.g. in your example above you have 'ValueToBeQueried' as string, but is your var1 defined as string in table attribute definition?

answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions