AWS re:Invent 2020: The serverless LAMP stack

AWS re:Invent 2020: The serverless LAMP stack

Show Video

hello everybody thank you so much for joining me my name is ben smith and i'm a senior developer advocate for aws serverless and this session is on the serverless lamp stack now prior to joining aws i was a php developer for about 15 years and i had built all sorts of applications of different shapes and sizes over that time and one challenge that i would constantly be coming up against was that of scalability now this isn't just me this is a common challenge with this traditional lamp stack implementation that many php developers will come up against and by scalability i mean an application that can handle highly variable levels of traffic now this image here represents a kind of high level implementation of a serverless or sorry of a traditional lamp stack application so you can see that you have requests coming from the internet and they are met by a load balancer which will then route those requests downstream to a server or a node depending on the routing logic that you've applied to that load balancer now the problem or the challenge with this sort of traditional lamp stack application is that as you as your application requires more capacity maybe you're receiving more requests your applications becoming more and more noticed or more successful you will need to provision more capacity for it and that means you have to scale like this by adding a new server or a new node behind that load balancer so every time you do this you bring additional overhead in the form of networking or administration storage capacity backup and restore systems you might have to update some form of asset management inventory and as you scale each additional server you know that they run independently from each other so you might see synchronization issues as each server has its own disk and its own file system so using serverless technologies this challenge of scalability is managed for the developer if traffic surges to your application in a serverless application those services that your application sits on will automatically scale in line with that demand so that allows you the developer to transition your applications from prototype to production really quickly and very easily once your application works and it's secure it's ready at scale so serverless has been around for a while now but specifically now this moment is a really good time for php developers to maybe take another look at serverless technologies and there's a reason for that and i think to understand that reason it's useful to have a look at the timeline of events and of service releases that has led us up to today so going back to november of 2014 this was re invent um this is when aws lambda was first launched and this is a compute service that lets you run your code in response to events and it automatically manage the compute resources for you now we'll talk about lambda in a lot of detail over the course of this session so we'll come back to that then in july of 2015 this service called amazon api gateway was announced and this allows developers to build secure and scalable apis very quickly in front of a variety of different types of application architectures then november of 2017 we launched this new service called amazon aurora serverless and this was a new configuration for relational databases that allows you to pay for requests to your relational database on a second by second basis so it's moving you more towards a serverless payment model then in november of 2018 probably the most significant part of this timeline for this particular session we launched something called lambda layers along with something called the custom runtime api and the custom runtime api allows you to build any language that's compatible with linux into lambda and you can distribute that custom runtime with something called a lambda layer and we'll look at how to do that coming up in just a minute then in september of 2019 we improved vpc networking for lambdas that means lambdas that or lambda functions that have to work inside of epc so customers were reporting to us that they were experiencing slower startup times for these lambda functions that were configured to run inside of epc and by a more efficient use of the eni the elastic network interface we were able to solve this problem why was this important well because if you want to communicate with a rds database from lambda then that lambda function has to be configured to run inside the same vpc virtual private cloud as your database then in november 2019 we launched something called amazon rds proxy so this is a fully managed highly available database proxy for rds databases that makes applications more scalable and more resilient to failures when building with relational databases so this is the sequence of events which has made serverless much more accessible now for php developers and this is the serverless lamp stack so where normally you would have seen lamp as linux apache mysql and php now you have lambda api gateway mysql and php and i'm going to step into each one of those components but before i do that i think it's probably useful to take a little look at how we define serverless specifically at aws and typically at aws you will find that we define service serverless as something that fulfills all four of these important tenants so first of all there should be no infrastructure to provision or manage so this means no service to spin up nothing to operate or patch essentially no physical or virtual container orchestration of any sort the next important thing is that the service should scale automatically and that means scaling by unit of consumption rather than by unit of server or by unit of compute there should be a pay for value billing model so this another way of putting this is that you don't pay for idle when you're not using the service you're not getting billed for it and the fourth tenant is that it must be highly available and secure so thought tolerance is baked into the service so there's no need to architect specifically for that so when we say serverless what we're talking about is the removal of server related operations and that's the important distinction for developers because it allows them to focus on building an application rather than spending time and resources on the infrastructure and scaling the infrastructure that that application sits upon so that brings me to lambda like i mentioned lambda is a compute service that runs code that you upload to it in response to events and lambda doesn't just sit in as part of a vacuum typically it's comprised of two or three components so the first component is the event source and this is the thing the event that invokes your lambda function tells it to start running the code that you've uploaded to it and this can be a number of different things it can be a change in data state from a database it can be a direct request to invoke from a request from an http endpoint or it could be a change in resource state from any number of integrated aws services again it's the thing the event that invokes your lambda function and tells it to start running the code that you've uploaded to it then there's your lambda function itself lambda provides curated execution environment with a number of languages that are natively supported and some of them are listed here on this slide but now with the custom runtime api you can bring to lander any language that is compatible with amazon linux environment so that's not just php that could be powershell or any number of languages the third component is the service or the destination the thing that your lambda function needs to act on or interact with and this can be essentially anything that your lambda function needs to do it depends on the business logic of your application and the requirements of your application another way to look at lambda is to look at the anatomy of it so if you think of lambda as a kind of onion with a number of layers going from the outermost layer in first there's the lambda compute substrate there's the outermost layer and this is the underlying compute layer for all of lambda next there's the service itself and this manages the scheduling and the organization of workloads across hundreds of thousands of customers and what's important to know is that these first two layers are completely invisible to you the developer they're managed entirely for you by aws and you don't have visibility or access to them then the next layer a little further in is the execution environment now this is customer specific and aws account specific and it's the secure space where code itself is run inside each execution environment there's the language runtime and then finally there's the function the handler function which is what you provide zipped up as a package with any dependencies that are required now we'll come back to lambda but just want to touch on the other components of this serverless lamp stack so the the a the replacement for apache is api gateway and you've probably heard it said many times before that apis are the front door to your back end application your back-end services and there's this very comprehensive service at aws called amazon api gateway which is a fully managed service that makes it easy to create and maintain and secure apis at pretty much any scale now these apis can be used to access data or business logic or functionality from backend service you can create restful apis you can create http apis you can create websocket apis to enable real-time two-way communication between your application and it can support containerized workloads as well as serverless workloads more or less any kind of web application that you can conceive now api gateway is a really comprehensive service that i'm sure you'll find entire talks dedicated to at re invent so we don't have time to to dive deeply into amazon api gateway but some key feature highlights that i would want to pull out for this session is that it's perfect for communicating with micro services and it has built-in protection from ddos attacks and throttling for back-end applications and you can configure each call and each resource to authenticate and authorize in a number of different ways so the next piece is mysql and that's my sequel running on amazon aurora with amazon rds proxy so aurora is our cloud native database service that's still the fastest growing service in aws history and this is a database instance that gets created inside of epc virtual private cloud that prevents public access to it and to connect to this aurora database instance from a lambda function like i mentioned before that lambda function must also be configured to access the same vpc now this provides high performance and availability for mysql and postgresql databases and the underlying storage scales automatically to meet demand of up to 64 tabi bytes which is over 70 000 gigabytes and you can use alongside this this other service called amazon rds proxy which went ga just a couple of months ago now this is a database proxy that lets you pull and share database connections to improve application scaling when using relational databases so before rds proxy customers were reporting to us problems that they were experiencing with a form of database memory exhaustion where they would be connecting directly to their rds databases from a lambda function and if you can imagine hundreds or thousands of lambda functions concurrently opening and closing connections directly to the database at the same time this was cording causing a surge and leading to slower query times and limited application scalability so rds proxy was built specifically to solve that problem what it does is to establish a database connection pool and it sits between your application and your related relational database and your lambda function can reuse connections in this pool so it protects the database against over subscription without memory and cpu overhead of opening a new database connection each time and what's really cool is that credentials for this database connection can be securely stored in aws secrets manager and then access via an iam role identity access management role so this enforces really good strong authentication requirements for your database applications without a costly migration effort for the database instance itself and this is the kind of token dance or token exchange that takes place when you need to connect to a aurora database from a lambda function using rds proxy so you use your lambda function to connect to rds proxy which uses a trust policy to grab the credentials from secrets manager this then returns a secure token which you can use in your next line of code to connect to a database connection in the pool and you can use that database connection for the duration of your lambda function so this is the meat of this presentation really is php on aws lambda so we know still that php is approximately powering about 80 of the web still it's i think 25 years old this year php so it's a very mature language but it's not going away anytime soon it's um very powerful and still a very active community and what's good now is that with the custom uh with the runtime api for lambda you can build a custom runtime to uh create php lambda functions and like i said it does this doesn't have to be just for php you can do this with any language that will run in a linux compatible machine and you can distribute this custom runtime as what's called a lambda layer now in order to build a custom runtime you need to create a special file called a bootstrap and this bootstrap file acts as a communication bridge between your lambda function handler and the lambda execution environment and it uses this runtime api along with some important environment variables to form this communication bridge so what it does is it handles this kind of event loop um it's responsible for a few different things first it has to process the next inbound event and grab the headers and then it has to initialize the lambda handler function and uh invoke it it also needs to handle the function response and any errors that might be occurring as well and it needs to manage the function cleanup and like i mentioned there's some important environment variables that are available to you in order to communicate with the runtime api so you have an environment variable that holds the host address and the port number of the runtime api for you to make the http calls in your bootstrap file you have an environment variable that holds the location of the handler function and one that holds the location of the application function code as well this is a an example of a very simple bootstrap file where all of those things have been put together so it's processing the next inbound event and header it's initializing the function and invoking it and it's using environment variables to know the name of the handler function and to return the response whether it's a an error or not and what's really useful with building your own custom runtime for lambda is you can include only that php version that you specifically want to use you can include only those modules and package dependencies that you're going to use in your functions so you can create very lightweight and specific runtimes for lambda and this is how you do it so you compile your required version of php so in this example i'm going to compile php73 and then i include all those extensions that i want to use in my function so this example you can see i've highlighted that i'm going to use mysqli to connect to my database then i package the binary and the bootstrap file that we just looked at together into something called runtime.zip here i'm using the cli to publish that runtime.zip as a lambda layer and then here i'm using the serverless application model aws sam to add that layer to my lambda function and that's all i need to allow my function to understand how to handle a php runtime i can do something similar for handling libraries and dependencies as well so here i'm using composer to install and manage the aws sdk for php and then using the aws cli to publish something called vendor.zip as a layer and that vendor.zip holds my aws

