In the past two posts, we built a Rails app in Docker and deployed it in Amazon ECS. In this post, we use AWS CodePipeline to automate building Doc...
For further actions, you may consider blocking this person and/or reporting abuse
Hey Raphael, Thanks for this!
I have two questions:
1) Im not being able to find what to use instead. of "web" in. the buildspec. Where do you find your container name? Is it related to the task definitions? If that's so, how would we handle the sidekiq and web different build commands?
2) How would you configure two have a production and a staging environment?
Hi Nico, addressing your concerns below:
" Im not being able to find what to use instead. of "web" in. the buildspec."
"how would we handle the sidekiq and web different build commands?"
"How would you configure two have a production and a staging environment?"
Thank you!! I could run the deployments!!
One more thing maybe you know how to do it. Before I did it manually but its the same thing, when I update a ECS service with a new task definition, it takes forever to update the task definition of the service and now with CodePipeline its the same thing, the Deploy stage its not ending because the deployment is not being done.
In the past I solved this by stopping the task but its not good for production environment of course.
Is there some configuration that I may be missing or is just how it is?
Thanks again!
Hi Nico,
Ahh yes, it does take awhile. This is because you are using ECS deployment controller. Essentially, during deployment it creates new tasks with the new version while the old version is running. The way I understood it is traffic is only redirected when the container reaches a healthy status and it passes the load balancer target group health check. To quote AWS documentation:
"If a task has an essential container with a health check defined, the service scheduler will wait for both the task to reach a healthy status and the load balancer target group health check to return a healthy status before counting the task towards the minimum healthy percent total."
Now, the default for "load balancer target group health check to return a healthy status" is 5 consecutive periods of 30seconds. So that's at least 2.5minutes after your containers are marked as healthy that traffic starts to get to your instances.
I'd totally recommend going for AWS Code Deploy's blue/green deployment so your traffic (or at least part of it) will be shifted to the new version right away (or in parts, over a period of time). Rollbacks are also so much easier with this design.
Perfect! Yes, that's the type of deployment Im looking for. I will try to configure it.
I figured out that my problem is that the container has 1024 MB of CPU units available and with both my tasks (each with 512), it reaches this limit so when trying to do a new deployment, I guess it tries to create the new task first and then stop the old one, but there's no CPU to have the "third" task running simultaneosly. Do you know where I can configure how much CPU does the container have?
Or should I use different containers for web and sidekiq? Maybe add to the buildspec to create two artifacts and configure each deployment to look at a different json file? What do you think?
Hi Nico,
" I guess it tries to create the new task first and then stop the old one, but there's no CPU to have the "third" task running simultaneosly. "
Do you know where I can configure how much CPU does the container have?
Or should I use different containers for web and sidekiq?
Maybe add to the buildspec to create two artifacts and configure each deployment to look at a different json file? What do you think?
This post is worth the wait! 💯This will be very helpful to us, clicking through each of the services is a hassle. 😅
I know you didn't touch on deploying to the "sidekiq" ECS service to make things simple, but just curious, if we need to do that, will we create a separate pipeline for it?
Hi Jaye, no need to create a separate pipeline. Just add a new deploy stage in the pipeline to deploy to those ECS service. You may have to change the container name of your sidekiq container from "sidekiq" to "web".
Ahh got it, thanks!! 🙏🏻
By renaming to web, wouldnt it be pointing into other Task Definition?
Thanks for this post!
How would you suggest handling one-off tasks. For example, database migrations that would need to be run before the Deploy phase in CodePipeline? Another example would be running tasks like rails console at any point of time.
Hi Tejas, sorry late reply, been swamped with work lately.
For database migrations, you can include it in your build process but you must have a process in doing so. Like forbidding "destructive" migrations (delete table / delete column) from being run inside the CI/CD. We just implemented this but only "additive" migrations is allowed (add column / add table).
Also, best to run a point-in-time snapshot of the RDS database every time you run this.
For rails console tasks, we just enter the container via
docker exec
. We have fargate containers for prod, but we left out 1 ECS container running on EC2 for this exact purpose.No worries and I appreciate you taking out time to reply. Here's what I ended up doing:
For the database migrations - I did include it in the build process but I separated the migrations into another stage in the pipeline and implemented something similar to what the aws-rails-provisioner gem does (Basically uses another buildspec for the release stage).
For one-off tasks - I ended up writing a shell script which runs a task, waits for it to be placed in a container, runs
docker exec -ti
to open the console and kills the task when the console is closed. The script could be run by something like:bash rails-console.sh --cluster "cluster_name" --task-definition "task_def_name" --profile "cli_profile_name"
Saving this for later 🚀
Thanks man! Let me know what you think :D