AWS API-gateway manual deploy required? - amazon-web-services

The API tends to go down when I re-deploy a REST-API using AWS API-gateway and cloudformation (AWS::ApiGateway::RestApi). Then a manual "deploy of the API" through AWS-console is required to fix it. This creates downtime until I have done this. Which options do I have to prevent this?
Ref:
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html

In your CloudFormation template, be sure to include a AWS:ApiGateway:Deployment resource to trigger the actual deployment after a change.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-deployment.html
APIs are deployed without downtime. While the new configuration is propagated API Gateway responds to requests using the previous config. Once the new configuration is available and a new request comes in it will be handled using the updated configuration.

Related

Cloudformation stack references old/nonexistent resource

My stack is referencing a resource that has been deleted (long story short it's been deleted because we use Serverless for API GW and async routes at the same time).
When I look at CloudFormation I see the resource and its ID. However the resource does not exist anymore. Is there a way to remove this reference or update it? Note that the new resource was created separately using AWS CLI, not through CloudFormation updates.
Here's an image to the resource I am talking about
This command aws apigateway get-authorizers --rest-api-id however does show the correct ID for the authorizer. It's the cloudformation console Resources tab that shows it outdated.
I solved this by using the handy DefinitionBody property under Properties. You can define your API Gateway methods, authorizer and other things using OpenAPI specification. Just include the correct syntax under that property DefinitionBody.
The way I found out my DefinitionBody was by exporting an existing API gateway from the API Gateway console (API GW -> Stages -> choose stage and click on Export tab, choose Export as Swagger + API Gateway Extensions) and modifying it according to my needs. You can see the screenshot of this tab in my answer here: Defining authorizer and using it in API Gateway using Open API
OpenAPI docs can be found here: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md

How to have a static URL for serverless framework AWS deployments?

When I use serverless framework to deploy with sls deploy to an AWS endpoint with lambdas and dynamodb, the host of the endpoint changes every time with a different prefix. This is a problem because if I release a client, I won't be able to deploy with serverless again.
For example, a host might look like this: 9svhw8numd.execute-api.us-east-1.amazonaws.com
That 9svhw8numd part changes each time there is a new deployment.
I've checked the serverless documentation and I can't seem to find anything that tells me how to configure it to have a static URL. How do I keep the host static for each serverless deployment?
What you're seeing is a URL for an AWS API Gateway instance. If you delete and re-create your serverless stack, a new endpoint will be generated. If you don't remove the stack, it'll stay the same throughout multiple serverless deploy commands.
If you'd like a custom domain instead of one generated by API Gateway, you'll need to configure a domain name via AWS Route 53. If you're using the Serverless Framework, here's a good guide to do that.

Deployment failing after deleting API Gateway. How to recover?

After I removed the API gateway manually via the aws console because changing the configuration in my serverless.yml file didn’t seem to change the Gateway configuration anymore.
Now deployment fails with " An error saying: ApiGatewayMethodGet - Template error: API Gateway RestAPI dj1ivqgipb doesn't exist".
I understand that this is an error caused by me, but can anyone please hint me into the direction of how to recover from this?
https://i.stack.imgur.com/rzr8S.png
All I did was to go to API Gateway -> Custom domain names -> then I reconfigure API mapping from pointing to the old deleted API to then point to the existing API that I just created in the cli... Then now I can re-deploy my serverless application.
https://i.stack.imgur.com/N6Sjh.png

how does serverless invoke in aws

I am new to this whole serverless framework. I created my first serverless function as documented here https://www.npmjs.com/package/serverless#quick-start. Next when I do a "serverless invoke" it works. I am confused how this works, the questions I have around this are
There does not seem to be an API gateway created so how can it invoke?
There are also stages mentioned in the serverless.yml file, I'm not sure what these translate to
Any help on this is highly appreciated.
First of all the default code comes with the AWS template, is only having a Lambda function declared. Let me try to answer your questions inline.
There does not seem to be an API gateway created so how can it invoke?
Yes, since there is no API Gateway created, its not possible to invoke the Lambda through URLs. However, it is possible to invoke the Lambda using AWS CLI or SDKs which is what Serverless Framework is providing with "serverless invoke". To create a API Gateway, you need to add an event object to the function code as shown below.
functions:
hello:
handler: handler.hello
events:
- http:
method: get
path: hello
There are also stages mentioned in the serverless.yml file, I'm not
sure what these translate to
When you define a stage in serverless.yml file, after the deployment, it creates a stage in API Gateway including it in the API Gateway URL path as shown below.
https://your-api/<stage-you-defined>/resurce-methods
Note: that if you setup a custom certificate for API Gateway, then you have option to setup your own custom paths.
Also its important to note that, although API Gateway supported this feature to have different stages(e.g test, staging, production) of a Single API Gateway deployment, latest Serverless Framework doesn't use this feature. Instead when you define a new stages, it will deploy a whole new API Gateway with the new stage. Serverless Framework has the argument for separating the API Gateway and having a single stage to self-contain each stage for isolation.
You can attach an API gateway for invoking your lambda
Or
You can get event driven. Where your lambda gets invoked in response to some events like a new message in AWS SNS or when a new object gets created in S3
Or
You can have scheduled invocations using cloudwatch trigger events
For a comprehensive list of events that can invoke lambda see Invoking Lambda Functions
As documented in AWS Regions and Endpoints there are HTTPS endpoints for Lambda. For example, in the us-east-1 region the endpoint is https://lambda.us-east-1.amazonaws.com. This is how you're able to call a Lambda directly without the API gateway. API gateway can add additional functionality and puts a full HTTP protocol on top of a Lambda.

AWS API Gateway: How to achieve continuous delivery?

I'm building an API using AWS API Gateway and AWS Lambda. I would like to achieve continuous delivery for this API. The path I've chosen to do it is to use CloudFormation through AWS CodePipeline. I've managed to to it for another project using Lambdas (without API Gateway), it works perfectly and it is really pleasant to use.
The issue I'm facing when deploying is that the Lambdas are properly updated but not the API definition. From what I understand, the AWS::ApiGateway::Deployment are immutable resources which means that for each deployment of the API I need to create a new AWS::ApiGateway::Deployment resource. This is not practical at all because for each of this AWS::ApiGateway::Deployment I have a new Invoke URL. This is not acceptable since I would have to either change my DNS record to the newly deployed API invoke URL or ask our API users to change the URL in their applications.
What I would like is to be able to change the API definition and the Lambdas implementations without my API users having to change anything in their applications.
How can I achieve this behavior?
I created a tutorial to highlight my issue. You can find it at: https://github.com/JonathanGailliez/aws-api-gateway-lambda-example
As per: https://forums.aws.amazon.com/thread.jspa?messageID=789869&#789869
joey-aws says:
We are currently in the process of rolling out a solution which
addresses this exact problem. In the meantime, a common workaround
would be to update something small, such as a "description" field
which could then be used to "trigger" an API Gateway deployment when
updating the CloudFormation stack.
I'll update this answer and the example repo once it's rolled out.
You could run a Cloudformation update from the command line or in the AWS console. This would change the API definitions and any lambda code without changing the unique id to access your gateway.
The other option is to put your API behind a custom domain name and then you could keep deploy a new API or stage and switch over the custom domain mapping when you are ready. The users wouldn't recognize any change.
A way to achieve that is by leveraging existing frameworks like
AWS SAM
Serverless
Claudia
I was able to achieve this by using CloudFormation template generated by troposphere and boto3 api in Python as follows:
Split the template into two parts
API definition, Method(s), IAM roles, ApiKey and Lambda (a)
Deployment, UsagePlan and UsagePlanKey (b)
Once changed Lambda code is zipped up and uploaded to S3 using boto3 api
Stack (b) is deleted
Stack (a) is updated with new resource id for the GET method connected to lambda
Stack (b) is created anew
Steps 3, 4, 5 are performed using CloudFormation boto3 api with blocking until completed.
Most importantly after all steps are done ApiKey value and stage Invoke URL remain the same, running updated Lambda code as tested with curl.
Note: it may take additional 30-60s for API to become fully functional after CloudFormation update is completed.