For one of the projects, I was supposed to publish a new resource to the existing API. AWS API Gateway allows you to deploy the same API for different stages. It separates deployments of the same code for different environments, enabling "code once" principles. But you already see where the trap is.

Most likely, you have different backends for different tiers, maybe in different accounts. That means when you deploy a new version of API, you have to change your targets appropriately. AWS offers a solution - stage variables.

Let's see how to use stage variables and reuse the same code across all environments.    

Prepare Backend Lambdas

Since AWS Lambda is not the show's star, I have created two simple functions with different names and status messages.

Sample Lambda Function

Create a New API

For demo purposes, I created a new regional RESTful API from scratch.

Now, add a new resource with the creative name "lambda." Do not forget to enable API Gateway CORS.  

Define a resource for the new API

Now add the POST method to the existing resource. To do so:

  • Select /lambda resource;
  • Click the Actions button;
  • Then use the "Create Method" item from the drop-down menu.
  • Select POST from the new blank method  and then click the "Ok" icon next to the method selector;
Add the new method to the API resource. 

For  the method setup window, I configured:

  • Integration Type: Lambda Function
  • Use Lambda Proxy Integration: Checked
  • My Region: us-east-1
  • Lambda Function: lambda-stage
  • Click the "Save" button to complete the method configuration.  
  • API wizard will warn you that you are giving execution permission for the Lambda function.  Click "Ok"
Configured POST Method with Lambda attached
  • Click on the Client's "Test" link to validate our configuration.
  • You can put anything into headers and Request body and click "Test."
  • If API Gateway has all the privileges and Lambda is deployed properly, you will get the function response
Test POST method before deployment. 

Now our demo API is ready for deployment.

  • Click on "Actions" and then select "Deploy API"
  • For the Deployment stage, select [New stage]
  • Give a Stage name, for Example - "stg"
  • Give some meaningful descriptions for the environment and deployment and click "Deploy."

Now you have an additional entity available - Stage.  Stage allows you to control some aspects of the  API deployment. For this demo we focus on Stage variables.

We need another stage for the production deployment. Let's quickly repeat some of the configuration steps:

  • Select "Resources" from the navigation pane.
  • Navigate to the /lambda{POST} method
  • Click on Integration Request to open the configuration form
  • Replace your staging Lambda with the production one. In my case, I change lambda-stage to lambda-prod.
  • Deploy the updated API to the new "prd" stage.

Upon completion, you should have both stages with identical API but different code behind it.  Let's run some tests from the AWS Cloud Shell.

# curl - Test HTTP/s RESTful resources. jq - JSON query tyo format output  
curl -s -d '{"test":"messgae"}' https://xxxxx.execute-api.us-east-1.amazonaws.com/stg/lambda |jq
Test deployed APIs 

It is time to untangle the API source from the deployment stage

Implementing Stage Variables

  • Select "Stages"  from the API navigation panel
  • Select "stg" from the Stages tree
  • Select "Stage Variables" tab
  • Click "Add Stage Variable" and set the name to "LambdaName"  and value to your staging Lambda ARN. You can use only the Lambda name if your functions are under the same account.
Stage Variable LambdaName
  • Select "Resources"  then POST method under "/lambda" resource.
  • Click on the "Integration Request" and edit the "Lambda Function"  field. Make a note that now the integration request points to production Lambda.
  • Set ${stageVariables.LambdaName} as a new value.
  • Confirm the change and accept the warning.
  • Use the "Actions" button to deploy the updated API to "stg."
  • Now create a variable with the same name for the "prd"  stage.
  • Give it a  production Lambda name or ARN.
  • Make a new deployment to "prd".

Let's make sure that our functions are still reachable and we get a response from both environments.

Final function tests

A Quick Recap

  • The AWS API Gateway allows you to deploy the same API to multiple environments.
  • API Gateway offers stage variables that allow you to disconnect the API code from the backend specifics.
  • Stage variable may contain a function name (i.e. "my-lamnbda-func") if the API and Lambda belong to the same account, or full-qualified ARN ("arn:aws:lambda:my-region:11111111111:function:my-lambda-name") for cross-account deployments.
  • You can use stage variables for message enrichment or to provide environment-specific information for the backend.