I have the following Lambda function configured in AWS Lambda :
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();
exports.handler = function(event, context) {
var item = { id: 123,
foo: "bar"};
var cb = function(err, data) {
if(err) {
console.log(err);
context.fail('unable to update hit at this time' + err);
} else {
console.log(data);
context.done(null, data);
}
};
// This doesn't work. How do I get current stage ?
tableName = 'my_dynamo_table_' + stage;
dynamo.putItem({TableName:tableName, Item:item}, cb);
};
Everything works as expected (I insert an item in DynamoDB every time I call it).
I would like the dynamo table name to depend on the stage in which the lambda is deployed.
My table would be:
my_dynamo_table_staging
for stage staging
my_dynamo_table_prod
for stage prod
However, how do I get the name of the current stage inside the lambda ?
Edit: My Lambda is invoked by HTTP via an endpoint defined with API Gateway
In Stage description, type a description for your new stage, and then choose Deploy. To apply the change, deploy the API to a new stage called prod: Next, set up the stage variable in the new deployment stage to point to the second Lambda function, GetHelloWithName : Now you are ready to test!
To deploy an API, you create an API deployment and associate it with a stage. A stage is a logical reference to a lifecycle state of your API (for example, dev , prod , beta , v2 ). API stages are identified by the API ID and stage name. They're included in the URL that you use to invoke the API.
A stage is a named reference to a deployment, which is a snapshot of the API. You use a Stage to manage and optimize a particular deployment. For example, you can configure stage settings to enable caching, customize request throttling, configure logging, define stage variables, or attach a canary release for testing.
If you have checked "Lambda Proxy Integration" in your Method Integration Request on API Gateway, you should receive the stage
from API Gateway, as well as any stageVariable
you have configured.
Here's an example of an event
object from a Lambda function invoked by API Gateway configured with "Lambda Proxy Integration":
{
"resource": "/resourceName",
"path": "/resourceName",
"httpMethod": "POST",
"headers": {
"header1": "value1",
"header2": "value2"
},
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"accountId": "123",
"resourceId": "abc",
"stage": "dev",
"requestId": "456",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "1.1.1.1",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "agent",
"user": null
},
"resourcePath": "/resourceName",
"httpMethod": "POST",
"apiId": "abc123"
},
"body": "body here",
"isBase64Encoded": false
}
I managed it after much fiddling. Here is a walkthrough:
I assume that you have API Gateway and Lambda configured. If not, here's a good guide. You need part-1 and part-2. You can skip the end of part-2 by clicking the newly introduced button "Enable CORS" in API Gateway
Go to API Gateway.
Click here:
Click here:
Then expand Body Mapping Templates
, enter application/json
as content type, click the add button, then select mapping template, click edit
And paste the following content in "Mapping Template":
{
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
#end
},
"stage" : "$context.stage"
}
Then click the button "Deploy API" (this is important for changes in API Gateway to take effect)
You can test by changing the Lambda function to this:
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();
exports.handler = function(event, context) {
var currentStage = event['stage'];
if (true || !currentStage) { // Used for debugging
context.fail('Cannot find currentStage.' + ' stage is:'+currentStage);
return;
}
// ...
}
Then call your endpoint. You should have a HTTP 200 response, with the following response body:
{"errorMessage":"Cannot find currentStage. stage is:development"}
Important note:
If you have a Body Mapping Template
that is too simple, like this: {"stage" : "$context.stage"}
, this will override the params in the request. That's why body
and headers
keys are present in the Body Mapping Template
. If they are not, your Lambda has not access to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With