I'm trying to get the ssm parameter inside my nodejs project, is IAM credentials I and wrote a test in my elastic beanstalk instance and works. The problem is inside the project. Any ideas why?
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
var ssm = new AWS.SSM();
var options = {
Name: '/test/test', /* required */
WithDecryption: false
};
var parameterPromise = ssm.getParameter(options).promise();
parameterPromise.then(function(data, err) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
I discovered, the same of this https://github.com/localstack/localstack/issues/1107
need to pass the region in the SSM constructor
var ssm = new AWS.SSM({region: 'us-east-1'});
seems to be a bug
tks
Related
I have a NodeJS lambda function that is trying to list IAM users via the IAM listUsers API method . The call is firing off but never returning until the lambda function itself times out and I'm unsure why. Here is the code:
exports.handler = async (event) => {
console.log('before call');
var ret = await listIAMUsers();
console.log('ret: ' + JSON.stringify(ret));
};
async function listIAMUsers() {
var AWS = require('aws-sdk');
AWS.config.update({region: 'REGION'});
var iam = new AWS.IAM({apiVersion: '2010-05-08'});
var params = {MaxItems: 10};
return iam.listUsers(params).promise();
}
Managing IAM Users. Pay close attention where we initialize the client and add require statements.
For the optimization purpose. it is good to load and initialize the. client while loading the function
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});
// Create the IAM service object
var iam = new AWS.IAM({apiVersion: '2010-05-08'});
As JS is single-threaded so you reuse the clients.
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
exports.handler = async (event, context) => {
console.log('before call');
var ret = await listIAMUsers();
console.log('ret: ' + JSON.stringify(ret));
};
async function listIAMUsers() {
// Set the region
AWS.config.update({region: 'REGION'});
// Create the IAM service object
var iam = new AWS.IAM({apiVersion: '2010-05-08'});
var params = {MaxItems: 10};
return iam.listUsers(params).promise();
}
START RequestId: 933ca3dd-2feb-4f98-8f8e-87286f59748d Version: $LATEST
2021-02-22T15:57:14.867Z 933ca3dd-2feb-4f98-8f8e-87286f59748d INFO before call
2021-02-22T15:57:15.560Z 933ca3dd-2feb-4f98-8f8e-87286f59748d INFO ret: {"ResponseMetadata":{"RequestId":"bf65a9f5-e4a6-493b-a6a2-c3081d88f7be"},
"Users":[
{"Path":"/","UserName":"username","UserId":"sadsadsadsa",
"Arn":"arn:aws:iam::1234567890:user/username",
"CreateDate":"2020-11-27T13:09:20.000Z","Tags":[]},
{"Path":"/","UserName":"tempuser","UserId":"adsadasdasdsad",
"Arn":"arn:aws:iam::1234567890:user/tempuser",
"CreateDate":"2021-01-24T21:24:47.000Z","Tags":[]}],"IsTruncated":false}
END RequestId: 933ca3dd-2
There are a few possibilities here:
Lambda Role Permission - Try to check if your lambda role is attached with the correct IAM Policy such as arn:aws:iam::aws:policy/IAMReadOnlyAccess
If your Lambda function is placed within a Public Subnet or Private Subnet without any internet access, you would require arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole attached as well as the internet or aws services access (shown here)
I am trying to use the Node.js sample code that AWS Secrets Manager provides to read a secret value, and am putting this code inside a Lambda function. However, I can't seem to get into the function that handles the response from getting the secret value.
The Lambda role has AdministratorAccess permissions to rule out it being a permissions issue.
Lambda Code:
exports.handler = async (event) => {
// Load the AWS SDK
var AWS = require('aws-sdk'),
region = "us-east-1",
secretName = "/my-secrets/level1/level2",
secret,
decodedBinarySecret;
var client = new AWS.SecretsManager({
region: region
});
console.log('above')
client.getSecretValue({SecretId: secretName}, function(err, data) {
console.log('in')
if (err) {
throw err;
}
else {
if ('SecretString' in data) {
secret = data.SecretString;
} else {
let buff = new Buffer(data.SecretBinary, 'base64');
decodedBinarySecret = buff.toString('ascii');
}
}
console.log(secret)
});
console.log('below')
};
OUTPUT
2020-03-05T18:51:54.547Z a3101875-a1f4-4b6f-ac62-3c2f93f5941f INFO above
2020-03-05T18:51:54.947Z a3101875-a1f4-4b6f-ac62-3c2f93f5941f INFO below
Because the secret exists, I would expect to see "in" and the secret lines in the output...what is preventing it from getting inside that function?
Change your call to be a promise:
const data = await client.getSecretValue({SecretId: secretName}).promise();
The problem you are running into is that the lambda is ending execution before your callback is executed. AWS Lambda Function Handler in Node.js
The above solution works, but for a full code example, please refer to this link: https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/secrets/src/secrets_getsecretvalue.js
I'm new to AWS lambda functions and was given some sample code (below -- in the actual code I fill in the placeholders correctly, of course). But each time I call the lambda function, I get
Error [ConfigError]: Missing region in config
at Request.VALIDATE_REGION (/Users/abc/Documents/projects/bot/node_modules/aws-sdk/lib/event_listeners.js:92:45)
Even though the region is set in aws.config.update. I'm not sure what to do to fix this. I've tried removing the call to aws.config.update, removing the reference to region, but nothing helps.
I'd also be keen to know if there's a way to load the credentials from the shared file in ~/.aws/credentials, instead of having to enter them directly here.
Thanks for any help!
const aws = require('aws-sdk');
// do this only in dev, in prod you will not need to put your keys...
aws.config.update({accessKeyId: '<YOU ACCESS KEY>', secretAccessKey: '<YOUR SECRET>', region:'ap-northeast-1'});
const lambda = new aws.Lambda();
function invokeLambda(options) {
return new Promise((resolve, reject) => {
lambda.invoke(options, (err, data) => {
if (err) {
return reject(err);
}
return resolve(data);
});
});
}
const sampleCall = async () => {
try {
const options = {
FunctionName: '<NAME OF THE FUNCTION YOU WANT TO INVOKE>',
Payload: '<The JSON.stringify of the object you want to provide as parameter>',
}
const result = await invokeLambda(options);
console.log(result);
} catch (err) {
console.error(err);
}
};
You can configure the region before using any services.
like this:
var AWS = require('aws-sdk');
AWS.config.update({region:'us-east-1'});
const lambda = new aws.Lambda();
AWS services such as lambda has the ability to assume an IAM Role. Because the applications does not need to store credentials.
here is what you should do:
The IAM role is attached to the lambda
Permissions are then attached to the IAM role
Basically you can attach the same policy that your IAM user is using to the IAM role. After doing that, you can remove credentials from the code.
Reference:
https://aws.amazon.com/blogs/security/how-to-create-an-aws-iam-policy-to-grant-aws-lambda-access-to-an-amazon-dynamodb-table/
Hey No need for configure the whole AWS setttings. if you want to keep it unconfigured and not for all of your request to use the region.
The lambda constructor receive 'region' param just set it to your desired region.
Example:
const lambda = new Lambda({
region: 'us-east-1'
});
lambda.invoke({ FunctionName: 'your-function-name'},
function(err, data) {
if(err) {
console.log(err, err.stack);
}
else {
console.log(data);
}
}
);
I have this Lambda function code which is invoked by an SQS.
SQS triggers my Lambda function ( in nodeJS).
Lambda will also send out an SES email. Is there a way I can test this on my local Ubuntu rather than always using AWS web console?
Any help is appreciated.
Here is my Lambda NodeJS code: This code works only on AWS Lambda. When I run
$node index.js , it does not send out SES email.
var aws = require("aws-sdk");
var nodemailer = require("nodemailer");
aws.config.loadFromPath('aws_config.json');
var ses = new aws.SES();
var s3 = new aws.S3();
// Set the region
aws.config.update({region: 'us-west-2'});
exports.handler = function (event, context, callback) {
const response = {
statusCode: 200,
body: JSON.stringify({
message: 'SQS event processed.',
input: event,
}),
};
console.log('event: ', JSON.stringify(event.Records));
result = JSON.stringify(event.Records)
result = result.replace(/(^\[)/, '');
result = result.replace(/(\]$)/, '');
var resultObj = JSON.parse(result);
var idCustomer = resultObj.body;
console.log('===SENDING EMAIL====');
// Create sendEmail paramssd
var params = {
Destination: {
/* required */
CcAddresses: [
'XXXXX#gmail.com',
/* more items */
]
},
Message: {
/* required s*/
Body: {
/* required */
Html: {
Charset: "UTF-8",
Data: "BODY:"
},
Text: {
Charset: "UTF-8",
Data: "TEXT_FORMAT_BODY"
}
},
Subject: {
Charset: 'UTF-8',
Data: idCustomer
}
},
Source: 'xxxx#eeeee.com', /* required */
ReplyToAddresses: [
'wwwwww#wwwwwwwww.com',
/* more items */
],
};
// Create the promise and SES service object
var sendPromise = new aws.SES({apiVersion: '2010-12-01'}).sendEmail(params).promise();
// Handle promise's fulfilled/rejected states s
sendPromise.then(
function (data) {
console.log("Successfully sent using SES");
console.log(data.MessageId);
}).catch(
function (err) {
console.log("An Error occured while senting using using SES");
console.error(err, err.stack);
});
};
You should definetely take a look at SAM LOCAL. It is a tool developed by the AWS team specifically for testing lambdas.
https://github.com/awslabs/aws-sam-cli
Publishes a version of your function from the current snapshot of
$LATEST. That is, AWS Lambda takes a snapshot of the function code and
configuration information from $LATEST and publishes a new version.
The code and configuration cannot be modified after publication. For
information about the versioning feature, see
It is easy to use, you just type
sam local invoke --event event.json
And behind the scenes it will run a docker cotnainer for your lambda and call it.
Regarding your SES, you should put a small if(SAM_LOCAL) condition in the code and call the real one only if not in local mode. Note that SAM_LOCAL is env variable set by the SAM LOCAL tool when you run a function locally.
Good luck !
If you want to use aws as a backend - serverless framework is probably what you looking for https://serverless.com/ If you want to test your code without executing lambda on aws backend take a look at localastack framework https://github.com/localstack/localstack
My problem
I am writing a simple js function that reads some information from AWS CloudWatch Logs.
Following the answer at Configuring region in Node.js AWS SDK, and the AWS nodejs SDK documentation, I came up with the following:
Code
var AWS = require('aws-sdk');
var cloudwatchlogs = new AWS.CloudWatchLogs();
console.log(AWS.config.region) // Undefined
AWS.config.region = 'eu-central-1' // Define the region with dot notation
console.log(AWS.config.region) . // eu-central-1
AWS.config.update({region:'eu-central-1'}); // Another way to update
console.log(AWS.config.region) . // eu-central-1
var params = {
limit: 0,
// logGroupNamePrefix: 'STRING_VALUE',
// nextToken: 'STRING_VALUE'
};
// This call is failing
cloudwatchlogs.describeLogGroups(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
Output and error
undefined
eu-central-1
eu-central-1
{ ConfigError: Missing region in config
at Request.VALIDATE_REGION (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/event_listeners.js:91:45)
at Request.callListeners (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at callNextListener (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
at /Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/event_listeners.js:85:9
at finish (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/config.js:315:7)
at /Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/config.js:333:9
at SharedIniFileCredentials.get (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/credentials.js:126:7)
at getAsyncCredentials (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/config.js:327:24)
at Config.getCredentials (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/config.js:347:9)
at Request.VALIDATE_CREDENTIALS (/Users/adam/binaris/adam-test-sls/node_modules/aws-sdk/lib/event_listeners.js:80:26)
message: 'Missing region in config',
code: 'ConfigError',
time: 2017-07-11T09:57:55.638Z } ...
Environment
The code is running locally under node v8.1.2.
My question
How can I correctly configure the region in the AWS js SDK?
Addendum
Opened an issue on github and got some response.
Or, alternatively, you can specify that when creating your cloudwatch object:
var AWS = require('aws-sdk');
var cloudwatchlogs = new AWS.CloudWatchLogs({region: 'eu-central-1'});
Write code in following way it will work.
var AWS = require('aws-sdk');
// assign AWS credentials here in following way:
AWS.config.update({
accessKeyId: 'asdjsadkskdskskdk',
secretAccessKey: 'sdsadsissdiidicdsi',
region: 'eu-central-1'
});
var cloudwatchlogs = new AWS.CloudWatchLogs({apiVersion: '2014-03-28'});
Use following.
AWS.config.update({region: 'eu-central-1'});
You can find more information in following link.
http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html