ghdna / athena-express

Athena-Express can simplify executing SQL queries in Amazon Athena AND fetching cleaned-up JSON results in the same synchronous or asynchronous request - well suited for web applications.
https://www.npmjs.com/package/athena-express
MIT License
181 stars 70 forks source link

Error `AWS object not present or incorrect in the constructor` when using IAM role #21

Closed dchertousov closed 3 years ago

dchertousov commented 5 years ago

When IAM role is used for EC2/Lambda and s3 options is not passed to the config, athena-express is not able to create new buckets on its behalf, failing with error AWS object not present or incorrect in the constructor.

It looks here: https://github.com/ghdna/athena-express/blob/master/lib/athenaExpress.js#L232 that it expects either s3 option to be set or credentials keys to be passed.

I had IAM role set up with full access to S3 and Athena, though I had to specify S3 location manually to override behavior.

ghdna commented 5 years ago

With IAM role in a Lambda or EC2, you can skip configuring the AWS object with access/secret keys but you still need to pass the AWS object for athena-express to pull the relevant methods off the SDK. Make sure you const aws = require("aws-sdk"); in your Lambda/EC2 and then pass it in the athena-express constructor.

dchertousov commented 5 years ago

@ghdna thank you fro swift reply. I pass aws config just as you describe const aws = require("aws-sdk"); but I still receive the error above on the machine where just IAM role is attached and none credentials are configured view aws configure. All other AWS services like s3 work using the same aws object instance. Roles permissions are set just as you described (full access for s3 and Athena).

ghdna commented 5 years ago

oh okay, let me look into it. When IAM roles are attached, I use info from the aws object to create a unique S3 bucket name. If there is an issue with that, perhaps the temporary workaround, until i investigate this, is to provide your own unique s3 bucket name.

SamuelHaleMN commented 4 years ago

I can confirm that I'm also having this issue.

Executing within a Lamba, with an IAM policy attached to it.

Getting the same error message.

ghdna commented 4 years ago

Did this get fixed? I tried replicating it but couldnt. Can you check if the IAM role has Athena and S3 access. And does it work if you provide s3://yourbucketname in the config?

sonupsp3 commented 4 years ago

Even I'm facing the same issue but with the nodejs. I tried even by supplying s3 in the config

sonupsp3 commented 4 years ago

I'm using athena-express in java script by passing awsCredentials and also specified s3

carlosescura commented 4 years ago

Same issue here, when I use profiles in my computer or access keys it works, but when it uses the AssumeRoleWithWebIdentity in K8s it fails

carlosescura commented 4 years ago

After a further investigation, I found the issue and why it's related only with roles:

This line is the cause.

For all of you having this issue, can you specify a custom s3 output directory for your queries? If so, it won't fail as the exception is thrown because of the lack of both, the s3 value in the constructor, and the lack of a valid AWS access key (because you are using a role/instanceprofile).

const aws = require("aws-sdk");

const athenaExpressConfig = {
    aws,
    s3: "s3://whatever-your-bucket-is"
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);
KrickyKiki commented 4 years ago

I had this error when trying to pass AWS ( caps ) instead of aws. To replicate the issue:

const AWS = require("aws-sdk");
const athenaExpressConfig = {
    AWS
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);

However below worked fine:

const AWS = require("aws-sdk");
const athenaExpressConfig = {
    aws: AWS
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);
SamuelHaleMN commented 4 years ago

I had this error when trying to pass AWS ( caps ) instead of aws. To replicate the issue:

const AWS = require("aws-sdk");
const athenaExpressConfig = {
  AWS
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);

However below worked fine:

const AWS = require("aws-sdk");
const athenaExpressConfig = {
  aws: AWS
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);

This was my issue as well. It was specifically replicable when passing the all-caps instance of the aws-sdk, labeled as 'AWS' into the AthenaExpress constructor.

ghdna commented 3 years ago

Closing this issue. Based on the comments, this was not an issue with code and instead an issue with the examples in readme. The uppercase of AWS in const AWS = require("aws-sdk") mismatched when passing it to AthenaExpress configuration in lowercase. I have updated the readme examples to make following easier. Thanks for bringing this to our notice. If there is still an issue with this, let me know and I'll reopen.

msokolov93 commented 3 years ago
const aws = require("aws-sdk");

const athenaExpressConfig = {
    aws,
    s3: "s3://whatever-your-bucket-is"
};
const athenaExpress = new AthenaExpress(athenaExpressConfig);

Had the same issue. After s3 path was added Athena worked and saved files to LOCATION from its tables; not the s3 path added in AthenaExpress configuration.

Probable cause - Athena attempted to create bucket that already existed. I think Service should check for it, or at least provide accurate error message.