Amazon ECS

Deploy Codefresh to Amazon ECS Service

Prerequisites

  1. Configure an ECS Cluster with at least one running instance.
  1. Configure an ECS Service and Task Definition with a reference to the image that you are going to build and push. See the official amazon docs for more details.
  1. Verify you have AWS Credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), with following privileges:

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1479146904000",
      "Effect": "Allow",
      "Action": [
        "ecs:DescribeServices",
        "ecs:DescribeTaskDefinition",
        "ecs:DescribeTasks",
        "ecs:ListClusters",
        "ecs:ListServices",
        "ecs:ListTasks",
        "ecs:RegisterTaskDefinition",
        "ecs:UpdateService"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

Deployment with Codefresh.yml

The codefresh.yml file runs the codefresh/cf-deploy-ecs image with the cfecs-update command.

  1. Add encrypted environment variables for AWS credentials (see the pipeline “General “ tab)
   - AWS_ACCESS_KEY_ID
   - AWS_SECRET_ACCESS_KEY 
  1. Configure Codefresh to access Amazon docker registry on the Integration page. The Task Definition you are deploying to must be able to access the registry as well.
  1. Describe your push step so that the image is pushed into the configured registry.
  1. Add a free-style step that uses our “cf-deploy-ecs” image.
  1. Specify the command “cfecs-update” to be executed with following parameters:
   1) `--image-name`
   2) `--image-tag`
   3) `aws region`
   4) `ecs cluster`
   5) `ecs-service-names`. 

Note that the --image-name and --image-tag pair should comprise the full name of the image that was pushed to the registry (including the registry name) in order to be correctly referred by the corresponding Task Definition.

YAML

# codefresh.yml example with deploy to ecs step
version: '1.0'

steps:
  build-step:
    type: build
    image-name: repo/image:tag  # this is the name of the image that will be stored locally in the Codefresh registry

  # in this step below you are pushing the image to Amazon so it can be used by your Task Definition
 
 push to registry: 
    type: push
    candidate: ${{build-step}}
    tag: ${{CF_BRANCH}}
    registry: MyAmazonDCR   #name of the registry configured on the Integration page

 deploy to ecs:
    image: codefresh/cf-deploy-ecs    # the name of the Codefresh docker image (not your image)
    commands:
      - cfecs-update --image-name <image-fullname-without-tag> --image-tag '${{CF_BRANCH}}' <aws-region> <ecs-cluster-name> <ecs-service-name>
  *     environment:
      - AWS_ACCESS_KEY_ID=${{AWS_ACCESS_KEY_ID}}
      - AWS_SECRET_ACCESS_KEY=${{AWS_SECRET_ACCESS_KEY}}

    when:
      branch:
        only:
          - master

Deploy from a Pipeline’s UI deploy step

  1. Select Codefresh’s Deploy Images in the pipeline’s and select codefresh/cf-deploy-ecs:latest.
  1. As a deploy command use cfecs-update <aws-region> <ecs-cluster-name> <ecs-service-name> and replace <aws-region>, ≤ecs-cluster>, and ≤service-names≥ with the right region, cluster name and service name from your ECS account. For more information on how to use the Codefresh’s ECS update check the image’s page on GitHub.
  1. Add encrypted environment variables for AWS credentials.
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY

Notice: The UI deploy step will run on any build. Make sure that your automated builds run only on a specific branch trigger.

Image.png

Set the deploy image and script

image2.png

Set the environment variable

Deployment Flow

  1. Get the ECS service by specified aws-region, ecs-cluster, and service-names.
  1. Create a new revision from the current task definition of the service. If --image-name and --image-tag are provided, replace the image tag.
  1. Run the update-service command with the new task definition revision.
  1. Wait for the deployment to complete. By default, service deployment is no run with the --no-wait command.
    • Deployment is successfully completed if runningCount == desiredCount for PRIMARY deployment - see aws ecs describe-service
    • The cfecs-update command exits with a timeout error if after –timeout (default = 900s) runningCount does not equal desiredCount
    • The cfecs-update exits with an error if –max-failed (default = 2) or more ECS tasks were stopped with error for the task definition that you are deploying. ECS continuously retries failed tasks.

Usage with Docker

docker run --rm -it -e AWS_ACCESS_KEY_ID=**** -e AWS_SECRET_ACCESS_KEY=**** codefresh/cf-ecs-deploy cfecs-update [options] <aws-region> <ecs-cluster-name> <ecs-service-name>

cfecs-update -h

usage: cfecs-update [-h] [-i IMAGE_NAME] [-t IMAGE_TAG] [--wait | --no-wait]
                    [--timeout TIMEOUT] [--max-failed MAX_FAILED] [--debug]
                    region_name cluster_name service_name

Codefresh ECS Deploy

positional arguments:
  region_name           AWS Region, ex. us-east-1
  cluster_name          ECS Cluster Name
  service_name          ECS Service Name

optional arguments:
  -h, --help            show this help message and exit
  --wait                Wait for deployment to complete (default)
  --no-wait             No Wait for deployment to complete
  --timeout TIMEOUT     deployment wait timeout (default 900s)
  --max-failed MAX_FAILED
                        max failed tasks to consider deployment as failed
                        (default 2)
  --debug               show debug messages

  -i IMAGE_NAME, --image-name IMAGE_NAME
                        Image Name in ECS Task Definition to set new tag
  -t IMAGE_TAG, --image-tag IMAGE_TAG
                        Tag for the image