0

I have a node app deployed using elastic beanstalk. I'm trying to publish to an SNS topic using the sdk from within my app. It's my understanding that the credentials will be provided for all the api calls my app makes from the IAM role associated with my eb ec2 instances. Here's the code that attempts the publication of the SNS message:

var arn = process.env.EVENT_ALARM_ARN;

            if(arn){
                var sns = new AWS.SNS();
                console.log("the sns: " + JSON.stringify(sns));
                sns.publish({
                    TopicArn:arn,
                    Message:JSON.stringify(event),
                    Subject:"Event Check"},
                    function(err, data) {
                        if(err){
                            console.log("Error sending SNS message for alarm check: " + err);
                        } else {
                            console.log("Queued SNS message " + JSON.stringify(data));
                        }

                });
            } else {
                console.log("No SNS with ARN: " + arn);
            }

The log output from prining the sns:

"the sns: {\"config\":{\"credentials\":null,\"credentialProvider\":{\"providers\":[null,null,null,null]},\"logger\":null,\"apiVersions\":{},\"apiVersion\":null,\"endpoint\":\"sns.undefined.amazonaws.com\",\"httpOptions\":{\"timeout\":120000},\"maxRedirects\":10,\"paramValidation\":true,\"sslEnabled\":true,\"s3ForcePathStyle\":false,\"s3BucketEndpoint\":false,\"s3DisableBodySigning\":true,\"computeChecksums\":true,\"convertResponseTypes\":true,\"correctClockSkew\":false,\"customUserAgent\":null,\"dynamoDbCrc32\":true,\"systemClockOffset\":0,\"signatureVersion\":\"v4\",\"signatureCache\":true,\"retryDelayOptions\":{\"base\":100},\"useAccelerateEndpoint\":false},\"isGlobalEndpoint\":false,\"endpoint\":{\"protocol\":\"https:\",\"host\":\"sns.undefined.amazonaws.com\",\"port\":443,\"hostname\":\"sns.undefined.amazonaws.com\",\"pathname\":\"/\",\"path\":\"/\",\"href\":\"https://sns.undefined.amazonaws.com/\"},\"_clientId\":121}"

which seems to indicate I have no credentials. I'm not doing anything explicitly to obtain them, as I understand this happens automatically. I'm failing to send the SNS, with the following error:

Error sending SNS message for alarm check: ConfigError: Missing region in config

I would think the instance would know what region it's in, and ideally, if I have to specify that in some sort of configuration call, I'd be able to dynamically derive it's value. I'm just confused as to what I need to provide, and how I can get it from the environment. So my question is how do I properly specify the credentials and any other data needed to successfully call this api that publishes to the SNS topic, given these instances are elastic beanstalk instances and have the proper IAM roles associated with them? Thanks.

UPDATE:

If I instantiate the sns object like this:

var sns = new AWS.SNS({
                    region: 'us-east-1' //change to your region
                });

I successfully post to the SNS topic. So now I'm down to just figuring out how I can derive the region string to pass into that constructor from whatever environment data I can access

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
wkhatch
  • 2,664
  • 7
  • 36
  • 45
  • For your secondary question you could use elastic beanstlalk environment variables, here is a [good example](https://alexdisler.com/2016/03/26/nodejs-environment-variables-elastic-beanstalk-aws/) of how to access them with Node.js. One way to se the env variables would to create an ebextension with your variables. .elasticbeanstalk/env_var.config -> ` option_settings: - namespace: aws:elasticbeanstalk:application:environment option_name: REGION value: us-east-1 - namespace: aws:elasticbeanstalk:application:environment option_name: MY_ENV value: FOO ` – nbalas Jan 24 '17 at 19:48
  • yeah, I rely on those quite a bit, so that's what I ended up doing as a sort of work around. just seems so weird that I'd have to explicitly pass in the region on an ec2 instance that is already running within a region – wkhatch Jan 24 '17 at 19:53
  • Looks like [this](http://stackoverflow.com/questions/4249488/find-region-from-within-ec2-instance) might be the closed you can get to 'automatic' detection. Technically you would be able to hit other region endpoints from your EC2 instance in us-east-1 so the specification is required. – nbalas Jan 24 '17 at 21:03
  • I hadn't considered that an EC2 instance may be reaching an endpoint or service in another region, so I guess it does make sense. But still, it would seem there'd be a means of interrogating an instances meta data via the sdk api's to determine what region it's running it. It has to know that or have access to that attribute, I'd think. – wkhatch Jan 24 '17 at 22:34

0 Answers0