AWS Credentials not passed in ecs task with dynamodb nodejs
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.
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);
});
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);
})
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??
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.
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?
Relevant questions
Why do deployments with CodeDeploy to ECS (fargate) without tasks succeed?
asked 8 days agoShould ECS/EC2 ASGProvider Capacity Provider be able to scale-up from zero, 0->1
Accepted Answerasked 5 months agoAWS Credentials not passed in ecs task with dynamodb nodejs
Accepted Answerasked 4 months agoShould ECS Service Task start be triggered by ASG capacity 0->1?
Accepted Answerasked 5 months agoDelayed shutdown of ECS Fargate tasks?
asked 4 months agoHow to register IP address for ECS task at startup so that other resources can find it
Accepted Answerasked 2 years agoECS: Random container failed to start - no log
asked 7 days agoHow to I troubleshoot a deploy that is forever in "IN_PROGRESS"?
asked 6 months agodefining the name of task definition json to run ecs task in github actions
asked 2 years agoWhat needs to be done to make event bridge invoke a fargate task when file added to s3
asked 22 days ago
I dont wanna use User access keys, I would prefer to use the Role Credentials