HTTP API Integration with lamda function and stage variable not working


I have an HTTP API with two stages dev and prod. Each stage has a stage variable 'environment', for the dev stage the value is 'blue' and for the prod stage the value is 'red'.

I have a helloworld lambda function that has two aliases 'red' and 'blue'. Each of the aliases points to a different version of the lambda function.

Using the console:

I created a lambda function integration using the arn of the helloworld function and the stage variable: arn:aws:lambda:us-east-1:XXXXXX:function:helloworld1:${stageVariables.environment}

From this AWS blog post , I understand that I cannot use the "Grant API permission . . . " toggle and instead must use an ARN of a role that has permissions to invoke the lambda function. After some investigation, I understand that this role must have iam:PassRole permission. I've entered the ARN of a role that has IAMFullAccess.

I can save the integration and then attach the integration to a GET /helloworld endpoint.

With that all set up, https://<domain>/dev/helloworld or https://<domain>/prod/helloworld both return a response: 404 Not Found.

How do I set up an HTTP API to use stage variables to select the alias of the integrated lambda function? What exactly must the IAM role be capable of to make this work?



Edited by: T. Hoag on Aug 3, 2021 9:16 PM

T. Hoag
asked 3 years ago789 views
1 Answer

To make an HTTP API integration work with stage variables and a lambda function with aliases:

  1. Create an HTTP API. (not REST)

  2. Create two or more stages in the API. For this example, I'm creating two stages and naming them ‘development’ and ‘production’.

  3. In each stage, create a stage variable 'lambda_alias'. In the ‘development’ stage, give the variable the value 'dev' and in ‘production’: 'prod'. Deploy the stages of the API if they are not auto-deployed.

  4. In your lambda function, create an alias called 'prod' and have the alias point to the first version of your lambda function. Create a second alias 'dev' and have it point to $LATEST. In this example, the lambda function is named ‘helloworld1’ . This assumes that the lambda function has at least one version and has been deployed one or more times since the version was made. Both version 1 and the latest deployment provide output that are different (so that on you can check that the setup is working properly).

  5. Save and copy the ARN of the helloworld1 function.

  6. Back in the API console, create a lambda function integration.

  7. For the lambda function name, you cannot use the lambda function name from the drop down OR the lambda function ARN that you previously copied. Instead, you must use a gateway ARN with the invocations action. Use the following as a template with your values for region and the previously copied function ARN. Do not make any substitutions for ${stageVariables.lambda_alias}


  1. Save (Create button) the integration.

A side-note on the “Why?” for the remaining steps. When you create the integration with a lambda function that contains a stage variable, it opens a small security hole. Left unchecked, the integration would run any aliased version of the lambda function. A bad actor could add an alias to the lambda function to accomplish some nefarious purpose. To prevent this bad behavior, AWS security takes a disallow stance on all integrations with a lambda function that use stage variables. The following steps tell AWS which alaised versions of the lambda function to allow.

  1. After the save operation is complete, there is an “Invoke Permission” section on the “Integration details for route”. Expand the details for that section.

  2. The ‘Example Policy Statement’ must be run for each lambda function alias. Do not run the code example as written: run it once for each of your lambda function aliases that you want API Gateway to have permission to run, substituting the alias value for ${stageVariables.lambda_alias}. Using a configured AWS CLI with a user that has sufficient privileges, run the ‘add-permission’ command for both helloworld1:dev and helloworld1:prod. Double check that you get a response similar to the one shown on the integration details page.

  3. Attach the integration to an API route -- I’m using ‘howdy’ as the route.

  4. Make a request to the /production/howdy and the ‘prod’ alias of the lambda function will be invoked. A request to the /development/howdy will invoke the ‘dev’ alias of the lambda function.

Releasing new versions of a lambda function will only require you to update which version of the function that prod and dev aliases point to. You do not need to make any additional changes to the API integration.

T. Hoag
answered 3 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions