Video details

Building serverless applications with infrastructure as code - Talia Nassi

Serverless
07.17.2022
English

How do you ensure consistency in your environments? How do you make sure the resources you deploy have the same configurations across different accounts? Infrastructure as code is the answer. In this talk, learn how to develop, debug, and deploy your serverless applications with the command line.

Transcript

All right, so my name is Talia. I'm a senior developer advocate here at AWS. But not for service days, just for AWS. We're going to be talking about building serverless applications with infrastructure as code. Just to show of hands, did any of you go to reinvent this past year? Okay, a couple of people so I can't reuse the same jokes as me and noted. So my job is to build server listings and then talk about them, write about things that I've built. Thank you. Before becoming a dev advocate, I was a test engineer, and so I did QA automation testing. Like all that stuff that your developers hate doing. Yeah, I did that for about six years before becoming a dev advocate. And I realized I really like the public speaking aspect. I like the community outreach, connecting with developers part. So that's kind of how I transitioned into being a dev advocate. Today we're going to talk about serverless, what it means to be serverless. We're going to talk about what it means to have a serverless application. We'll talk about an intro to infrastructure as code, and then we're going to talk about some infrastructure as code tools at AWS. There's a few of them. The one we're going to focus on today is Sam, the service application model. We'll do a quick demo with the Sam CLI, and then we'll also talk about Sam Accelerate, which is like one of our new launches that we did. So we're going to get started. So what's serverless? When I say serverless, I know there's a lot of different levels of knowledge in here, so just to get everyone on the same page, so when we say serverless, we mean it's the removal of server operations. So that means that there's no servers to provision, that there's no infrastructure to manage. AWS will do all of that for you. When you use Serverless, this means that you can focus on your business logic, you can focus on your application logic. And this is really great. When you want to deal with the management and scaling of your application, we handle that for you. You don't have to architect for that. And these are the four tenants that define Serverless as an operational model. So again, there's no infrastructure to provision or manage. There's no servers to spin up. Operator patch surveillance applications automatically scale by unit of consumption rather than by server unit. And automatic scaling is a big win because if you have multiple MVPs, a lot of times you don't want to build them all out for scalability because you don't know which one is going to end up in production. And then Serverless has a pay for value billing model, so you only pay for what you use, not idle time. And this is great because if you have an idea that's not taking off, it means you can experiment more. So let's say you have an idea for a new feature and James has an idea for a new feature. Like, you guys can AB test the feature and whichever one has the highest conversion rate, you can deploy that. So it's not going to affect your cost because you only pay for your customers are using. And serverless applications have built in availability and fault tolerance, so you don't have to architect for availability because it's built into the service. And this is pretty important because unexpected things happen. Like there can be outages, there can be earthquakes like spaghetti and meatball can fall from the sky. You never know what's going to happen. So with this built in availability, this highly secure environment like AWS Serverless will have you covered in case anything happens. So when we're talking about serverless, I want to focus specifically on the concept of a serverless application that is based around Lambda. And for those of you who are new to this space, lambda is a compute service where you create your application code and a lambda function. And we support six main managed runtimes. These are runtimes where we help with the patching, the updating, feeding, watering of these run times. And we also release new ones periodically. The ones that we support are Node, Python, Java, C Sharp, Go and Ruby. And then you can also bring in your own language with a runtime API. And then on either side of your lambda function, we have an event source and a destination. So an event source is something that happened in your application that causes your lambda function to come to life. So this is anything that happened, a change in state that says, hey Lambda, wake up, go do this thing for me. I need you to go perform whatever code that I wrote. So this could be like maybe an item was dropped into an S three bucket. Maybe you hit an API that triggered the lambda function. Maybe you processed a payment through a third party like stripe. Basically any change in state, like something that happened that says, hey Lambda, I need you to go do this thing, go run your code and then you have your destination. And this is what your function can talk to. It can be a ton of services both in and out of AWS. It can be databases, data stores, there's storage services, like a bunch of different things that you can add here. All right, so when you're building a serverless applications, a lot of times when people start building, you start in the AWS console, right? This is where I started when I first started learning serverless. And you go into the console, you choose the services you want, you go to the Lambda console, you build out your lambda function, you choose this as your event trigger, you choose this as your destination, and you do all the configuration in the console. And you drag and drop different services into your application. And it's really great because you have this visual UI that you can see everything and it's a really great way to learn, right? The only problem comes when you want to reproduce what you just did or you want to somehow replicate everything that you just created in another environment or just somehow move your application from one environment to another. Like, how do you do that, right? Chances are you're not going to know exactly which configurations you set and exactly what you did. And so what we're going to do is we're going to solve this problem. We're going to look outside of the console to infrastructure as code. So infrastructure as code is a process of provisioning and managing cloud resources by storing configuration in a template file. And I wish Jeremy was here to hear this, but infrastructure is code. Basically what you're doing is you're automating the provisioning process. So that means you're not going to go to the console, choose this service, choose that service, connect them through the UI. You're going to use a tool called Sam, which we'll talk about in a minute to deploy. And what you're going to do is you're going to use Sam and you're going to define all of your resources in a Sam template. You're going to instantiate infrastructure by using these configuration files. Basically what this means is you have this template and in this template you have all the steps, all the resources of your application. So you're saying this is my lambda function, this is what triggers the lambda function. All the configuration is going to be listed in one place. It's one source of truth for your application. And basically you can treat that template as code. And like, what do you do with code? Like you version it, you deploy it. If something goes wrong, you can roll back. So you treat this file as a piece of code and then this allows you to eliminate configuration drift through automation. So like I said, I used to be a test engineer and one of the things that I heard all the time was, well, hey, it worked on my machine. Like if I found a bug in production or in another environment. So let's say you get paged one night because there's an incident for your application and it's really late at night and you wake up in the middle of the night and you go in and you fix it. You realize what the issue is. It's a configuration issue. So you go in and you make the configuration change in production and you go back to sleep because it's like the middle of the night. So what you just said is even though you fixed the issue in production, you've just created an even bigger divide between your staging environment and your production environment because you didn't make the same change in staging. So a lot of times your staging environment and your production environment, there's like this configuration drift because you didn't make the same changes in your staging environment. So when you use infrastructure as code, you have this one source of truth. You have this one central authority that is this Sam template. And then you push those infrastructure changes through. So you don't have this like, well, hey, it worked on my machine problem anymore. There's three infrastructure as code tools at AWS. The primary one is cloud formation. So Sam and CDK are built on top of CloudFormation, and they both output to CloudFormation. Sam stands for the serverless application model. It's specifically built for serverless, and it uses a few serverless resources that we'll talk about. So if you use cloud formation, you get the whole suite of AWS resources. And then if you want to add serverless resources, you can use Sam for that. Sam is an open source framework for building serverless applications using infrastructure as code. It's template based. It uses either YAML or JSON. It's typically found in a template YML file. So the way that I like to think about this is just like React is a framework for building JavaScript applications. Sam as a framework for building serverless applications. Okay, so Sam comes in two parts. We have the Sam templates and the Sam CLI. So the templates are a way to use shorthand syntax to express resources and event source mappings. It's where you define all the resources in your application. The Sam CLI is a command line interface that lets you build your serverless applications within your local machine, and it helps you with development and debugging and builds. So this is what an example Sam template looks like. This one is written in YML. You can see here that there's a few resources being created. We have a lambda function, a DynamoDB table, an API. We created the lambda function and we added the corresponding IAM role that lets the lambda function talk to DynamoDB. And there's a lot of options when it comes to policies that you can configure. Here, we also created an API from API gateway. And then you have this event source. You can see this event source for your lambda function, which is this Http API. And you can configure these templates to add AWS resources and create your application. And you have a lot of flexibility to configure this however you want. So with these 20 lines of code, when you deploy this, this on the left becomes this on the right. So you have the lambda function that's triggered by API gateway. And then you have the DynamoDB table that stores all the data. And what's already created for you is the permission for API gateway to invoke the function. That happens automatically in Sam when you set API gateway as the event source for your lambda function. And then you add the policy saying you can only read from the table. So there are seven serverless resource types you can use in your template. There are other resources, other cloud formation resources, that you can add to your template. These are just the seven serverless ones. So again, there are many more that you can use. These are just the serverless specific ones. So for serverless, you can add a function. You can add two types of APIs, a table, a layer version, an application, and a state machine. And I want to go through one of them so you can see kind of how you can customize each one of them for your needs. We don't have time to go through all of them, but I just want to go through a lambda function. So this is one of the resource types. The syntax is highlighted here. And when you add this to your template, you're adding a lambda function. Some of the configurations you can add are, again, policies and permissions. You can add event source mappings that trigger the function. Another configuration you can add is either Arm 64 or the X 86 chipset. So this was the Graviton release that we did last year. And the reason that you would want to use Graviton is there are certain types of lambda functions that are very computationally heavy, like machine learning or graphics processing, things like that. So in these computationally heavy use cases, running your lambda functions with Graviton could be faster, it could be more cost effective. So this is one of the configurations that you can set. Do you guys remember in the beginning where I talked about lambda event sources? So this is, again, what triggers your lambda function. So in Sam, you can set up the event source mappings from your template. Like I showed, there's 17 event source types that are supported in Sam. Side note, there's more that you can set up in the console for third parties, but the ones that are supported by Sam, there are 17 of them. So, for example, any time an event is put onto an Sqsq, you can trigger your lambda function. Or anytime a message is sent with SMS, you can trigger your lambda function. So these are the 17 that are for serverless. There's also more than 75 policies built within Sam. They're all on the Lovely AWS documentation site. Don't laugh when I say lovely. AWS. Documentation. There's a list of the templates that you can add. I also have a few in this deck. I have a few S twelve D.Com links. That stands for serverless land.com. That's my team's website where we put a lot of content on learning videos and blogs and things like that. So if you haven't looked at serverless land, be sure to do that. This is an example of how you would use policies. So in this example, we're using DynamoDB. So the policies we can add could be like to get an item, delete an item, put an item somewhere, and then you can say which resources they're applied to. So you can get items from this table, you can put items into this specific table. And remember, you always want to follow the principle of least privilege. So you only want to give access to the things that you need. And then when you're building lambda functions, you have the option to do the standard build method, which is applied to any of our supported runtimes, Python, Java, all of those. And you can also do a custom build. And this allows you to use the make file as a build method. So this lets you create your own method of building. If you want to use a specific dependency or grab specific files, this is something that you could do. Okay, so one of the goals of infrastructure as code is to make your infrastructure reusable, right? Like if I want to redo something or if I want to deploy something that I created in a different environment, how do I do that? I want it to be simple. And why is this? Why does that matter? I'm going to say some things now that are pretty controversial, but we'll see how it goes. So in an ideal world, everybody would test their code in production. And if you know me or have heard me speak, like, I'm so passionate about testing and production, and I really dislike using staging environments, but sometimes that's not an option. Sometimes your infrastructure isn't set up for testing in prod. So you have a staging environment or a test environment, and those environments are in play. When we're dealing with serverless, the best practice is to have a developer account for each developer, and you use the Sam template to do that. And then your environments like Beta, staging and Prod, whatever, they should also all have their own account. So there's this inherent security that comes when you're saying that only folks who get to deploy to production should have access to production. And the same with staging. So that's one thing that you get out of it. You have this differentiation between accounts, between environments, and you can reuse the same template in different places to ensure consistency. So by breaking these out, again, you're ensuring consistency across environments. This is really great when you're onboarding new developers and like a new developer comes in and you give them this huge book of like, this is how you set up your environment. And they go through it and they're crying in the corner because they don't know what they're doing, versus you give them a stamp temp hey, deploy this. Done. Your environment is set up. So again, when I was a test engineer, so many times I'd find issues in production and then I would send them to the dev team and they wouldn't be able to reproduce the issues. So they would say like, oh, it works on my machine. But with templates, you have one source of truth. You have this one central authority that is the Sam template. But if there is an issue, you can roll back to the last stable version. All right, so let's go ahead and create a serverless application using infrastructure as code. There's a few steps to build your application with Sam. These are commands that you run with the Sam CLI. So first you need to install Sam. And if you're using Cloud Nine as your text editor, then Sam has already installed for you. But if you're not, then you need to install it. Then you run Sam and knit. And when you run Sam and it you're going to be asked for some user input. So you have to fill out a few things. First you have to fill out what kind of template you want. So we give you a few templates to work from. We have, like, a Hello World template. We have a simple web back end which we have a template for just like some stock stuff that's on there. And then you select your runtime. You can choose Python, Ruby, Go Java, net Core, or you can also use a custom runtime. So you have a few options there. And then you have to choose your dependency manager if your runtime requires it. And then the result is something like this. On the right, you got to read me with some instructions. You get the events that trigger your lambda function. And then you have the Hello World folder with all the information about the Hello World function. And then again you have the template YAML file, which is that Sam template with all of your resources that you created and all the steps to deploy your application, everything that you need that's in your application with all the configuration. Next you have to run Sam build. And there's a few things that happen when you run Sam build. So you can build with native runtimes. You can also do it with custom run times using a make file. Again, this just gives you a lot of flexibility. And just to note, I know this is serverless days and I know that I work for Serverless and I don't know if I'm allowed to say the C word because this is serverless, but a lot of the runtimes are supported by containers. So if you do Sam builds use container. You can grab a container that's based in the environment that your lambda function will run in and then it'll build that out for you. You can also use a cached or parallel flag. And when you use a cache flag, you can cash a bill. So let's say you have like ten lambda functions and you only make a change to one of them. When you do the build, nine of them will be cashed, but only one of them will be built. And then you can also run things in parallel with the parallel flag. You can also do omission if you want to emit something. So when you run Sam build, it creates a separate folder and it isolates each of their functions into their own build. So you get a really nice output. And each lambda function is prepared with a self contained package with all of its dependencies. All right, so next you need to deploy your application. You can do that with Sam deploy. So this deploys or updates your application on the Cloud. It manages the S three bucket for deployment artifacts, and it saves all the deployment options to a configuration file. And then when it does that, it creates a CloudFormation change set. And this is basically just a diff of what was in production versus what you're changing. So it'll show you what was there and what's there now. And it basically just compares the template to what's already out there. And if it's a brand new deploy, it's just going to deploy everything at once. And if it's not, then it'll just update those changes. Okay, so one of the coolest things we launched last year was Sam accelerate. And the big idea with Sam Accelerate is that it makes testing a lot easier. Because you're testing in the Cloud, you don't have to emulate your complete cloud infrastructure on your local machine. You're actually testing in the Cloud. And there's three features of Sam Accelerate that we're going to talk about today incremental build, Sam sync, and aggregated feedback. So with Sam accelerate, again, you're not emulating the Cloud, you're testing in the Cloud. And so to understand Sam accelerate, we really have to differentiate between code and configuration. So in this context, code is everything in your lambda function, your lambda layer code, your step functions, Amazon state language file, and your API gateway open API file. So everything else is considered configuration. So with that in mind, this update to Sam build, called incremental builds, it makes sure that all of your dependencies are in place and ensures that you basically have everything that you need to deploy. Before, when you ran Sam builds, it used to be that it builds everything all the time, the code and the configuration, regardless of what was updated. But we're with this update, with incremental builds, unless you add new dependencies, only the code itself is going to be built out. And we did this because we realized that dependencies don't change that often, so we don't have to spend that time to build those. So think of a lambda function if you have this hello, world lambda function. This is written in Python, so it probably has boto three and the request library as dependencies. So if you change something in your lambda function when you run Sam build, it's only going to update the code, it's going to separate the cache, and it's going to keep the dependencies in a separate place. And we optimize this even further with Sam sync. Before Sam accelerate, when you wanted to test your code in the Cloud, it would do a deploy and do a full stack update with cloud formation, and it could take several minutes because again, it's deploying everything, not just what you updated. It would deploy both the dependencies and the code. Now, when you make a change and it's a code only change, it doesn't do a full stack update only, it updates what you changed and it makes development a lot faster because again, the whole stack doesn't redeploy. You can also use Samsung watch. And what this does is it watches your code for changes and automatically decides if it should be a configuration update or a code update. So if it's a configuration update, then you use CloudFormation for a full stack update. And if it's a code update, it just updates the code. And this happens automatically for you. So as you make changes to your code, sam is watching and it'll send those changes up for you. Now, the last thing about Sam accelerate I want to talk about before we do the demo is aggregated feedback. So before this launch, you only used to get lambda function logs when you ran Sam logs. And now in addition to Cloud Watch logs, you get logs from API gateway and you get traces from X ray. So it kind of just gives you like a more holistic view of what's happening in your application. And then again, after you deploy, you can use Samsung Watch and it'll synchronize your updates to the cloud and Sam will watch for those updates. Okay, so we're going to build a quick application. We talked about one way to build a serverless app using that five step process. Another way to do it is using the Serverless Patterns Collection. So the Serverless Patterns Collection is a repository of pre built Sam and CDK templates that was started by my team and it started as a learning resource. What we're going to do today is we're going to use a Sam template to deploy our application. And this Sam template is pre built. And in our scenario, we're going to use DynamoDB and Lambda. Anytime a new item is added to a DynamoDB table, we're going to trigger a lambda function and it's going to log that event into Cloud Watch logs. So to build our application, we're going to head to Serverlessland Compatterns. This is where the Patterns collection lives. And we're going to use one of the predefined Sam templates we're going to filter by DynamoDB and Lambda. And then we're going to choose the pattern DynamoDB to Lambda. And then I'm going to click on the download instructions. It's just going to clone the repo for me. And then I'm going to head to my terminal. This is in cloud nine so I don't have to install Sam. I'm going to paste the download instructions again. It just clones the repo, changes the directory to the right place, and then I'm going to run Sam deployguided. And this is going to deploy my application. It's going to ask me some questions, some prompts, and I'm just going to leave everything blank, because when I do that, it just takes the default options. It takes a few minutes here, but you're going to see is you're going to see a change set. And this change, that is from cloud formation. It's saying these are the resources that we're going to create. And it's going to say we're adding all of them because, again, there was nothing in production. We're deploying this from scratch. All of these are being created. This is that diff that I was talking about. It's that difference between what's in production and the changes that I'm making now. So this does take a second. So these will be updated one at a time. So here you can see the DynamoDB table is being created, the IAM roles, the lambda function, the event source mapping, and you'll see this success message successfully created once the stack has been created. Now we're going to go into the console and test what we just deployed. So we're going to head over to the DynamoDB console because we need to test adding an item to the DynamoDB table. So we're going to go to tables. We're going to choose the table that was just created for us when we deployed. And we're going to add an item to this table. I'm pretty sure when I recorded this, I was hungry. So we'll see what the name of the item was that I added. Yes. Great. Okay, so we added a banana. Now that we've added the item to the DynamoDB table, we're going to go into lambda and make sure that the lambda function was triggered. And the way we do that is we're going to go to the lambda console and we're going to choose the lambda function that was created for us when we deployed the Sam template. And we're going to scroll down to view logs in Cloud Watch. This is where we can see all the logs for the lambda function, and we're going to look for banana. And there it is. So anytime a new item is added into your DynamoDB table, this lambda function is going to be invoked, and it'll log the event into Cloud Watch. I know this is a super simple example, but I just wanted to show you. We do have pre built Salmon CDK templates that you can use and deploy, and you can configure them however you like, but this is a really great place to start if you don't want to start from scratch from building your Sam template from nothing. So we have a ton of content and learning opportunities, including the entire serverless land patterns collection for you at serverless land.com. So be sure to visit us if you haven't already. And thank you all so much for joining me in our journey through infrastructure with code.