Docker on Amazon ECS Fargate using CloudFormation - Episode #9

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we will step through the deployment of a containerized application on Amazon ECS using cloud formation and CLI this is not an introduction to ECS or containerization or even cloud formation if you have not used cloud formation before I suggest you watch episode seven besides the basics of cloud formation you will need to have the basic knowledge of docker docker registry creating or building docker images etc let's take a look at the steps that we are going to go through in this video we are going to start by creating a simple API application create or build docker image for that application and test it locally using AWS CLI create a repository for our docker image on ECR or AWS ECR and push the docker image into that registry next we will define a cloud formation stack to define a VPC to subnets across two of the availability zones on an AWS region creating VPC and subnets will also involve defining things like internet gateway Rob tables and so on next we will define a cloud formation stack to create resources such as ECS cluster application load balancer load balancer listener for port 80 cloud watch law group for the containers and a couple of security groups and then define a cloud formation stack to create task that configures the container and then create a scheduling service that runs the container or the task and define deployment configurations configure the container locks and load balancer rules and so on configure it in a way that on launching the task instances or container instances it will fetch the image from ECR and it will register the container onto the load balancer and also hide the container logs go out to cloud watch Law Group that's a lot of things to cover in a short video I'll try to adjust the pace to not drag this too long so let's get started I'm going to be using the AWS CLI to create or delete stacks on AWS instead of the AWS management console let's go to the terminal window create a project directory I will name the directory as docker on ECS and go into that directory let's open that in a code editor I'll start by creating a tiny API application that we then containerize or docker eyes create an app directory and I'll create a service name it as service dot RB this is a simple Ruby service in a few lines using Sinatra framework I will paste in some code here as I said it's a Sinatra app so it needs to require those libraries here is a simple data model book that defines a static list of books each with an ID and name attributes and two class methods one that returns a list of books and another one that does a book look-up by book ID here are the two default and health check URI pads for the service both return a simple text response with 200 response code here is the namespace for API endpoints let's say all of our API endpoint or URI paths start with slash API here it sets the default content type as JSON and defines two endpoints here one that returns a list of all the books as a JSON response and another one that returns a book by book ID in the URI path that's how simple the API implementation with stub data is so I have copied the following files docker file to define docker image for this simple application and other two files gem file and gem file lock for the Ruby application so let's not go into the details of those files let's build the docker image locally command is docker Bill tag books API and the directory of the docker file app in a few seconds we had the docker image created and tagged as books API : latest now let's run this container application locally and tested command is docker run with some options the Sinatra app runs on port 4567 in the container and let's expose that on the same port on the host as well so the port mapping is 4567 and both container rhine host an option to remove the container after the container is stopped and the image name books api latest which is on local here we have the application running in container and available on container port 4567 and is the same port on the host as well let's go to the browser and test request localhost 4567 which is the default health check endpoint which responds with a text message that looks good now request the API for listing the books localhost 4567 slash API slash books and that returns a list of stub books as JSON that looks good let's start the container and now we need to push the docker image to a registry Amazon ECR on another terminal window let's create a new repository on ECR for our books API image I have the AWS CLI configured with a default profile create a repository now command is AWS ECR create repository repository name books api for our docker image and something repository on ECR has been created and we had the details here now let's login to the docker registry or ECR for which we will need login credentials with easier we can get the login or docker login command using CLI and the command is AWS ECR get log in with some options this will return docker login command to ECR with an inline password so i will pipe the output to a shell and that runs the docker login command now here the doctor login to ECR is successful that's good now let's push the image to the repository on ECR we need the repository URL which was in the response of create repository command let's get that using ECR describe repositories command AWS ECR describe repositories repository name is books api and here is the repository uri let's copy that we will append the repository ura with an image tag say v1 no tag books API latest image on local as the repository URI : v1 and the command is docker tag books API latest paste in the repository URI : v1 now let's push the image to ECR the command is dr. push repository URI : v1 submit while the image is being pushed let's verify the repository on AWS management console under services go to elastic container service and on the left hand navigation go to repositories here is the ebooks API repository created from CLI switch back to the terminal window now the image has been pushed to the repository let's verify that on the management console click on books API repository and here is the image tag v1 now let's start creating cloud formation stacks to define the infrastructure and resources to run the container application on ECS let's define a cloud formation stack template to create VPC subnets and resources to define Internet gateway and drop tables etc I will create a new directory called infra under that directory let's create a stack file I'll name it as V PC double let's define the stack template version and some description for the stack V PC for ECS test and now define the resources there are mainly three resources in this stack one is the V PC and 2 subnets subnet one in subnet two for V PC the type is AWS ec2 V PC and the properties to make it quicker I'll paste in some properties here cider block that defines the IP range available within the V PC enabled DNS support to set the true enabled DNS host name to true with us the instances launched within the V PC gets host names and instance tenancy is default now let's define subnet 1 the type is AWS ec2 subnet and let's add some properties v pc ID is the V PC defined above which is the V PC the subnet will belong to we can use ref function to refer to the V PC resource defined in the same stack we need to specify the availability zone for this subnet the default region that the CLI profile is configured to is us ps2 and that region has three availability zones and we need to pick the first one for this subnet one option is to use the hard coded zone name and another option is to use predefined functions to fetch a list of availability zones and pick the first one we will go with the latter use the function get a ZZZ that returns all the availability zones and use another function that selects the first one or the one at index 0 Sider block for the subnet within the V PC at my public IP on launch - true but this the instances launched within the subnet will have a public IP address now that's all for the subnet one let's define subnet to copy subnet one properties and paste in for subnet two as well a couple of things we need to change for subnet to pick a different side of block within VPC and change the availability zone to set the second availability zone or the one at index one that's it both the subnets have been defined now in order to allow internet connection to the V PC or resources within V PC or subnets we need to create Internet gateway route tables and associate them to both these subnets let's create an Internet gateway I'll paste in two lines of code for this resource resource type is AWS ec2 Internet gateway now we need to attach this Internet gateway to the V PC create another resource which is of type AWS ec2 V PC gateway attachment and the properties our Internet gateway ID references to the Internet gateway defined above and the V PC ID which references to the V PC defined in the same stack Internet gateway has been attached and now we need to create a route table within this V PC here it is the type is AWS ec2 Rock table only one property V PC ID which refers to the resource V PC now let's associate the route table to both the subnets for subnet 1 create a subnet 1 drop table Association named it as route table Association one type is AWS ec2 subnet route table Association first property is the subnet which references to the subnet 1 that's defined above and second property is the route table ID that references to the router table resource definable repeat the same to associate subnet 2 to the rock table here it is about table Association 2 subnet ID references to the subnet 2 resource drought table ID references to the common rough table resource now one last thing in the V PC stack and that is we need to define or create an Internet router that links the internet gateway route table and defines destination address to allow the connections here it is type is AWS ec2 route depends on the create now VPC gateway attachment we define above this means the Internet gateway and VPC attachment is completed before this resource is created gateway ID references to the Internet gateway define above route table ID references to the router table define a bar and lastly the destination side block for this route easier one is zero zero zero zero slash zero that's all the resources we needed to define in the stack I'll have to keep the detailed explanation of VPC subnet route tables route gateway etc out of the scope of this video as that itself is a separate topic and it will require a good amount of time now that we have all the resources defined let's output some of the resource identifiers that we need to refer in these stacks we are going to create next first output is V PC give it a description which is optional value of the V PC can be fetched by referencing the V PC resource defined above export as a variable that it can be referenced in another stack give the variable a name I'll name it as V PC now one more output is subnet one give it a description value is a reference to a subnet one export variable subnet one let's repeat the subnet output for subnet two as well that's all for this stack we have defined a B PC two subnets one each on two of the availability zones Internet gateway attach that to the V PC route table and associated the route table to both the subnets internet route that links gateway router table and destination address range and finally output DV PC and both subnets to be referenced in these stacks we are going to create later switch back to the terminal window and execute a command to create the stack on AWS the command is AWS CloudFormation create stack stack name and name it as V PC and the CloudFormation template template body file colon the current working directory / infra / vp c dot llamo now before i excute this command let's review the template one more time for any typos or errors here's one this should be outputs plural and for both the subnets I need to remove the properties under properties tag let's do that and that looks good under the outputs again subnet 1 is repeated the second one should be subnet 2 this is good now let's go ahead and run the command the command is successful stacker is being created and we had this tag ID in the response let's go to the management console and go to services cloud formation and there is the stack VPC which is being created a few seconds fast forward we have the stack created now let's go to the outputs tab and here we have the outputs from the stack creation these are the three outputs we have defined VPC subnet 1 and submit to export name is what we will be using to reference these resources from the stack in the stacks we are gonna create next now before we create other stacks let's create one more stack that will define I am roles or identity and access management role that we need for the containers to be able to interact with cloud watch and ECR let's copy the bpc template and name it as I am DMO so let's clean this up and update the description roles and policies let's create a new resource and name it as EC as task execution drug which is a role that we need to assign to a container task in ECS we will know how that helps later when we run containers on ICS type is AWS I am row and add properties I will paste in some code here let's not go into the details at a high level this is the role for ECS tasks that we will define later and policies allow permissions to resources on ECR and cloud watch Law Group from the tasks or containers let's also output this role so that it can be referenced in the other stack templates I will paste in the code to output notice the value of the output instead of using ref function it uses get at or a get attribute function to read a specific attribute a RN from the resource ECS task execution role and name of the export variable is ECS task execution role and that's not for the role definition let's go ahead and create the stack on AWS command is AWS CloudFormation create stack stack name I'll name it I am and using template current working directory infra IM dot llamo submit and it failed saying it needs additional capabilities and name of the capability is capability underscore I am so a stag that creates I am roles will require this capability and the command now is AWS CloudFormation create stack stack name is I am template I am dot llamo and capabilities capability underscore I am all block letters enter and that's good stachy is being created and we have the stack ID here let's verify that on management console here it is being created and a few seconds fast-forward this stack creation is complete under the output tab we had the new role a RN assigned to an export variable the stack that we are going to define next we'll create ACS cluster or application load balancer load balancer listener and cloud watch law group for container application logs it will also create a couple of security groups let's copy the VP CR I am stat template and I will name this stack as app cluster dot llamo let's clean this up and change the description contain our cluster on ECS and a load balancer let's start adding resources the first one is the ECS cluster the type is AWS ECS cluster the only one property it will have is the cluster name let's name it as book store next resource is the load balancer for our continual application the type is AWS elastic load balancing v2 load balancer this gives an idea of kind of load balance of we are using under properties give it a name I will name it as ECS services and now I need to provide a list of subnets we will specify both the subnets we have created subnet 1 and subnet 2 now these subnets are defined in the other stack VPC and available for us to reference using export output variable we can use the function import value to reference those variables let's do that import values of net1 and import value subnet 2 next is security groups for the load balancer you can assign one or more security groups we don't have any security group defined yet let's say the name of the security group that we're going to define a load balancer security group let's define that resource load balancer security group type is AWS ec2 security group under properties give it a description or a group description specify the v p-- see represents the VPC from the other stack output variable using import value function security group ingress is where we need to specify the list of ingress values we are going to use a simple one which will allow requests or connections from anywhere The Cider IP zero zero zero zero slash zero and IP protocol value is -1 to allow all protocols now that we have the load balancer and necessary security group we also need to define a load balancer listener to allow connections on say port 80 or 443 we need to set up HTTPS and then that listener will have a default target group let's define another resource for listener type is AWS elastic load balancing be to listener and this listener for the load balancer specify the load balancer AR n reference load balancer resource defined above protocol is HTTP port is 80 and now specify the default actions to be performed for the requests on this listener default action type should be forward and that will require a default target group for this we need to create a dummy target group say the name of the default target group is default target group let's define the resource for that type is AWS elastic load balancing v2 target group I will name it as default VP CID reference using import value protocol is HTTP port again is 80 now that we had the load balancer security group listener for port 80 and default target group when the stack has created request on port will error out because that target group has nothing but we still needed to create one now let's create a resource to create cloud watch log group type is AWS logs log group the group name is say api's retention in this for the logs when they should be good that's all for the log group now let's add one last resource in the stack and that is to define a security group for the containers that we are going to define in the next stack similar to how we define a security group for load balancers that allow connections from the internet we will define a security group for containers that will allow connections from the load balancer so resource name is container security group the type a is AWS ec2 security group PPC ID reference using import value give it a description and under security group ingress mentioned the source security group ID and reference the security group of the load balancer we created above and the IP protocol again is -1 to allow all types of protocols now let's add the output section to define some export variables the first one is the cluster value reference the ECS cluster resource give it an export name UCS cluster the next is listener give it a description value reference the load balancer listener created above give it an export name short form is listener next one is the container security group give it a description value reference the container security group resource define above give it an export name I will keep it same as the resource name container security group last one in the outputs is the load balancers domain name the output name is load balancer DNS give it a description value will be the DNS name attribute from the load balancer resource use the get at or get attribute function to read that attribute from load balancer resource defined above give it an export name I'll name it as domain name now that's all for this track let's quickly go over the resources we have defined in the stack ECS cluster application load balancer listener for port 80 security group for the load balancer default target group for the listener log group for the container logs and lastly the security group for the container we are going to deploy in another stack let's go ahead and create the stack on AWS command is AWS CloudFormation create stack I'll name it as app cluster using the template app cluster dot llamo in the introductory and the stack is being created we have the stack ID here let's verify that on management console now it failed to create the stat let's see what the error is here it is error indicates the name given to the load balancer is not an acceptable format now let's go to the stack template load balancer definition the name specified in the load balancer has a space which is what it was complaining about and that makes sense as this name will be used as part of the load balancer domain name let's change that to use - instead of space save it now let's delete the stack from the Kludd AWS CloudFormation delete stack the stack name is a plaster make sure it is deleted and now create the stack again fast-forward a little bit and we have the stack created let's quickly review the outputs and it has the listener container security group cluster name and the load balancer domain name the last stack that we are going to define and create is the one that deploys our container image from ECR repository into the ECS cluster let's copy the app cluster template name it as API dot llamó clean this up and delete all the resources and outputs give it a description mainly we'll be creating for resources in this stack tasks service target group for the load balancer and a listener rule let's define the task which basically defines the container type is AWS ECS task definition give it a family name say ap ice now family here groups multiple versions of the task definitions I'll skip over the details of this for now but you will need to learn to understand how it versions the task definitions and it has a significance when you need to update the task definitions specify the CPU and memory requirements say CPU is 256 and memory is 512 Meg now define the container a task can have multiple containers but we're going to use just one give a container a name I'll name it as books API specify the image it is the one from the ECR repository that we created at the beginning we will update that in a bit let's add port mapping container port is 4567 protocol is TCP to be very specific here now let's go back to the terminal to get the docker image URL describe the ECR repository AWS ECR describe repositories here is the repository URI and copy that paste that for the container image value and append it with the tag v1 which makes it a complete image tag URL now that we have the container defined in the task with the memory and CPU requirements now there are two ways the task can be deployed to ecs let's take a quick look at the options the first option is called ECS Fargate in this we just need to define the container memory and CPU requirements and some roles that's needed for the task and then forget we'll manage the cluster and containers and the second option is ec2 now this is the default one this will allow was more granular control over managing containers on specific type of ec2 instances we have to define a bunch more resources to manage the cluster things like ec2 instance type create or choose from an ami right easy to launch configurations manage auto scaling of ec2 instances and scaling policies and so on now ec2 option isn't hard but requires us to write and know a lot more things about managing the cluster if there are specific requirements around security or compliances or even architecture you will probably want to go with this option option one is easier because Fargate will manage the cluster now when it comes to auto scale of containers nor the ec2 instances you will have to write code by adding additional resources to manage the auto scaling of tasks or containers and that's common for both the options but with ec2 option regardless of auto scale of containers you will still have to code for auto scale of ec2 instances also so we are going to go with option 1 in this video and for Fargate there are a few specific attribute values that we need to specify in the task definition let's add those properties network mode or the docker of networking mode this should be AWS PPC and requires compatibilities should be Fargate now let's add some logging configuration to the container log driver is AWS logs AWS driver specific options log group api s-- logs region so this will be the region where the stack is being deployed use the predefined variable using the reference function to fetch the current region and log streams prefix prefix to stream of logs created for every container instances on the cloud watch i'll name it as books api i think we are good with the task definition here next is the service definition service we'll define how the task or the container will be scheduled and deplore in the cluster and also it will define how the container instances will be registered with the load balancer listener target so let's define the service name of the resource a service type a is AWS ECS service and properties task definition reference the task resource that we just defined cluster is where this service will be run the one we created in the A+ tour stack reference using import value function launch type should be far gate and then desired count of containers say two instances cluster will ensure at least two instances of the container or task or active deployment configuration to configure how many tasks to run during every deployment maximum percentage I would set to hundred percent so during deployment it can go up to four tasks if the desired count was two minimum healthy percentage I would say at 70 percent this basically defines the minimum healthy containers running during the deployments the next days the network configurations AWS VPC configuration design public IP set to enabled subnets for the container instance or the tasks or the service subnet one and two that we created in the V PC stack reference using import value security groups mention the one that we created for the containers and that is container security group in the app cluster use import value function to reference now when the service is run we need to have the container be register to the load balancer load balancer takes container name the container that we need to be registered to the load balancer is books API we need to specify this because reference tasks may contain multiple containers so we need to pick the one that we need to add to the load balancer container port again 4567 target group AR n now this will be the target group where the container instances will be registered to be served by the listener or load balancer listener we will not use the default or dummy target group that we created but we need to create a new target group for our application container instances or the service let the resource name be target group which we are going to define in the same stack and that's it for the service definition let's define the target group resource the type is AWS elastic load balancing v2 target group V PC IDE is the V PC reference using import value now port we have to set some value here ideally the port should be optional for ECS containers but it is mandatory 1 so the value can be anything let's just say 80 protocol is HTTP let provide a few status and health check properties for the containers that gets registered with this target group matcher HTTP code healthy targets must use on responding to the health check codes let's use the range say from 200 to 299 health check intervals in seconds say 10 or 10 seconds between health checks for an invalid target or container he'll check path remember we have two health check paths for our container or service or the application that's going to run in container I will use the one that as /stat protocol is a HTTP health check timeout seconds timeout for the health check requests healthy threshold count say 10 the number of consecutive successful health checks that are required before an unhealthy target container is considered healthy target type value of this will depend on the launch type of the service again for Fargate the value should be IB now we had the target group where the container instances gets registered but the load balancer or the listener is not aware of the new target group yet now we want the requests on the load balancer that have you our iPod /ap I slash books to be served by this new target group or the containers in that target group for that we'll need to define a listener rule let's define that I'll name the rule as a listener rule type is AWS elastic load balancing b2 listener rule we need to specify the listener under properties reference the listener defined in the app cluster stack priority say - load balancing evaluates the rules by priority order low to high you might as well set this to 1 the conditions are condition is the you are a pad pattern comparison field a spot pattern values just one value and that is to check the you are a path for slash API slash book star or anything that follows specify the actions target group a are n reference the new target group to forward to and hence the action type a is forward with this the load balancer listener should forward all the requests that have the URI pad / API slash book star or starting with slash API slash book to the targets in the target group or the containers now that's it for the listener role let's make a small change to the service to set a dependency on the so that the Lesnar rule is created before creating the service in the stack we have defined the task definition for the containers service to scheduled the tasks on cluster load balancer target group for the container instances and a listener rule specific to our application to forward the request to the containers let's add just one output I'd like to output the API endpoint or the base endpoint or the base URI for the api's when the stack is created the output name is API endpoint give it a small description value I'll add this in a bit give it an export name say books API endpoint for the value we need the domain name from the app cluster reference using import value use join function prefix domain name with HTTP colon slash slash and the API URL path slash API slash books as the suffix that's all for this time back to the terminal window and create the stack command is AWS CloudFormation create stack stack name I will name it API using the template API dot llamo and it failed with the validation error saying listener resource is not available in the stack let's check that here we should be using import value to reference listener which is an output export from another stack that's fixed let's run the command again and it fails one more time there is a typo in the value of type of the resource service let's fix that and run it again now the stack is being created let's verify that on the management console and it is rolling back which means it fail let's see what the error was it failed to create the task and that is because we did not specify the I am role for this task we need to fix that and create the stack again first let's delete the stack AWS CloudFormation delete stack stack name is API verify that it is deleted go to the task definition and add a new property execution roll AR n use import value to reference the role that we created in I am stack and that is ACS task execution role that's it let's go and run the create stack command again and stack is being created let's verify that on the management console fast forward a little bit and we had the API stack created from the output copy the API endpoint value go to the browser and make a request to that URL and that should respond with a list of books as JSON you may test the request to a specific book resource by adding slash book ID and that also works let's quickly check the cloud watch Law Group and log streams created for the containers if the application or the container writes all the logs to standard output all the application logs should be available in one of the log streams in the log rope API so now let's go to the ECS and view the cluster here it shows bookstore cluster which is labeled as Fargate and it has one service and two running tasks under the tasks tab you can view all the containers or staska instances now that's pretty much for this video let's do a quick recap we have created a containerized api application created an ECR repository for the docker image of the application created a cloud formation stack for VPC created another cloud formations stack to define iam role for the easiest tasks to allow access to cloud watch an ECR create a cloud formation stack to define cluster load balancer cloud watch law group and necessary security groups lastly created a cloud formation stack to define tasks and service along with listener rule and load balancer target group together to deploy The Container application on ECS before I finish up I'd like to give a few pointers first one is that I chose two group resources in two different stacks for multiple reasons and I have used output or variables people refer to the resources between stack templates or different stacks now such approach of using output variables may not work for all use cases another option is to use stack template parameters if there are multiple VPC or clusters etc for different API or service groups or say product groups you cannot reuse the variables in the same region in such cases if you still prefer to use the export variables you'll need to have some sort of fun naming conventions for the output variables if I need to deploy one or more api's to be served on the same domain name or same load balancer but a different URI paths a-slash api / pricing i would define a new stack similar to api dot llamo and define the task service listener rule and target group etc once deployed this is how it'll look from the load balancer point of view and another option is to parameterize the api dot y amal stack template for example dropper image task name you are iPads etc can be sent as parameter to the api dot llamo on creating the cloud formation stack and lastly I don't consider these stack templates are production-ready but if you are starting to use easy as I would say you can take these templates modify and make it work for your applications that's all for this video I hope this helps thanks for watching
Info
Channel: Chandra Shettigar
Views: 29,093
Rating: 4.9764705 out of 5
Keywords: docker, amazon ecs, ecs, cloudformation, fargate, ecs fargate, microservices on aws, user docker container and run on fargate, aws cloudformation docker, aws task definitions cloud formation, ecs aws, docker containers, aws cloudformation tutorial, aws cloudformation deep dive, aws cloudformation example, ecs fargate vs ec2, ecs fargate aws, amazon ecs tutorial, cloudformation yaml, amazon ecs video, fargate tutorial, aws ecs fargate, ecs aws tutorial
Id: Gr2yTSsVSqg
Channel Id: undefined
Length: 36min 28sec (2188 seconds)
Published: Fri Aug 03 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.