-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutliple API stages but in a single document - best practice #198
Comments
I too would very much like to see some better examples. I've spent quite a lot of time just figuring out how all of these parts work together. I'm fairly certain now I have a reasonable grasp of the current situation. And there certainly seems to be a disconnect with what's being documented as capable and what actually makes sense in actual operations... That being said @mikebrules, this is where I'm at. I have a script that wraps the cfn package/deploy which takes in any stage related variables i.e STAGE, VPCID, things like that. Here it is
I have a single SAM template that gets executed for each
And finally, here is the swagger doc used to generate the API Gateway API
You may have noticed a few things here; First off stages at this point in either Cloudformation native or SAM seems very clunky, remember cloudformation is toted as a tool for resource creation, not orchestration. You can feel it here... Secondly, you'll notice I'm not using lambda versions as they were intended either. This one I think has a lot more technical issues that would need to be resolved to make sense entertaining. There is a serious breakdown in the pipeline of this, basically, you need Lambdas -> Versions -> Aliases all this seems fine and dandy in theory, all the parts are technically there... However, in practice, it breaks down in a number of spots which required special maneuvers (hacks?) to accomplish. All the way from requiring DSL's to produce CFN deployable templates to custom Lambdas used to transition/upgrade/roll forward your actual Lambdas (if you want versioning). |
hi @zodeus thanks for the detailed post. Very useful indeed. I am in total agreement that the main breakdown is around managing versioning, specifically of Lambdas in my case which is causing me some confusion. Lambda out the box gives me a sensible versioning model with the use of aliases - I don't want multiple Lambda versions per environment, and nor, I expect, does AWS recommend that- its just that SAM is not yet able to support them. I have managed to get Lambdas working with versions and aliases in SAM, but it is a mess in all honesty. I have a client who I want to ship a nice, tight set of cfn to, and at the moment, its hard to do that. I post my approach too as a contrast |
@zodeus Does the template you show here actually work? I am doing something very similar, but I can neither get the local swagger file to work, nor get the stageName variables to show. For the local swagger file I get
and for the stageVariable my lambda is named in the api as ${stageVariable.myFunction}. It doesn't actually get translated. |
Never mind. I have worked past it. |
Ya, sorry about that, I had originally taken some production code and tried to obfuscate it. Clearly, I lost some details ;). Glad you worked through it. |
@badfun, in the AWS UI seeing that variable as the function name is correct, also the function trigger on the lambda will look broken, however, when a Stage is deployed, it populates that variable and everything gets linked together. Although through the UI it doesn't appear so. |
Thanks @zodeus. I figured out that I was misunderstanding stage variables and it was actually working. For the api that I am creating I've gone with the 'Fn::Transform' 'AWS::Include' option. Seems to be working out so far. |
After spending some time looking deeper into this, including coming across this issue, we wrote up a summary. Maybe you’ll find it interesting. |
thanks @christianklotz I will take a good look |
Hello, I am new to CFN and AWS SAM.
OR I can leave out the |
Hi @rohitrishi - I'm not sure this is what you wanted, but just in case - you can use the "lambda proxy" config to ensure every route on your api is directed to a single lambda function. I'm assuming you can mount this path like any other route and it should help trim down your function in cfn. Take a look at this Apologies if this isn;t what you wanted. On the multiple api stages best practice, we (and quite a few others I know) just rolled over on that one. Its not easy by any means and the model is still confused. @christianklotz write up (^ up there) is worth a read for sure |
@mikebrules just wonder if u set your API gateway stage to use a specific version of your lambda. I realized API Gateway always points to the latest version of my lambda so there is no point of manually publishing to a Prod stage after using CloudFormation to publish to a Dev stage. I am trying to figure out how to use lambda versioning properly with API Gateway stages |
@Jun711 yes, you can do that. You just need to try and bind the Lambda references in your API Definition to
Note the
Does that make sense? |
@mikebrules Thanks Mike. It makes sense. 2 questions: I am using SAM template and trying it with the following template:
and
|
HI @Jun711 I use API Gateway versioning alongside Lambda Versioning/ALiasing. My stack.yaml just includes multiple stage definitions. You can achieve what (I think) you want by defining a stage in your cloudformation that is constructed from environment variables - every time you run your deployment, the stack yaml is called with a new Environment version and the API Gateway stage (and Lambda mappings) are created just for that stage. The other way is to define ALL stages in your stack, and use |
@mikebrules thanks. I will give it a try.
If I run the template twice with a different ENV param, it will remove my previous stage, so do I create all my stages in the API definition (presumably using normal Cloudformation Type::Stage to reference the Serverless::Api)? EDIT: |
HI @Jun711 yes, you've hit the part of the recommendation about defining everything once and passing in an ENV - it doesn't work like it should. Easiest solution is to do is define everything (all environments) in one stack.yaml file, but that means you've got ALL your api gateway envs in the file, but only a single version of the lambda - this is why it doesn;t hold together. Otherwise, what I now do is define an API PER environment (I don't use stages) and a Lamba per environment - it feels wrong, but its much, much easier.... |
@Jun711 you may be interested in our experience with multiple stages as described in this article. The gist is we started with a single stack defining all environments, eventually moved away from it and have a single template that brings up one stack and can be repurposed for multiple environments. One of the main reasons is to limit the "blast radius" in case things go wrong during development – you don't accidentally want to bring down the production environment during a development deployment. Also this gives you much finer control over permissions, etc. |
Thanks @mikebrules @chrisradek I will check out your suggestions. Btw, I noticed this. It could be a bug but if we manually deploy to another stage on API Gateway console, when you redeploy using a SAM yaml file, it doesn't seem to delete the stages. |
Hi guys,
|
This is an important feature and I'll make sure we get it scheduled. In the meantime, I'd appreciate any suggestions/ideas people have of what the schema/API should look like. Perhaps a |
Current if I create two API with different stageName, it will create two RestApi with these stages, not two stages in one RestApi. Seems no way to have two stages in one Api. |
@badfun , you said you've worked past the issue of stageVariable not resolving in swagger yaml. It would be great help if you can comment on how you did that. I'm facing the exact same issue with function name resolving to ${stageVariable.Stage}_<function_name> instead of resolving stageVariable.Stage. |
Hi, is there an ETA for this fix? This really impedes development and adopting SAM and leveraging infrastructure as code. Thanks. |
What a ridiculous mess to just do dev/test/stage/production. |
I'm not sure what the mess is or what AWS or SAM should do. I'm having a great time using the single stack arch in this article (https://hackernoon.com/managing-multi-environment-serverless-architecture-using-aws-an-investigation-6cd6501d261e) with a StageName parameter that helps drive everything from tagging to other parts of my template using intrinsic functions. |
@gpasq for multi-stage/environment development it's best to spin up a new stack for each environment/stage, and if you have the means to, they should also be deployed into separate AWS accounts for more isolation. We certainly need to improve our documentation around this (and more). |
How do you manage environment variables? Assuming a single template + multiple stage deployments is the recommended way with a Maintain 10+ or 20+ variable long Thinking of just using |
@Tanbouz there is the option of using Conditions to manage this kind of stuff, but in all honesty, its going to be a nightmare. I gave up a year ago on managing multiple API Gateway stages. The model just isn't there and the hacks are awkward for little actual benefit. We deploy an API per environment, and a Lambda per Environment, which feels broken from a 12-factor app model, but is actually very workable, and you won't regret it once you've got over the guilt :) |
@Tanbouz it can be a bit misleading that API Gateway and Lambda both have their own concepts of environments (stages and aliases) but it may be better not to follow them and go for the one-stack-per-environment approach (see my previous comment). There are still good use cases for the use of stages and aliases – AWS just gives you plenty of options which can be a bit overwhelming at times. |
I’m using Serverless now, which is one stack per environment, and it works very well. Trying to use multiple environments in a single stack is infeasible, IMO
Regards
-Greg Pasquariello
… On Oct 2, 2018, at 2:47 PM, Christian Klotz ***@***.***> wrote:
@Tanbouz <https://github.com/Tanbouz> it can be a bit misleading that API Gateway and Lambda both have their own concepts of environments (stages and aliases) but it may be better not to follow them and go for the one-stack-per-environment approach (see my previous comment).
There are still good use cases for the use of stages and aliases – AWS just gives you plenty of options which can be a bit overwhelming at times.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#198 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/ADoBfQU5PCKDhLSsk8ovn-8UNBB9SxZmks5ug9DRgaJpZM4PXWo8>.
|
Sorry, I was not clear. I meant multiple environments or stacks. I already started refactoring my template as everyone here suggested. Till now it is looking great 👍 . The discussion here and resources linked were extremely helpful, thanks. I was wondering how is everyone managing their SAM serverless application configs when using this pattern. A large number of Lambda environments variables used as configs for a serverless application are a hassle to manage. I need to pass different values per environment into a single template that takes the parameters over the command line. Prefer to
Options I'm currently aware of... (1) Include configs in application code. Load appropriate configs per
(2)
(3) CloudFormation dynamic SSM references
(4) Get configs using SSM API during runtime.
(5)
(6) CodePipeline's Template configuration
(7)
(8) Template parameter defaults
(9) CloudFormation conditions
I will give it a shot in the coming days and see how it goes. It was not as clear until I wrote this up. I felt overwhelmed as with API stages and Lambda aliases. Any other recommendations/suggestions are welcome. |
@Jun711 were you still using the single stack for multi-stage api gateway deployment? I was running into the same issue where the SAM template remove my previous stage on Api gateway if I deploy it on a second time with a different StageName. Any workaround will be appreciated! |
I'm too facing the same issue. SAM template deployment replaces my previously created stage with new one. |
@Joycechocho @lucky2siddharth However, I have learnt from others from this discussion and started deploying a Lambda and an API for each environment(one stack per environment). It is easier to manage. You can check out Continuous Integration and Continuous Deployment(CI/CD) using AWS CodePipeline and AWS CodeStar to see how to set up. |
any one got any solution to handle multiple stages under API gateway using serverless SAM. |
I agree with the approach of : In my environment I have 3 separate pipelines, each connected to a different branch of my source. I pass the parameter at codebuild time. This works well, and doesn't mangle all three environments in case of a "stack rollback". My codepipeline and codebuilder are also templated to accomplish this feat with a single parameter "dev","prod",or "qa". |
Looks like the initial ask/question has been answered in this thread, namely SAM's current design only accepts a single Stage and multiple stages should be another stack. I realize this isn't everyone's setup but is the current approach we have taken. If there is an ask to support multiple stages, please create a new issue (there might be another issue already for this, but haven't checked). Closing as the initial issue was answered |
Given that it has been two years since this discussion, I would like to inquire if there have been any updates regarding support for multiple stages in AWS SAM. Specifically, does SAM now allow deploying an API Gateway into multiple stages, similar to what is possible via the API Gateway console UI? Or is using a unique stack per stage still the only solution available when working with SAM? |
Hello - I read the Best Practice guidelines for SAM Online Tech Talk which states to create multiple environments in a single file, using, for example, Environment VARS passed in.
In practice, I'm not sure how this works. I clearly want to use Lambdas Versioning and Aliasing model, so I only want ONE defintion of my Lambdas, but I want MUTIPLE api stages.
If I run the template twice with a different ENV param, it will remove my previous stage, so do I create all my stages in the API definition (presumably using normal Cloudformation Type::Stage to reference the Serverless::Api)?
There seems to be lots of questions concerning versioning and environments. Any chance we could have a non-trivial example by an expert that could help clear this up please?
The text was updated successfully, but these errors were encountered: