Deploy Your Application to ECS via CI/CD with Ecspresso
Tags: ecs, deploy, cicd, githubactions
Published: 2023-05-01 00:58:04

---
title: Deploy Your Application to ECS via CI/CD with Ecspresso
published: true
description: Are you looking for a tool to simplify your application deployment process to Amazon ECS? Look no further than Ecspresso! With its ability to manage your ECS resources as code and its seamless integration into CI/CD pipelines, Ecspresso is an essential tool for teams that frequently deploy applications. In this article, we'll walk you through how to use Ecspresso, step-by-step, and how to integrate it into your CI/CD pipeline.
tags: ecs, deploy, cicd, githubactions
---

Are you interested in deploy your application to ECS via CI/CD?
if so, ecspresso is tool for you!

## What is ecspresso?

ecspresso is a tool that helping to deploy your application to ECS,
And easy to integrate it into your CI/CD easily.

[ecspresso](https://github.com/kayac/ecspresso)

## Motivation

Why you should consider using ecspresso for the deployment of your application to ECS rather than another deployment tool?
Because ecspresso can manage your ECS resource as code. Why is that useful?
Imagine, your team deploy frequently your application and there is a moment to change ECS configuration relates to the application such as memory or CPU, etc.. If you could manage your ECS resources as code, possible to change the configuration in every deployment easily.
Just remain, this tool is for you who manage infra resources using Terraform or a tool such as CloudFormation.

## Usage

```
Usage: ecspresso <command>

Flags:
  -h, --help                      Show context-sensitive help.
      --envfile=ENVFILE,...       environment files
      --debug                     enable debug log
      --ext-str=KEY=VALUE;...     external string values for Jsonnet
      --ext-code=KEY=VALUE;...    external code values for Jsonnet
      --config="ecspresso.yml"    config file
      --assume-role-arn=""        the ARN of the role to assume
      --option=OPTION

Commands:

  - deploy
    - deploy service
  - diff
    - show diff between task definition, service definition with current running service and task definition
  - exec
    - execute command on task
  - init --service=SERVICE
    - create configuration files from existing ECS service
  - register
    - register task definition
  - rollback
    - rollback service
  - run
    - run task
  - wait
    - wait until service stable

```

## How to Integrate ecspresso into CI/CD?

I will explain to you step by step!

NOTE:
You need to set your aws credential `(~/.aws/credentials)`
Assume your ECS is already running on AWS

## Install

```
// brew
brew install kayac/tap/ecspresso

or

// asdf
asdf plugin add ecspresso
asdf install ecspresso 2.0.0
```

## Init to generate yml file

Import your current ECS service setting to yml file.

```
ecspresso init --region ap-northeast-1 --cluster your-cluster-name --service your-service-name --config ecspresso.yml
```

After running the above command, you can see below generated files.

```
- ecspresso.yml
- ecs-service-def.json
- ecs-task-def.json.
```

## Import your tfstate

Possible to write some external resource information such as VPC, security group Id and etc...
However, it will decrease maintainability and readability. ecspresso allows to read tfstate to solve this problem!

You can set your file path to tfstate in ecspresso.yml and then able to read it inside .json file.
prefer set func_prefix.

ecspresso.yml

```
region: ap-northeast-1
cluster: your-cluster-name
service: your-service-name
service_definition: ecs-service-def.json
task_definition: ecs-task-def.json
timeout: "10m0s"
plugins:
  - name: tfstate
    config:
      url: s3://path-to-terraform.tfstate
    func_prefix: sg
  - name: tfstate
    config:
      url: s3://path-to-terraform.tfstate
    func_prefix: network
```

ecs-service-def.json

```
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "assignPublicIp": "DISABLED",
      "securityGroups": [
        "{{ sg_tfstate `aws_security_group.service.id` }}"
      ],
      "subnets": [
        "{{ network_tfstate `aws_subnet.private['private'].id` }}",
      ]
    }
  },
```

## Setup ci/cd

It is simple but one important thing is that most cases, want to set the latest image for ECS task so
need to set the latest image dynamically.

Look at the `export IMAGE_TAG=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG `
I define IMAGE_TAG. It will be key.
In ecs-task-def.json you can use must_env and IMAGE_TAG will dynamically load!

ecs-task-def.json

```
  "image": "{{ must_env `IMAGE_TAG` }}",
```

GitHubActions

```
  deploy:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: checkout
        uses: actions/checkout@v3

      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/role
          aws-region: ap-northeast-1

      - name: login to ecr
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - uses: actions/checkout@v3
      - uses: kayac/ecspresso@v2
        with:
          version: v2.0.0 # or latest
          # version-file: .ecspresso-version

      - name: deploy
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: dev
          IMAGE_TAG: api-${{ github.sha }}
        run: |
            export IMAGE_TAG=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
            ecspresso deploy --config ecspresso/ecspresso.yal
```

## Conclusion

ecspresso is helpful to manage and deploy your application to ECS.
You can manage your ECS resources as code and easy to integrate your deployment flow into CI/CD

Thank you for reading my article, Happy Coding!

### Reference:

[kayac/ecspresso: ecspresso is a deployment tool for Amazon ECS](https://github.com/kayac/ecspresso)