This is an introductory guide to ufo, an ECS deployment tool, with AWS Fargate. Ufo helps you deploy Docker images to AWS ECS. With Fargate, you can run docker containers without having to manage servers, for an interesting “serverless” option.

Pros and Cons

A huge pro of ECS Fargate is that you no longer have to maintain the servers. AWS will handling all the OS patching, upgrades, and ECS agent updates. This benefit can make a lot of sense for folks with limited DevOps resources, don’t need access to the container, and don’t want to manage, maintain and patch the server cluster.

The disadvantages of ECS Fargate is less control. You do not have access to the EC2 instance if you need to debug at that level. ECS Fargate is more expensive in terms of infrastructure cost and you cannot take advantage of EC2 Spot Pricing. This ECS Fargate vs EC2 Pricing article highlights the pricing difference.

Summary of Commands

Here’s an example of creating web service with Fargate.

git clone https://github.com/tongueroo/demo-java demo
cd demo
bin/build
ufo init --image tongueroo/demo-java --launch-type fargate --execution-role-arn XXX
ufo current --service demo-web
ufo ship

Replace the --execution-role-arn with the ecsTaskExecutionRole associated with your account. If you do not have an ecsTaskExecutionRole yet, create one by following Amazon ECS Task Execution IAM Role guide.

Create the ECS Cluster

Go to the ECS Console

  1. Click Create Cluster.
  2. Choose Networking Only “Powered by Fargate”
  3. For Cluster name use: development For Create VPC, leave unchecked
  4. Click Create

Clone the project

The first command clones the project into a demo folder and build the java artifact.

git clone https://github.com/tongueroo/demo-java.git demo
cd demo
bin/build

The project is a small demo java app that prints “Hello World”. Details on the project are provided in it’s README.

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-java --launch-type fargate --execution-role-arn XXX
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.

Remember to replace the --execution-role-arn with the ecsTaskExecutionRole associated with your account. If you do not have an ecsTaskExecutionRole yet, create one by following Amazon ECS Task Execution IAM Role guide.

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-11T18-47-31-eb0789a -f Dockerfile .
...
Docker image tongueroo/demo-java:ufo-2018-07-11T18-47-31-eb0789a built.
Docker build took 2s.
=> docker push tongueroo/demo-java:ufo-2018-07-11T18-47-31-eb0789a
...
Pushed tongueroo/demo-java:ufo-2018-07-11T18-47-31-eb0789a docker image.
Docker push took 7s.
Building Task Definitions...
Generating Task Definitions:
  .ufo/output/demo-web.json
  .ufo/output/demo-worker.json
  .ufo/output/demo-clock.json
Task Definitions built in .ufo/output
Equivalent aws cli command:
  aws ecs register-task-definition --cli-input-json file://.ufo/output/demo-web.json
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
06:47:49PM CREATE_IN_PROGRESS AWS::CloudFormation::Stack development-demo-web User Initiated
...
06:52:12PM CREATE_COMPLETE AWS::CloudFormation::Stack development-demo-web
Stack success status: CREATE_COMPLETE
Time took for stack deployment: 4m 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-T5L6BOEZZ1NC
   Status: ACTIVE
   Running count: 1
   Desired count: 1
   Launch type: FARGATE
   Task definition: demo-web:183
   Elb: develop-Elb-1BFT5CZPZK6RH-88180209.us-east-1.elb.amazonaws.com
   Elb type: application
+----------+------+--------------+----------------+---------+-------+
|    Id    | Name |   Release    |    Started     | Status  | Notes |
+----------+------+--------------+----------------+---------+-------+
| 6d687f41 | web  | demo-web:183 | 46 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 --no-summary
+----------+------+--------------+----------------+---------+-------+
|    Id    | Name |   Release    |    Started     | Status  | Notes |
+----------+------+--------------+----------------+---------+-------+
| 427d7344 | web  | demo-web:183 | 29 seconds ago | RUNNING |       |
| 6d687f41 | web  | demo-web:183 | 48 minutes ago | RUNNING |       |
| 89dd6788 | web  | demo-web:183 | 20 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.
04:30:25PM DELETE_IN_PROGRESS AWS::CloudFormation::Stack development-demo-web User Initiated
...
Stack development-demo-web deleted.
Time took for deletion: 3m 20s.
$

Summary

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