AWS re:Invent 2020: Monolith to serverless SaaS: Migrating to multi-tenant architecture

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello everybody and thanks for joining my session today. As the slide says, my name is Tod Golding and I'm a partner solutions architect at AWS, and I am part of a team that is called SaaS factor, and that team basically helps different organizations that are in various stages of building or operating or delivering a SaaS solution on AWS. And as you can imagine, one of the really common themes we run into with SaaS organizations is that these organizations often are starting out in this sort of classic monolithic model where they've built sort of maybe a legacy solution or they built a newer solution and it is running in a monolithic pattern… it may be deployed on-premises, it may be deployed in the cloud, but the key theme here is that each of the customers are often running their own environments. They may be running with their own customizations, they may be running separate versions, and what these organizations find is that, essentially, it gets very difficult to scale and operate a business in this matter and they can't grow as fast as they want, the operational burden is getting higher, they can't innovate as fast as they want, and this is what really, sort of, motivates them to want to move to a SaaS delivery model. They see the efficiency of SaaS, they see the innovation pace of SaaS, they see the cost in operational efficiency at SaaS. And they are really sort of interested in saying, how can I take this monolithic solution that I have and migrate it to a SaaS model. And specifically lots of them are very compelled to move into what we call a serverless SaaS model, and that is a model that leverages AWS lambda as its sort of compute basis here and so we are going to in this session, is we are going to look at this exact journey, we are going to look at what it takes to move one of these monolithic solutions from one of these classic sort of models, incrementally into a SaaS model that is based on serverless technologies. And the goal here is to figure out how can you sort of make this transition in a way that still addresses the needs of your business but also moves you toward this fully modernized, multi-tenant experience. Now in this session we are looking at a 300 level session so we are not going to be digging into the weeds and looking at code and some of those bits, we certainly have those bits out there and I encourage you to go find them and look up the AWS Factory and other bits and you'll find that depth. But today we are going to be looking more at what's the architecture behind this model. We will definitely get into the tech of this, but we are not going to be sort of opening the IDE or looking at code. So hopefully that sort of fits with what your expectations are. Now, before we sort of get into the tech of this, it is important to sort of talk about where we are starting and where we are trying to get to, because the starting point for every business and their goals are often very different. But generally everybody would love to have the option to say, can we just go away, re-write our entire solution, deliver it in a SaaS model, and we will already be fully modernized. But that isn't reality, and that isn't a luxury that most organizations really have. Most organizations are also struggling with business pressures they have. They need to get a SaaS product to market fast, they have competitive pressures that are out there, they have market pressures, and so they are always in this sort of in this nature tension between re-write, re-build, and get to market as fast as they can. Well in reality when you set off on this migration path, we encourage people to try to get to market as quick as they possibly can. If you can at least get a SaaS product into market and you can start to get feedback from your customers, then your new version of your product, as you can sort of have all of those best practices and still have all of this feedback from your customers incorporated into that experience. Now what makes this particularly challenging is that the starting point for this from a technology perspective isn't particularly easy, right, if you look at a classic sort of monolithic architecture, what you'll see here is we have this sort of classic end-tier experience, we have a web tier and some sort of app tier where our business logic is, and some sort of storage tier maybe where our database lives, and what we find is these things tend to be super coarse grained, and they tend to have a really high coupling. So if you dig, for example, into the application tier of your environment, you might have individual services, you might have some frameworks and libraries, but what you will ultimately find here is that these services are really tightly connected and that they are really hard to sort of pull out and deploy on their own. What we will also see is that when you look at the databases, the database will tend to have really tight coupling to all of these services, so each service author essentially has the ability to go and touch any part of the database they want and we'll even see business logic pulled out of this application tier and moved into this storage tier. And so this just creates all these sort of connections that are hard, and on top of all of this, this tends to get deployed as a single unit. So we'll see the one big unit of deployment that sends out the web and the app tiers, and so this becomes your single unit of scale, your single unit of fault tolerance, all those things that are sort of classically struggling - make monolithic environments struggle. And so, this is our starting point of migrating and we have to figure out how can we get from here to a serverless, modernized model. So the good news here is that we have a really natural sort of starting point for our modernization exercise, which is one that allows us to sort of minimize the amount of work we have to put into just getting our SaaS solution available to the market. So what you see here in this slide is an example of what we would call a siloed SaaS environment. And in this solution basically what we are doing is we are taking that monolith and we are deploying it into a shared SaaS environment, so we are essentially going to deploy a separate stack for each tenant, but we are going to deploy it into this universally sort of managed SaaS environment. So, the key thing here is that each one of these environments, each stack that is deployed for each tenant, is the exact same stack with the exact same infrastructure, and they are all running the exact same applications, and that's key here and this gets us away from some of the challenges of having individual customers running their own versions, or having all of this sort of one-off customization, and this sort of fundamental to making your SaaS product available to the market. So we are going to take that monolith and we are going to make it available inside the shared environment and then we are going to surround it with all of these SaaS constructs that allow us to run and allow us to operate our business in a SaaS model. So you see for example at the top we introduce onboarding and identity, and we will dig into those in more detail, but essentially this gives us a way for a tenant or for our own processes to come in and provision a new tenant into this experience in a very frictionless manner, and be able to associate users with individual tenants and flow that tenant context into the stacks of our offering. Now on the left hand side you will also see sort of some of the operation bits we have to bring along with us to make this a fully SaaS environment, so we will need new Dev-ops and new deployment sort of mechanisms to deploy the SaaS environments, and we will need new management and operations tooling, that will allow us to collectively manage all of these tenants through a single pane of glass so we can see the health of individual tenants, or the collective health of the overall system all through a single, unified experience. But then also on the right hand side you'll also see some of the other bits we will have to introduce to make this a SaaS environment. We are going to need to have some notion of sort of metering and billing here that will let us capture the activity of tenants in our environment so we can generate a bill for them. And you will also see metrics and analytics. Here is where we are going to introduce an instrument, your monolithic environment, with new metrics and analytics, that give us visibility in how tenants are consuming our environment. But the best news of all of this is, it lets you essentially move your monolithic environment in, present it to your customers as SaaS, and buys you the time to now say, okay, how can I now begin to morph this into a modern application. Now the first step in that process, to me, and the step that I will sort of drive home here and I'll drive home at the end of this is, you should start this entire process by introducing tenancy into your environment. Some organizations will go away and build their multi-tenant application but build it with one customer, one tenant in that environment, and that really doesn't exercise a lot of the multi-tenant pieces that we need to put into the belly here. So from day one I would really like for you to see you putting in all these multi-tenant constructs and exercising your system, testing your system, operating your system, in a multi-tenant fashion. So the first step in that process, obviously, is to introduce this onboarding process, and what we really want, again, is this frictionless onboarding process, so this is either somebody coming to a sign-up page, or some tool you have inside, launching this onboarding process, and then having that orchestrate all the other bits that are needed to get your tenant introduced into your environment. So, we will need to create, for example, a tenant in our tenant management system, and that will store the tenant, their bill, their plan, any kind of configuration, and that will give us back some kind of tenant identifier, and then we will need to go create the user for that tenant, so we will have to take the user that gave us, the email is often the user in this scenario, and we will go out into incognito in this use-case and will create that user inside of incognito. Now there's lots more moving parts to what happens in incognito and there's other talks on that, but essentially here we are going to create a binding between the user and the tenant using custom claims inside of incognito and I encourage you to go look at that in more detail because that is pretty fundamental to this. The other bit we are going to create here are IM policies. So we are going to go out and create any policies that are needed to enforce the isolation between this tenant and other tenants. Again, another topic that has a lot of depth behind it that I encourage you to go look at. Finally, you are going to go out now and say well now we've got the tenant, we've got the user created, now we've got to go out and create a relationship to the billings system. Often you either have a third party billing system or you have some internal billings system, but as part of having a new tenant come on board, we have to create that tenant inside that billings system so that they are set up with whatever plan they have or whatever billing constructs they need to generate a bill for them. And then the last piece, which is sometimes optional, but is required in this particular use-case, is the provisioning of your actual tenant environment. So here, because we are running in a siloed model, each one of our-each one of our tenants has to have infrastructure provision for them as part of coming onboard, and we will look at that in more detail. But, fundamentally, when you have all of these pieces in place, you now have the bits you need to identify a tenant, identify their isolation policies, know what their relationship is to billing, and you have all of their infrastructure created, all by one automated process. Now, I said we would talk about the-what that automation and provision looks like, let's dig into that a little bit more. So if you look at what we are doing here as our starting point, because again we are starting with the silos, you'll see that we'll come in, we'll come in through route 53, you'll see we have a subdomain here which is tenant one, that identifies our tenant here, and that tenant will be routed to the infrastructure that is supporting our silo, in this case I've shown a VPC, multi-AZ, classic sort of AWS constructs, along with some compute and some storage. Naturally what's in this will depend on what's in your monolith to get it running, but generally look at a VPC per tenant kind of model as a really common approach that we will see people use here. Now that's a tenant that is already running, but we now want to onboard a new tenant, so we will come in through our onboarding process, we will register this new tenant, and like the last step in the previous slide, we will now provision all of the infrastructure needed for this tenant, in this case another VPC, AZs, all the things that are needed here, we will provision that into the common environment, and then the last step in this will be to actually set up the routing, so tenant two, now when they come in, they automatically route. And the nice part of this is, once all of this is automated, adding ten more tenants, adding one hundred more tenants, it won't really matter, you've got sort of all the friction removed from this experience and you can sort of ask the business, go ahead, bring me as many tenants as you'd like, obviously you have to think about limits and scale and other sorts of things in that equation, but in general, you are ready to sort of grow the business in a SaaS model. Now, the next piece of this is, now that we have these tenants here, is that we have to think about how we are going to get tenant context for these tenants and flow that through our architecture. This really happens during the authentication process, so here I'll authenticate a user, and then as part of authenticating I'll go out to that incognito identity provider and get the data that I created essentially when I provisioned this tenant and so that will return to me a JSON webtoken, a jwt, and that jwt will have in it not just my user identity but also all of these other attributes that represent me as a tenant and so the user identity plus the tenant identity often gets what we'll call a SaaS identity, and that gives us this first class object that we can then flow through our architecture and give us access to these tenant attributes any time we need them. So here you'll see I flow the jwt into my siloed SaaS environment and you could say here, well do you really need the jwt here… well not-maybe you don't need it so much yet because your siloed and each silo sort of already knows which tenants its associated with, but there are even use-cases here where that jwts needed for you, which is, if you look for example at logging, as we log now, we are not just going to log, we are going to log with tenant context, so we need this jwt to say which tenant I am logging on behalf of and record that information to the log, or if we record metrics or metering or billing, all that needs tenant context. So even while we are still in this monolith, we can use this jwt to access that context. Okay, so now we've sort of got tenancy established, we are running in a siloed SaaS model, we have all this first class sort of constructs in place, the hard question is now, okay, how do we start to cut over to a modernized architecture. How do we get to that serverless SaaS architecture, and the starting point for this is pretty obvious and straight forward, right. We are still going to have our monolith, so when we come in, we will have two tenants come in, and they'll hit our routing, but when they hit the routing they will still go to the individual monoliths, and at this point, that all still remains exactly as it was. We'll also see we have these sort of shared services we talked about running on the side over here, tenant management, user management, and so on. But now we at this point we get to stop and ask ourselves, how can I start to create the first serverless microservices for my application, and what we are going to do now is look at our app and try to identify some really good candidate microservices that can be the first microservices that come out of our system. And we will talk a little more about it, how you might identify those. But right now the key here is that we've identified some piece of functionality that makes a good target to carve out first, we'll carve it out, we'll have our first microservice, and now you'll see here, my web tier comes-when I come into my web tier it may be hitting the old monolith app tier or it may be hitting my new microservice, and this microservice is now a multi-tenant microservice and now it is shared by both of these tenants, we are not going to have the silos anymore, we are slowly moving to a multi-tenanted serverless construct. The hardest part of this, though, is not just identifying this microservice, as part of moving this code out to this microservice, you also have to bring the data with you. And this is where it can get really sticky because if you have these big monolithic databases, how do I find a domain of data that I can carve out that isn't somehow dependent on by fifteen other services that are inside my monolith, and this is just sort of the challenge of getting these first services up and running. But when you bring it out, you really want it to be a first class microservice that has-that is incapsulating the data and providing you a true microservice experience. Now – an alternative sort of path for this and one that I-we sort of encourage people take here is to also start thinking about how to break that web tier out of the monolith as well, and the first step in that process is often to say, let's take that out of individual stacks of our tenants, and let's have a shared, multi-tenant web tier that can scale on its own but it's truly multi-tenant, so we get the economies that scale what we want here, this can scale in and out, it is a little easier to manage, costs us a little less, but we mostly leave it intact, we just break it out as a shared multi-tenant construct, and then we go through a routing construct to get to the app tier and the microservices that we have, but now we have at least created some boundary between our app tier and our web tier and they are clearly sort of separated from one another. Now the best evolution of this, if you have the opportunity to do it, is to pull that web tier out and truly move it to sort of a modern application experience. So here, if you look you will see we have our microservices and our sort of our monolith and our microservices and our shared services, and now what we will do is we will take that web tier, and we will actually move it out to a single page application and run it in React or Angular or one of those modern tools and we will use API gateway to connect to our services. So here you'll see, got my application running and hosted on S3 here, I am coming through the API gateway, and then the API gateway is hitting the individual services of my application. And the really cool part of this is, is that once I get to this stage, now it is really just my job to figure out how can I slowly move the rest of the functionality of my application over to these microservices, and what will see is that monolith slowly sort of fade away, and the more and more microservices that you move over, the more momentum you create, and the faster this evolution starts to happen, but when you are all done, the good news is, you've just-you got a fully modernized architecture – your serverless microservices, your modern web app going through the API gateway, and you've got all these surrounding bits of SaaS there ready for you. Now one of the things I really encourage people to do is to not cut corners when they build these first services, right. When you build this first microservices, you're laying the foundation for all of the other microservices that are going to come in your system. And what we tell people when you are building a microservice, invest heavily in hiding away the details of tenancy from your developers, so for me it is ideal if a developer feels like they are just writing a single tenant sort of application, something that has no awareness of multi-tenancy whatsoever, and that all of sort of the nuts and bolts of how multi-tenancy work are entirely outside of their view. So in this example you'll see how I put logging and metrics and analytics and data partitioning and data access sort of in these libraries that are on the outer edge and my code and my function just essentially says hey I want to log something or I want to record a metric, or I want to get to data, they don't worry about what the tenant context is, they just take the jwt token and pass it through that experience and let that get resolved outside of their view. Even with tenant isolation we will do the same thing here, right, we will try to enforce tenant isolation in a way that is outside of the developers. But the key take-away here, no matter how you surround the libraries, is that you don't want to policies of your multi-tenancy and details of your tenancy all through the function-all through the functions of your serverless application. You want to push that out to common constructs. Now one way to do this that is really powerful inside of lambda is by using this notion which is called lambda layers, and a lambda layer basically lets us say, hey we are going to create this shared, separately-deployable construct that has all this shared code in it, and we are going to be able to deploy it in a way that is used and referenced universally by all the functions of our applications. So, if you look at the right hand side here you'll see logging and metrics and these things we've been talking about deployed, and they are deployed as a layer, and then I have the functions of my application on the left hand side and these individual functions all just reference that layer, so if tomorrow I decide I have a different way I want to handle token management or logging or something of that nature, I can update those policies inside the layer, deploy a new version of the layer, and then have these different functions just get access to that new layer without having to-to sort of redeploy their services or at least not make a big invasive change that somehow spans all of these services. So this is super powerful construct and something within the serverless side we encourage very strongly. Just to get a sense of what that might look like, we have a metric example here. So I have a function that is in my microservice, that microservice wants to record a metric, but I don't want the developer to know much about it, so they just say record metric, pass the token and the metric through. Some metric services in the layer here, that is going to say, go get me the tenant ID, using the token, that will crack the token open, get the data out about the tenant, return to the tenant, and then it will actually publish the metric with the tenant context. And all of this code here, the metrics, the token management, all of that, is running inside of a layer. Now the thing you have to factor into all of this is, well all of our new microservices get all this goodness because we are building it into these microservices as they come and you still have this monolithic code that's out there that needs to participate in this overall SaaS experience. So while we'd love to say you're not going to touch that code and we can leave it entirely alone, the reality is, to introduce tenant context and apply tenant context fully across your whole operational experience, you may have to go back and retrofit in some concepts into the monolithic code here. So, if I want tenant aware logging, for example, I'm going to want to introduce some kind of framework and inter-change my logging here in my monolith so it sends this log message, it pulls out the tenant context, and it sends that tenant context through. Same with metrics and billings and so on. So we're going to have to modify some of that monolithic code to get all of these other bits to work, and I think that that is worth it because you certainly don't want to have a situation where, oh here is all the goodness coming out of my new microservices, and then I have this sort of separate puzzle to put together for the monolithic operational view of this. So I mentioned earlier that we'd try to like, talk about-what are the best ways to find the services that are the good starting points, and there is no magic bullet here, and a lot will depend on your domain and what your monolith looks like, but there are some patterns that I've seen. Certainly-if one of the ways I've seen people approach this is to just go after things that have minimum impact on the business. Can I find a service that if it were to have fault tolerance, if it were to have the ability to withstand issues, so if it had outage it wouldn't impact or cascade through the entire system, that may be a really good starting point because then you have the freedom to sort of do what you want with that service without-without worrying about the overall continuity of the business. One of the more obvious ones is, is just finding the services that are not tightly coupled, like if you can find those, they are often hard to find in a monolith, but if you can find those, that is often a sweet spot and a really good place to get started. And then, this one is-sorta feels like in opposition to the others, but it is a possibility which some people will say there is this really huge pain point in our existing application, it is a huge nightmare for us, it is already imposing all of this operation burden, can we use that as the target for our best service and yes, that adds risk, but we also start to address real pain points in our existing environment. And the last one is really-really more about these data. Can you find data domains, can you find areas where the data decouples – I wouldn't want this to be a data driven exercise, you should find your microservices based on the right set of criteria, but sometimes the data can help steer you toward that. So what are some of the key takeaways here. Well hopefully you can see that this silo SaaS model that we start with, that really buys us a lot of time, right. If we can get into that environment, surround that with all that SaaS goodness that we talked about, now I can present to the market a SaaS offering, take some of that pressure off, and really allow myself to think about how to be deliberate about my grading incrementally the rest of that application to this serverless SaaS model. I also hope, and I know I drove this home pretty hard and I'm sort of going to emphasize it again, which is start out with these tenancy concepts being introduced in your environment from the very beginning. Think about what it'll need to operate it, think about how you'll do logging, think about how you'll do onboarding, do all of that early, cause now when you have that surrounding your architecture, it will force sort of multi-tenant questions inside the implementation of your services. The other thing is, you'll know that your monolith will have to change some, right. There's a hope that you can minimize that impact, but I also want to be realistic – some bits of your monolith are going to change here. We just want to try to sort of balance how much we change that versus what it will mean to migrate that to a new serverless microservice. And then the data piece of this, there is just no getting past it. It is a hard part of this puzzle, especially at the very beginning, and I think as you get further down the line, it gets a little easier, but-but expect that you are going to spend a little while figuring out how to tease things out of your data model. And then really I couldn't emphasize this more, expect that you are kind of going to get the first few services wrong, right, like you may end up picking some services and then iterating on, decomposing them further, and so on, and this sort of ties into my next point, which is just expect them to evolve. Like don't think of them as a one-time decision, expect the overall service landscape to evolve. And finally, when you build these new microservices, set the serverless bar for them high, set the multi-tenancy bar for them high, build really good foundational services from the start, and then use those foundations services to sort of see the momentum toward the next set of microservices that you are going to build. Now I did want to highlight really quickly that there are some additional sessions that are going on over there – I'll just let you look at the screen - but we are looking at EKS, and some new offerings that are coming from the SaaS Factory team, there is also content available on the AWS SaaS Factory page around lots of these topics so I encourage you to look there. But I hope this was a really helpful session for you, I hope you got a lot out of it, really looking forward to seeing more and more people succeeding in migrating their solutions to a serverless SaaS model, and hope you enjoy the rest of the conference.
Info
Channel: AWS Events
Views: 2,526
Rating: undefined out of 5
Keywords: re:Invent 2020, Amazon, AWS re:Invent, API304, Application Integration, Amazon EventBridge
Id: oso7Pb33LK8
Channel Id: undefined
Length: 27min 3sec (1623 seconds)
Published: Fri Feb 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.