This is an introductory guide to ufo, an ECS deployment tool. Ufo helps you deploy Docker images to AWS ECS quickly. One pretty neat thing about ufo is that it provides direct access and control to the ECS Task Definition. So you can customize your ECS container options to your heart’s content. We’ll also talk about some of the resources that ufo creates.

Here’s a summary of the commands that we’ll cover:

git clone https://github.com/tongueroo/demo-ufo.git demo
cd demo
ufo init --image=tongueroo/demo-ufo
ufo current --service demo-web
ufo ship
ufo ps
ufo scale 2
ufo destroy

Prerequisites

This guide assumes that you already have Docker installed and you have an ECS development cluster with EC2 container instances. If you do not have one, you can create one by following the Creating a Cluster ECS docs. For simplicity, I’ve created an ECS development cluster choosing the “EC2 Linux + Networking” option and selected the default VPC.

Clone the project

The first command clones the project into a demo folder.

git clone https://github.com/tongueroo/demo-ufo.git demo
cd demo

The project is a small demo sinatra app that returns the meaning of life: 42.

Initialize the project

The init command creates starter .ufo files. These files are used by ufo to generate an ECS task definition. The output will look something like this:

$ ufo init --image=tongueroo/demo-ufo
Setting up ufo project...
      create  .env
      create  .ufo/params.yml
      create  .ufo/settings.yml
      create  .ufo/settings/cfn/default.yml
      create  .ufo/settings/network/default.yml
      create  .ufo/task_definitions.rb
      create  .ufo/templates/fargate.json.erb
      create  .ufo/templates/main.json.erb
      create  .ufo/variables/base.rb
      create  .ufo/variables/development.rb
      create  .ufo/variables/production.rb
      create  bin/deploy
      append  .gitignore
      create  .dockerignore
Starter ufo files created.

Deploy the project

You’ll deploy to ECS with the ufo ship comand. The output will look like this:

$ ufo current --service demo-web
Current settings saved in .ufo/current
Current service: demo-web
$ ufo ship
Building docker image with:
  docker build -t tongueroo/demo-java:ufo-2018-07-12T16-21-04-4357743 -f Dockerfile .
...
Successfully built 06d8c8d471f0
=> docker push tongueroo/demo-java:ufo-2018-07-12T16-21-04-4357743
...
Pushed tongueroo/demo-java:ufo-2018-07-12T16-21-04-4357743 docker image.
Docker push took 3s.
Building Task Definitions...
...
demo-web task definition registered.
Deploying demo-web...
Ensuring log group for demo-web task definition exists
Log group name: ecs/demo-web
Creating stack development-demo-web...
Generated template saved at: /tmp/ufo/development-demo-web/stack.yml
Generated parameters saved at: /tmp/ufo/development-demo-web/parameters.yml
04:21:19PM CREATE_IN_PROGRESS AWS::CloudFormation::Stack development-demo-web User Initiated
...
04:24:42PM CREATE_COMPLETE AWS::CloudFormation::Stack development-demo-web
Stack success status: CREATE_COMPLETE
Time took for stack deployment: 3m 23s.
Software shipped!
$

Checking out the generated ECS Task definition

While the app is deploying, it’s a good time to check out the generated .ufo/output/demo-web.json ECS task definition. This file was generated by combining:

  • .ufo/templates/main.json.erb
  • .ufo/task_definitions.rb
  • .ufo/variables files

Ufo provides a DSL that allows you to tailor the ECS task definition to fit your needs. More info about how to customize the task definition can be found on the ECS task definition tutorial docs.

Verifying App

After a few minutes, the ECS service should be deployed. There are a few ways to verify that the app deployed successfully. You can check the ECS console and you should see an ECS service running:

You can also check that the app is up with the ufo ps command. You’ll see something like this:

$ ufo ps
=> Service: demo-web
   Service name: development-demo-web-Ecs-1KPSRK9H6IQAI
   Status: ACTIVE
   Running count: 1
   Desired count: 1
   Launch type: FARGATE
   Task definition: demo-web:188
   Elb: develop-Elb-1FANEL62PGSUS-1886579630.us-east-1.elb.amazonaws.com
   Elb type: application
+----------+------+--------------+---------------+---------+-------+
|    Id    | Name |   Release    |    Started    | Status  | Notes |
+----------+------+--------------+---------------+---------+-------+
| 2680be76 | web  | demo-web:188 | 3 minutes ago | RUNNING |       |
+----------+------+--------------+---------------+---------+-------+
$

Scale App

You can scale the app with the ufo scale command and check for running containers after a few minutes.

$ ufo scale 3
Scale demo-web service in development cluster to 3
$ ufo ps
=> Service: demo-web
   Service name: development-demo-web-Ecs-1KPSRK9H6IQAI
   Status: ACTIVE
   Running count: 3
   Desired count: 3
   Launch type: FARGATE
   Task definition: demo-web:188
   Elb: develop-Elb-1FANEL62PGSUS-1886579630.us-east-1.elb.amazonaws.com
   Elb type: application
+----------+------+--------------+---------------+---------+-------+
|    Id    | Name |   Release    |    Started    | Status  | Notes |
+----------+------+--------------+---------------+---------+-------+
| 2680be76 | web  | demo-web:188 | 5 minutes ago | RUNNING |       |
| 73d602ff | web  | demo-web:188 | 7 seconds ago | RUNNING |       |
| c4c951c8 | web  | demo-web:188 | 7 seconds ago | RUNNING |       |
+----------+------+--------------+---------------+---------+-------+
$

Destroy App

Now all that’s left is to clean up after ourselves and remove the ECS service.

$ ufo destroy
You are about to destroy demo-web service on the development cluster.
Are you sure you want to do this? (y/n) y
Deleting CloudFormation stack with ECS resources: development-demo-web.
11:07:10AM DELETE_IN_PROGRESS AWS::CloudFormation::Stack development-demo-web User Initiated
...
11:07:45AM DELETE_COMPLETE AWS::ElasticLoadBalancingV2::LoadBalancer Elb
11:07:46AM DELETE_IN_PROGRESS AWS::EC2::SecurityGroup ElbSecurityGroup
Stack development-demo-web deleted.
$

Summary

In this guide, we cloned a small demo sinatra app and used it to build a Docker image and deploy to ECS. Hope you found this guide helpful. 🎉