Using stageVariables in lambda integration for API Gateway raises validation error
Asked Answered
O

1

7

I have two stages for my API Gateway (dev and prod). I want each to point to dev and prod lambda aliases, respectively. I tried using stageVariables in the lambda integration but this raises validation errors and API Gateway doesn't have permissions to invoke the lambda then. I cannot change the permissions policy from the lambda dashboard to include the stageVariables either.

First, I added a stage variable (LAMBDA_ALIAS) to each stage, with the appropriate value. I tried appending :${stageVariables.LAMBDA_ALIAS} to the lambda ARN. When I save this, the changes persist but a validation error appears at the top of the dashboard:

1 validation error detected: Value 'arn:aws:lambda:us-east-2:xxx:function:auth:${stageVariables.LAMBDA_ALIAS}' at 'functionName' failed to satisfy constraint: Member must satisfy regular expression pattern: (arn:(aws[a-zA-Z-]*)?:lambda:)?([a-z]{2}((-gov)|(-iso(b?)))?-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?

In addition, I noticed integration errors in CloudWatch logs after hitting the API route: "The IAM role configured on the integration or API Gateway doesn't have permissions to call the integration. Check the permissions and try again."

I've followed this guide to create a new integration with the full invocation ARN, but that didn't work either (it resolved to the lambda ARN). Finally, I tried issuing the JSON statement via the cli (aws lambda add-permissions) but that returned the same regex error as seen above.

Here's the JSON statement I used:

{
  "StatementId": "xxx",
  "Action": "lambda:InvokeFunction",
  "FunctionName": "arn:aws:lambda:us-east-2:xxx:function:auth:${stageVariables.LAMBDA_ALIAS}",
  "Principal": "apigateway.amazonaws.com",
  "SourceArn": "arn:aws:execute-api:us-east-1:xxx:xxx/*/*/auth"
}

I've stumbled across several video/blog tutorials that use stage variables to point API Gateway stages to different lambda versions/aliases, so my question is threefold: (1) does AWS still support this?, and (2) if so, how does one implement?, and (3) if not, what are alternative approaches?

Ocam answered 17/11, 2022 at 20:42 Comment(0)
C
1

Did you manage to fix the issue?

My issue was somewhat similar, I guess, I was trying to set up an HTTP API, with stages for dev and prod, and couldn't get the stageVariables to work when defining integration (via the UI).

After some digging around, I managed to solve it by:

  1. creating an IAM Role for API Gateway
  2. creating 2 IAM Policies for Lambdas (allowing the invokeFunction) One for DevPolicies and one for ProdPolicies, something like:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": [
                "arn:aws:lambda:<region>:<id>:function:do-something-one:<prod/dev>",
                ...
            ]
        }
    ]
}

Replacing the <region>,<id> with your relevant values for those, and <prod/dev> with the alias of the function you want to tie to this policy.

  1. Then I added these two policies into the Role, and used this IAM Role for the API Gateway Route integration (I had to untick the default 'Grant API Gateway permission to invoke your Lambda function' and then it allows manual input of which Role to use): Screenshot of the portion of the UI

This allowed me to successfully save the integration, and used different aliases for the lambda functions depending on which stage URL I accessed.

I assume one could create 2 Roles - one for Production and one for Development, and possibly use stageVariables.iamRole to further split permission based invocations, but that did not work for me as it complained about iamPassRole not being allowed.

Counterplot answered 7/2, 2023 at 11:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.