AWS SAM
I started my new project with the AWS SAM framework. In this post, I share some takeaways I have learned about creating serverless applications with it.
Learning curve
Overall, a different experience from writing a web app built around a classical monolith web framework. If you look at speakers presenting AWS SAM on stage, you may feel that it’s an excellent choice for a quick prototype or an API endpoint that you can start and finish within a few hours. In reality, if you don’t have much experience building cloud-native applications, there is a lot to learn, mostly with trial and error.
Still, if you want serverless, SAM can help. Creating a project with SAM is easier than cobbling together the infrastructure, resources, and code manually and writing update commands.
A few things that AWS SAM provides.
- Simplified templates with shortcuts for describing AWS resources.
- Scaffolds the structure to put your code.
- Commands for compiling and deploying the project.
- Commands for unit testing and local development.
Most importantly, especially for the beginning, SAM is opinionated. Cloud-native development best practices baked into the directory structure, command line tools, and template language.
Editor / IDE support
I started writing my code with VSCode but quickly switched to PyCharm, as it served me better than VSCode out of the box, even with all installed plugins.
A few things that I liked about PyCharm:
- It understands the structure of
template.yaml
and provides auto-complete documentation and validation for AWS resources. - Somehow, it picked up
node_modules
from a subdirectory with the Lambda code and started doing autocomplete and stuff.
Documentation quality and community support
- SAM developer guide is the documentation entry point. As with any AWS documentation, I find it exhaustive and meticulously pedantic. Despite all that, I find it aesthetically unpleasant and hard to navigate.
- Googling specific questions and error messages helps. Most of the time, I land on a GitHub issue with the discussion.
Framework maturity
In July 2020 (exactly two years ago, as I’m writing this), Amazon announced that AWS is now available for production use.
Still, I came across a few rough edges here and there. A few other things, such as TypeScript support, are still in beta, and you need to enable them with sam --beta-features
explicitly. If not, you get that message.
Using esbuild for bundling Node.js and TypeScript is a beta feature.
Please confirm if you would like to proceed with using esbuild to build your function.
You can also enable this beta feature with 'sam build --beta-features'. [y/N]:
Should I start learning a new framework by explicitly jumping into the beta bandwagon? Retrospectively, it was probably not a good idea. Still, when I considered the app architecture in my head, I was unaware that the features I wanted were not the first-class citizens yet.
SAM template file
When you start a project, SAM creates a template.yaml
file that describes all your resources. As it’s a serverless framework, these resources will most likely contain API endpoints, DynamoDB databases, SQS queues, and lambda functions processing the requests from the API or the queues.
The SAM template language is a superset of CloudFormation, and it’s compiled down to CloudFormation before deployment. The template provides various shortcuts to start quickly with the HTTP-API-centered application. See AWS Serverless Application Model specification for more details.
For example, the SAM-specific AWS::Serverless::Function resource creates a Lambda function, an IAM execution role, and event source mappings that trigger the function. Also, SAM implicitly creates an API Gateway instance. Writing this down and connecting the dots manually with a “raw” CloudFormation template would require much more work and domain knowledge.
Policy templates. Another example that helps is AWS SAM policy templates. With AWS, to define that process A can get access to a resource B, you define a policy and a role, and then attach that role to the process. Authoring and debugging IAM policies is not easy, but policy templates provide shortcuts.
Instead of writing a policy manually, You choose a policy template from the predefined list and attach it to the actor. The templates are parametrized — you can tell “I want to provide access to DynamoDB table foo
, or an S3 bucket bar
” instead of providing blanked access to “all DynamoDB” or “all S3” as you would do with AWS-managed policies.
Amazon Cognito
I gave up trying to add a Cognito authorizer to the API Gateway. I wanted to make it so that users could sign in with their Google accounts by tokens issued by a different app. I couldn’t make it work. Instead, I resorted to a Lambda Authorizer, sending a token to https://www.googleapis.com/oauth2/v1/tokeninfo.