sdk and all the other libraries that i'm using and then the the screenshot at the bottom is from the lambda console where you can see this lambda function has two layers the first layer holds the runtime the custom runtime for php the second layer holds um the vendor directory with all the libraries and dependencies packaged and now i can manage these independently of each other and whenever i want to create a p8am lambda function with php i simply need to add these two layers to my function and here is where every everything is put together so at the top of this lambda function i import the libraries that i'm going to use and then here i use them to connect to a relational database using rds proxy so in fact what these four or five lines of code are doing is this token exchange here and i'm doing that all with the aws sdk for php now that's great for creating custom runtimes that are lightweight and include only those dependencies that you need but if you don't want to jump in to start compiling versions of php then you don't have to do any of that there exists this fantastic open source and production ready php runtime for lambda it's called breath and this is built by the open source community and it's very active and it's very well documented so it's great for production ready applications and there's a many case studies of companies using this already and you can deploy this add this to your lambda functions using the serverless application model sam or serverless framework or the cdk which we'll talk about in a moment so it's very easy to add this to your lambda function and breath is very clever it has some very interesting application of some technology so there is a layer of breath called php fpm php fpm uses this fast cgi process manager which is traditionally used in servers like nginx and apache to manage inbound requests at high loads and breaths implementation of fpm takes care of a bunch of different things for you so it makes sure to run each http request as a new process which is the foundation of php's share nothing execution model it populates all those global variables that you're used to using like get and post so you can use them in your lambda functions and it provides a mechanism for php to return http responses as opposed to the json response that you're used to seeing with lambda so most frameworks today are already built most php frameworks sorry are built around these fpm features which makes this a really good runtime to transition from the traditional server hosting to a serverless lamp stack model you don't have to change very much about the way you're building your application so this is the serverless lamp stack lambda api gateway mysql and php but i like to think of it in this order it just doesn't roll off the tongue as well to say album but this is the direction that requests are actually happening they come in through api gateway they hit your lambda function your lambda function is running php and then mysql is running on aurora it's all happening inside the aws cloud and what you can do is you can use api gateway and lambda together as a kind of super scalable sub serverless web host what you would do is you would have a rule that would catch all inbound requests via amazon api gateway and route all those inbound requests to a single lambda function and that single lambda function can hold the entirety of your application code base and because it scales automatically it's able to scale up and down in line with demand so if you think of that as a kind of traditional in comparison to a traditional lamp stack model here you have on the right a typical configuration of an apache2 config file where you set the directory of your application and then in that directory you might put an hd access file and that hd access file might have routing rules to make sure everything is rooted via index.php now you can create a similar functionality in the serverless model by adding these two lines of code to route all events all routes directly to your single lambda function and you know that both of these services are serverless and they will scale automatically without you ever needing to add additional capacity or manage that infrastructure so that's one way of building a serverless application with php now this is another way is to build an event driven micro services model so here you would have your front end that would use a a separate resource to handle back end compute so let's say you would use an ajax request to something like slash api and then slash api would go to amazon api gateway amazon api gateway would have its own rules configured to then route further downstream to a lambda function so let's say your inbound request is from slash api map that would root this specific lambda function this lambda function would have only permissions available to communicate with rds proxy which would be able to get or set something from your aurora mysql database that's great but this is some other stuff you can do now is you could have another route that's to slash users and that could route to this lambda function which enables you to add something to a serverless event bus like amazon eventbridge which could invoke something else on s3 for example you could have one two slash search which could which could add something to a queue for you you could have have something to slash activity which would invoke a step functions workflow to trigger this serverless workflow to do i know perhaps some employee onboarding or something so with this model you're able to use the routing routing configuration in api gateway to route each request to a specific lambda function then each specific lambda function has finite scoped business logic applied to it to do one small piece of compute and what's more that means it also has finite permissions wrapped around it so that lambda function is only able to act on those services so that makes your application more secure it also makes it more scalable because now instead of one lambda function handling every request and scaling up and down in line for every request you have individual lambda functions scaling only for the request that is required of it so how did you get started so my advice is always to start with a framework and you could use the serverless framework or you could use the aws sam framework serverless application model but for this particular session of the serverless lamp stack there exists something else which is maybe more appropriate excuse me and that's the cloud development kit or the aws cdk cdk enables you to define cloud resources and infrastructure using the power of a programming language so you can use typescript javascript c-sharp java or python and you can do this in your ide with all those tools that you're used to using but really for me the main power of the cdk is that it allows you to create reusable and shareable cloud abstractions that we call constructs and these high-level components are really handy for best practices you can blend them together and tie them together to give you really good sort of jumping off point to further customize your application and there already exists this construct library for the serverless lamp stack which deploys all the infrastructure that we've been talking about in the last 20 minutes or so so here you can see that it consists of two constructs there's one construct for a laravel application and this is a laravel application that's running in one lambda function behind an api gateway url so this is the scalable web server model where everything is rooted via api gateway to a single lambda function you can connect this to the other construct which creates a vpc and an aurora database that's running and then you can deploy this with the cli the command line interface it transposes your cdk template into aws cloud formation and deploys those resources that architecture onto your aws account so this is how you do it in a few simple commands so first you create the directories for your cdk template and the directories for your laravel project your laravel code base and then you create the new laravel project using docker for example and then you can install those breadth packages that you would need the small configurations to run laravel inside that code base then you use the cdk to build your template so here we're initializing the cdk to use typescript and we're installing the cdk serverless lampstat construct and this is what you're left with after is two directories one holds the template and the cdk related modules and one holds the laravel application which is the standard laravel application that you used to see in along with some additions from breath and this is an example of the typescript template file that you can use to create and deploy those resources so you can see at the top of the file here i import the core cdk and i import the cdk serverless lampstat construct library then as part of the constructor i provide the breath runtime so this is the arn to the particular version of breath that i'm going to use as my custom runtime then i provide the path directory to my laravel application that we just installed then i use the cli to deploy that this takes a few seconds i have sped up a little bit but that returns to me an api gateway url which when i click on sends that request via api gateway to one lambda function which is then sending back to me my bootstrap installation of laravel so this is the whole serverless lamp stack in one go deployed within a couple of minutes using the cdk if i wanted to edit this laravel application as i'm sure you would because you wouldn't just want to deploy your bootstrap laravel i just go back into that codebase directory and start building out as i normally would so what do you do next there's a bunch of great places to learn more about this there's an entire blog series on the aws compute blog so if you were to google serverless lamp stack you'll find there's a six part blog series all about everything i've presented in the last in this session there's also a php repository on github by aws you can get to that from s12d.com lamp and this contains example codes and tutorials and lots of really good resources to try out some of the stuff i've been talking about as part of that there's also a community curated resource page that contains articles case studies talks videos tools and upcoming events from across the industry of people who are building with serverless and with php you can get to that from s12d.com

lamp resources and then the other place i'd recommend you go and have a look at is the open source php layer for lambda which is breadth has some great documentation on there and a really vibrant community around php and serverless you can get to that from this short link which is s12d.com breath so to recap the traditional lamp stack model doesn't scale very well and when it does scale it requires you the developer to manage that infrastructure but with serverless technologies php developers can now build scalable web applications without managing that infrastructure imagine never having to do another apache restart you can build decoupled services for your back-end applications you can use mature existing php frameworks you can move from prototype to production really quickly and you can either compile your own lightweight custom runtime or use an open source layer like breath so you can build serverless applications with php thank you so much for listening to this session if there's any questions you have that we didn't manage to get to in the chat then i would be happy to answer your questions you can reach out to me on twitter my name is benjamin underscore l underscore s thank you so much and i hope you enjoy the rest of the sessions here

2021-02-11 06:49

Show Video

Other news