Skip to content

API Gateway + SAM

0

I am creating an API Gateway along with the corresponding Lambdas that act as API endpoints. My idea is to have them separated into two stages: test and prod. I would also like to use stage variables. All of this is being developed using Infrastructure as Code with AWS SAM.

At the moment, I have a GitHub repository with two branches, test and prod, which deploy to the corresponding API stage.

Currently, I am creating the API and its resources in the production stack, along with the corresponding Lambdas and the stage with its stage variables. In the test stack, I only create the Lambdas related to test and the stage with its stage variables.

Right now, when running sam deploy, the stages are not being deployed, which is something I would like to fix. At the same time, I would appreciate an opinion on how much the overall structure could be improved. I am not sure whether creating the API and its resources in the production stack is the best option, but I am also not convinced that creating them in the test stack is ideal either. Another option I am considering is separating the API and all its resources into a different stack from the ones that create the Lambdas. Any guidance would be appreciated.

2 Answers
1
Accepted Answer

To address your issue with stages not being deployed when running sam deploy, there are a few key considerations and potential solutions:

First, when creating an API Gateway using AWS SAM, you need to specify the StageName property in your AWS::Serverless::Api resource. However, there's a known issue where the default stage is created as "Prod" regardless of what you specify. To fix this, you need to include the OpenApiVersion property in your template (the value doesn't matter - it could be 2.0, 3.0.1, etc.), which enables the stage name fix.

For your overall architecture, here are some approaches to consider:

  1. Single API with multiple stages: Create one API Gateway resource in a shared stack, then deploy different stages (test, prod) with their respective stage variables. This approach keeps your API definition consistent across environments.

  2. Separate stacks for infrastructure and implementation: Consider a three-stack approach:

  • Core infrastructure stack: Contains the API Gateway definition and resources
  • Test stack: Contains test-specific Lambdas and stage configuration
  • Prod stack: Contains production-specific Lambdas and stage configuration
  1. Stage variables for environment-specific configuration: Use stage variables to point to different Lambda functions or configurations based on the stage. For example, you could have a stage variable like functionName that points to different Lambda functions in test vs. prod.

When using stage variables with Lambda functions, remember that you'll need to manually configure permissions for the Lambda functions using the aws lambda add-permission command or equivalent CloudFormation/SAM resources.

For deployment, remember that in API Gateway, you need to create both a stage and a deployment. The deployment captures the current state of your API, and the stage makes that deployment accessible. When using SAM, the deployment should happen automatically when you specify the StageName property correctly.
Sources
Iterate rapidly, stay agile - AWS Serverless Multi-Tier Architectures with Amazon API Gateway and AWS Lambda
I want to change the Stage created when creating API Gateway with AWS SAM from Prod to a custom name | AWS re:Post
Use stage variables for HTTP APIs in API Gateway - Amazon API Gateway
Can't create API Gateway stage/deployment: Missing required key 'deploymentId' in params | AWS re:Post

answered 8 months ago

AWS
EXPERT

reviewed 8 months ago

  • Thanks for your answer!

0

For API Gateway stages in SAM, you need to explicitly define them in your template—SAM doesn't automatically deploy stages. Add a AWS::ApiGateway::Stage resource for each environment:

TestStage:
  Type: AWS::ApiGateway::Stage
  Properties:
    StageName: test
    RestApiId: !Ref MyApi
    DeploymentId: !Ref MyApiDeployment
    Variables:
      LambdaAlias: test
      OtherVar: value

ProdStage:
  Type: AWS::ApiGateway::Stage
  Properties:
    StageName: prod  
    RestApiId: !Ref MyApi
    DeploymentId: !Ref MyApiDeployment
    Variables:
      LambdaAlias: prod
      OtherVar: value

For your architecture, separate the API Gateway resources into their own base stack (shared between test/prod) and create Lambda stacks per environment that reference the base API—this prevents drift and maintains consistency. Use stage variables to point to Lambda aliases (${stageVariables.LambdaAlias}), allowing each stage to invoke its respective Lambda version while sharing the same API definition and resources across environments

answered 8 months ago

  • Thanks for your answer!

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.