AWS re:Invent 2020: Best practices for containerizing legacy applications
hi my name is diego i'm a senior solutions architect in aws and i'm specialized in migrations and on this session i want to highlight what types of legacy applications and associated factors that will make a good candidate to be migrated to containers and i will also discuss some of the best practices and some of the application changes that can have to be taken in consideration as you embark in your migration journey so the legacy application as part of your enterprise migration journey you'll probably find some really interesting legacy applications that happen to be running in your data center for years and legacy doesn't necessarily mean old but applications that are existing and they are in production and they are an important component for your business so assuming some of these applications were built years ago it's probable it's probably that they could have some very interesting design pattern or architectural decisions that were made before cloud existed and some of these applications would be totally fine if you decide to migrate them to aws using a lift and shift approach like using cloud endure or sms or maybe vmware cloud on a blast and all that has been proven to work and there's some benefit related to this lift and shift approach but at some time you would like these applications to evolve and during your migration planning somebody from your team might just come with this really good idea let's containerize this application yeah it sounds really a good idea and on this session i want to explore some of the application patterns and characteristics that would make a good candidate to become a container as well as some easy modifications that you can apply on your software to turn it more container friendly as well some of the challenges that you could face during this journey so i hope you enjoy well so why does it sound as a good idea to put your legacy application in a container that's because you might have the impression that by default you will inherit all the great benefits that operating in a container environment would provide that you can increase your agility by developing and deploying faster newer versions of your application to achieve your business goals or that your applications are going to be portable and you can run in any container compatible environment and that you are also going to be able to scale this environment and keep your applications isolated from other applications and that you can reduce your rt operational overhead to achieve optimize compute infrastructure because containers generally they might use less space than a virtual machine and that require few virtual machines or operating systems to manage and in some cases you can squeeze more applications per server yeah although all those benefits are true they can only be achieved if you understand the following we're talking about legacy software legacy applications and legacy software that they have been built years ago using some architectural patterns that are not really cloud focus and these applications they would have to evolve some architecture decisions that you done in the past they should not be repeated in the container world uh i would include as well uh the lack of domain knowledge on legacy applications because uh sometimes people don't remember how that application was built or how to install that specific application uh or you don't have the source code anymore that could be also part of the problem which includes legacy uh platforms you might be running on some unsupported uh older version of linux os or windows os some legacy version of java or tonkat or net that that will also have to evolve and connecting to that your staff so uh your staff is busy with their day-to-day operations and not necessarily they are experienced into into container technology so there will be a learning curve which affects operations because operating in containers is slightly different than operating on a virtual machine the way applications are deployed the way you connect to these applications for troubleshooting your backups everything changes so to achieve all those benefits mentioned in the previous slide it's really important that you select the right applications that should be containerized and to invest as well in your staffs to learner to learn container technology well now that we understand the challenges uh and also the benefits about moving to container let's talk about the four steps that would be that would have to be followed to migrate your legacy application to container the first one is to discover and understand how application works and then if we have multiple applications select and prioritize what applications will be containerized then you have to prepare this application before creating the container or make some small changes in the application to make it more container friendly the third step you build the container and you have to publish that in a container repository and finally you have to launch the application and put the application uh to operation uh it's important to mention that there are a lot of tools in the market that can help you with all those phases but i want to highlight aws app to container so in july 2020 aws released aws f2 container or a2c for short it's a command line tool for modernizing.net and job applications into containerized applications hsc discovers and analyzes all the applications running on your servers and you can simply select the application you want to containerize hlc will package this application artifact and run time dependencies into a container image you can configure the network parts and also generate ecs tasks and kubernetes pod definitions to be used to launch your applications so for the preparation phase i'm also recommending here that it's just something manual that you should want to execute because that depends in some factors and some other architectural decisions well so let's get started just covering with the first step which is discovering this legacy application and for that i'm going to use a pattern i would call that all in a box i'm going to use this application just an example because it makes things simple and let's pretend my legacy application is composed by another unsupported version of linux tomcat or maybe java running some older version i have a database that happens to be running in the same server the way i deploy this application is manual i have to log on into the server and mainly copy files and put the files in the right directory this is just an example but it could be the same principle if you're using windows or linux or different applications the important part is does it sound familiar to you i mean virtual show hands if you've seen this architecture before well how can i translate my application into something that's going to be more useful to containers or how can i have a more prescriptive discovery so i can determine if this i have a good candidate for the migration and you can run a simple discovery script um or um there are really a lot of good tools in the market that can help you to automate the discovery an app to containers is one of those uh which can detect your application and application dependencies but uh i'll focus here on the more conceptual principles so i'll start with how your users consume this application and what network parts are in use what protocols are you using it's a web application using http or is a tcp udp based protocol do you require to have encryption on that application ssl or any other kind of encryption or maybe a proprietary protocol this application might have or not a platform by platform tomcat jboz websphere iis is there any schedule task that requires this application to work what's the underlying operating system well really the focus also should be more towards um your application along with these other questions that i just made so how is this application is it a compiled application is it a script application like php or python do you have the source code not that source code is a requirement to become a container but it helps a lot when you're making these architectural decisions uh where is the configuration file is is the database connection defined uh into this configuration file where do we store the passwords to access that database uh is that information in the configuration file as well and where does this application save data for example if my fake application it has um a folder where i upload documents as part of this application functionality in what folder am i saving this data and how does application handle sessions uh is it a stateful session a stateless session can can it operate behind a load balancer without you having to worry about sessions management yeah i know it's a lot of questions but that's for a reason the answers will help us to drive the migration path and strategy so once you collect all that information we can use this diagram to understand and baseline the challenges that we'll have to address while creating the new containers out of this legacy app and i will demonstrate some of the factors that can be considered when selecting and prioritizing an accessing application my recommendation is that start with the easy ones select one that has a modern development language where you have the source code and web applications are generally easier to go to containers especially if they have a stateless um if you have a stateless application and also where you're saving data into a single folder and you have only one single configuration file that you need to modify for that and as you get more experienced and confident about containerizing applications you can start moving to the more complex applications some other advice i want to get to you uh just because you can do it that doesn't necessarily means you should do it and evaluating this application is a must do for just about any application so if you do determine that uh it would have a real value on in moving this application to a container then you have to measure the effort to achieve that outcome now that you discover and understand the priority of what applications are going to be containerized it's time to make some adjustments into this application so it becomes more container friendly and i will start with two basic container concepts uh first one is containers they should be portable that means you might want to distribute or use the same container in your test dev environment or if you're a software vendor which you want to distribute your container you want to use exactly the same container image so that means creating a container without uh user names or passwords or connection strings to that container you want to make it flexible and portable and not do not include any other dependencies like your database because as a good practice each application or each component of this application should be put on their own container and the sec second factor is containers they are ephemeral so that means they can come and go scale or not with your app and uh and being terminated as part of this uh scaling mechanism and with that being said you should not store application user data in the container and that includes your database data logs any other kind of user data that data it should be saved externalized from the container and i'll show you some alternatives on how to do it so if i cannot store my database connection string in the container where should i store it well one of the most important principles in containers is to pass the parameters to the container during the container launch such as connection strings credentials other parameters and that's achieved by using environment variables there are some other architectural decisions uh that you can select for example side cars but for for this session i want to keep it very simple so when you launch a container with your application you have to create a deployment configuration or a task depending on your container technology as you can see here on number one where you can define parameters as a database name or database hostname and this container platform will use this information to inject those values as an environment variable in the container one of the benefits about using amazon one of the container offerings in amazon like ecs or eks is that you can use the parameter called value from so you can store your parameters securely in aws systems manager parameters or aws secrets manager without having to worry about passwords being shared as plain text and when you launch this container that has your application as you can see here on number two the parameter will be presented to the container as a variable so your application on number three can read that information and use that properly and for that there are some changes that you can make in your application that are easy to manage or especially if you have the source code on my left side you will find a hard coded approach username password ip addresses everything is hardcoded in the source code my recommendation is that to change this approach to what you see in the other side where you tell the code to get a specific system environment db underscore name for example and that will give you some freedom to connect to a production or to a test database without having to modify your source code or create a new container every time for applications that read that information out of a configuration file a different approach can be used on my left side again simple configuration file everything is hardcoded my username password database ip address connection strings what you can do here is to modify this configuration file and replace some strings replace it with some strings that are unique for example f underscore db underscore name and then you can use a script using unix set for example to replace that string with your environment variable before you start the application as you can see on this green box so you can replace your environment variables that the container is receiving receiving from the task definition ingest those values into the configuration file and then finally launch your application some other modifications that you can do uh in the application prior to containerize it by default docker shows uh the command line outputs uh as if you're running a command in in a terminal uh if we use uh the linux case we're talking about the standard std in sd out and sdd error outputs the good thing is there is one docker driver that's called aws login driver and that driver will send those logs to amazon cloud watch logs by default but what about your application level logs well a quick fix that you can do is to create a symbolic link from the log file that your application saves into one of those io streams for example you can link var log my app log to dev std out and how to address this storage data the storage data situation so why not leveraging the existing nature of this application writing files directly to the operating system uh you would have to know in what path this application saves files and you can use amazon fsx for windows or efs for linux and configure that in your deployment or configuration task as you can see here in number one again my example my application saves data into the slash upload folder so i can define it in my configuration deployment to mount my efs volume with that specific path and and that will be mounted in my container as you can see here on number two the application number three will operate the same way to use to operate prior to be converted into a container because it reading write files out of that specific path which now is mounted externally this is a really nice approach because it i it adds some features in your application like highly available and elastic file systems uh and external backups now that i cover how to discover applications and some quick modifications that you can make in your application to make it more container friendly it's about time to launch and to build and launch your application my first recommendation is that you spend some time learning on how to use docker files to build a container app to container can generate those files for you but it's a good practice just to understand how docker file works on my left side there's one docker 5 example and i just want to use some of these items to highlight the first line is from base image that's the image that will be used as the base for holes in your application my recommendation is that you don't blindly trust any image that you download from the internet that's it's appealing it could be another factor is that when selecting this base image is to keep it very lightweight because you want to and of course only containing the very minimum necessary to make this application to work uh the next line you can create a symbolic link to redirect your la your logs as to the right output file as you can see redirecting my log file into stand out std out and the next script is to invoke the command to replace the strings in that configuration file this the unix set screen that i mentioned previously and finally you invoke the entry point or the binary file for application to start on my right side is just an example of a deployment configuration on ecs where i can define the log driver that is going to send logs to amazon cloud watch logs and the environment variables that sets my db name my database username and also that my password is a story on a secured way using aws secrets manager i'm also telling in the last line on how to how my container should mount my upload path into my efs volume so as you build this container you might choose the path of doing things manually and that's totally fine but why not doing that in a more automated fashion this is just a suggestion but app2container can create this workflow for you where every time you commit a new code into a repository as you can see here on number one it will build a new container for you on number two through a code pipeline and finally result it will be storing that container image that was just built into amazon ls container registry or ecr as you can see on number three and again one of the benefits about storing your container images into elastic container registry is that you can enable its vulnerability scanner so every time a new image is published it will automatically scan that image for you other functionality that app to container can provide is the capability to create confirmations that can be used to deploy your ecs fire gate or your eks cluster containing as well an elastic load balancer so the same image that epic container created for you on number one will be updated in the task definition of your far gate as you can see here on number two so as you already modify this application prior to creating the container you can leverage some of the aws services that can be integrated with containers such as rds efs secrets manager or amazon cloud watch log as you see on number three to deliver a modern elastic and highly available version of your application as next steps i'll start recommending select your aws container technology ecs eks fargate or even manage your own container-based solution start selecting what applications you want to experiment as part of your migration journey and to modify those applications to leverage some of the cloud-native technologies you can also find some real reusable patterns in your company you can use the same base image for example a base image that contains the same os or platform and just reuse it across your other applications and finally if your application is too heavy or is not scaling as expected start considering breaking this application into smaller applications or breaking the monolith with that i finish here this session and if you're looking for more content related to migrations please check one of these links in this deck that's all i have for today i hope i've had a good time and enjoy your reinvent 2020
2021-02-09 11:26