clarkie / dynogels

DynamoDB data mapper for node.js. Originally forked from https://github.com/ryanfitz/vogels
Other
490 stars 110 forks source link

Tips for running locally against dynamodb local? #49

Closed cmawhorter closed 7 years ago

cmawhorter commented 7 years ago

This is more a problem with aws-sdk I suppose, but I've tried everything I can think of to get dynogels to run locally against the local dynamodb server but I continue to get the "Missing region in config" aws error.

I've tried env, explicitly setting on the global AWS, dynogels.AWS, a combination of some or all, hitting it with a hammer. Nothing works.

Even doing the following combination of everything still fails with "Missing region in config" in spite of the fact that dynamodb.config.region is correctly set to "us-east-1".

process.env.AWS_DEFAULT_REGION = 'us-east-1';
process.env.AWS_ACCESS_KEY_ID = 'AKID';
process.env.AWS_SECRET_ACCESS_KEY = 'SECRET';
var config = {accessKeyId: 'AKID', secretAccessKey: 'SECRET', region: 'us-east-1'};
AWS.config.update(config);
dynogels.AWS.config.update(config);
var dynamodb = new AWS.DynamoDB({ endpoint: 'http://localhost:8000', region: config.region });
dynogels.dynamoDriver(dynamodb);
SomeModel.config({ service: dynamodb })
SomeModel.get(...) // "Missing region in config"

Nothing works. 😭 Anyone have any tips?

I cloned dynogels and npm test all pass.

Edit: Oh, and I should add. I have a script that does dynogels.createTables without a problem so I'm completely confused.

M1chaelTran commented 7 years ago

your code looks like it should work. this might be a stupid question, but have you checked that your local dynamodb has been started?

here's what we use in our app

import Joi from 'joi'
import uuid from 'uuid'
import dynogels from 'dynogels'

require('dotenv').load();

const AWS = dynogels.AWS;

AWS.config.update({
  accessKeyId: process.env.DYNAMODB_ACCESSKEYID
  , secretAccessKey: process.env.DYNAMODB_SECRETACCESSKEY
  , region: process.env.DYNAMODB_REGION
});

if (process.env.DYNAMODB_SECRETACCESSKEY === "verysecretaccesskey") {
  // test locally
  const opts = {endpoint: 'http://localhost:8000'}
  dynogels.dynamoDriver(new AWS.DynamoDB(opts))
}
cmawhorter commented 7 years ago

from what i can tell, it's partly (if not all) related to the way aws sdk infers credentials from the env whether you want it to or not.

i think what was happening here is it was loading from ~/.aws/credentials. i don't know if it's an aws bug or what.

i ended up giving up and going back to my own client because i couldn't get dynogels to do anything other than createTables and have no idea why. (even createTables only creates 3/4 of my tables...?)

Edit: I should've added my workaround. I still have no idea what was causing it, but the workaround is setting process.env.AWS_REGION and not AWS_DEFAULT_REGION. IIRC, AWS_DEFAULT_REGION is a aws cli specific env var.

clarkie commented 7 years ago

We've never had a problem with this. Here's the link to the AWS SDK docs showing the order in which the sdk will load the config: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html

This is how we do it:

dynogels.dynamoDriver(new AWS.DynamoDB(config));

where the config for local and production looks like this:

// local config
{
  endpoint: 'http://localhost:8000',
  region: 'eu-west-1',
},
// production config
{
  region: 'eu-west-1',
}

We then set the two environment variables for the sdk (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) on the EC2 machines in production

cmawhorter commented 7 years ago

It only happens on dev machines so my guess it is something to do with the existence of ~/.aws/ credentials conflicting with env vars and explicitly passing to the service constructor. And then maybe some code somewhere doing a require('aws-sdk') before the proper env variables can be set. I don't know.

It seems intermittent, but I'll see if I can come up with a min repro with dynogels and will close if not.

cmawhorter commented 7 years ago

Ooook. tl;dr; definitely not a problem with dynogels. So, closing.

I tried to create a repro but was coming up empty.

I still have no idea what is going on but my gut says that it's something to do with a) mixing AWS_PROFILE with other cred methods and b) aws sdk loading credentials async.

My guess is there is a race in there somewhere (which would explain the intermittent problem).

cmawhorter commented 7 years ago

For the future searchers of the world. This should at least keep aws from auto loading credentials:

if (process.env.NODE_ENV === 'development') {
  Object.keys(process.env).forEach(key => 0 === key.indexOf('AWS_') ? delete process.env[key] : null);
}
var AWS = require('aws-sdk');