ecspresso

repository·v2·Indexed 22 days ago

https://github.com/kayac/ecspresso

A deployment tool for Amazon ECS that enables managing ECS services and task definitions as code using JSON, YAML, or Jsonnet. It supports various deployment strategies, including Blue/Green deployments via the ECS deployment controller or AWS CodeDeploy, and features template syntax for environment variable injection. The tool integrates with Terraform, AWS CodeDeploy, GitHub Actions, and CircleCI.

Tokens
35.2K
Snippets
116
Records
142
Agent score
77%

What's inside ecspresso

  1. New features in ecspresso v2

    v2

    ecspresso v2 introduces several enhancements over v1:

    • CodeDeploy configuration: You can now specify the CodeDeploy application name and deployment group name directly in your configuration file.
    • CodeDeploy UX: A progress bar is shown during CodeDeploy deployments.
    • Verification: The verify command now verifies the container image platform.
    • Terraform state: Supports multiple tfstate files using a prefix.
    • Plugins: Added support for the SSM parameter store plugin.
    • ECS Service Connect: Full support for ECS Service Connect.
  2. Configure multiple tfstate files using func_prefix

    v2

    If you need to pull data from multiple different Terraform state files, use the func_prefix option in the plugin configuration. This adds a unique prefix to the template functions for that specific plugin instance.

    Example Setup

    In ecspresso.yml, assign a func_prefix to each plugin entry.

    Usage

    In your templates, call the functions using the prefix: {{ prefix_tfstate ... }}.

    # ecspresso.yml
    plugins:
       - name: tfstate
         config:
           url: s3://tfstate/first.tfstate
         func_prefix: first_
       - name: tfstate
         config:
           url: s3://tfstate/second.tfstate
         func_prefix: second_
    [
      "{{ first_tfstate `aws_s3_bucket.main.arn` }}",
      "{{ second_tfstate `aws_s3_bucket.main.arn` }}"
    ]
  3. Use ECS Express mode

    v2

    ECS Express mode allows deploying services with a single definition file instead of separate task and service definitions.

    Configuration: Use express_definition in your ecspresso.yml instead of task_definition and service_definition.

    Supported Commands: init --express, deploy, diff, render expressdef, delete, status, rollback (partial), verify, exec, refresh, tasks, wait.

    Unsupported Commands: scale, run, revisions, register, deregister, appspec.

    Migration: Use ecspresso init --no-express to import an existing Express service as a standard (non-express) service.

    # ecspresso.yml
    region: ap-northeast-1
    cluster: ecspresso
    service: myservice
    express_definition: ecs-express-def.json
  4. Use template syntax in definition files

    v2

    ecspresso supports template syntax in JSON, YAML, or Jsonnet files to inject environment variables.

    • {{ env 'VAR' 'default' }}: Replaces with the value of environment variable VAR. If VAR is not set, it uses 'default'.
    • {{ must_env 'VAR' }}: Replaces with the value of environment variable VAR. If VAR is not set, the deployment aborts immediately.

    Example: Updating an image tag In ecs-task-def.json:

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

    Deploy with the variable:

    IMAGE_TAG=stable ecspresso deploy --config ecspresso.yml
    nginx:{{ must_env `IMAGE_TAG` }}
  5. Use Jsonnet for service and task definitions

    v2

    ecspresso supports Jsonnet for service and task definitions (since v1.7) and configuration files (since v2.0). If a file has the .jsonnet extension, ecspresso processes it as Jsonnet, converts it to JSON, and then loads it with evaluation template syntax.

    To pass variables to Jsonnet files, use the --ext-str and --ext-code flags to set Jsonnet External Variables.

    $ ecspresso --ext-str Foo=foo --ext-code "Bar=1+1" ...
    {
      foo: std.extVar('Foo'), // = "foo"
      bar: std.extVar('Bar'), // = 2
    }
  6. Use template functions in ecspresso

    v2

    ecspresso uses the Go text/template standard package to render template files (YAML or JSON). If you are using Jsonnet, ecspresso renders the Jsonnet files first and then parses them as text/template. Because of this, template functions in Jsonnet must be wrapped in string quotes (e.g., "{{ ... }}") to avoid syntax conflicts.

    By default, the following template functions are available:

    • env: Replaces the placeholder with the value of an environment variable. Supports a default value.
    • must_env: Replaces the placeholder with the value of an environment variable. If the variable is not set, ecspresso will panic and stop execution. This is recommended for critical values to prevent unintended deployments.
    • json_escape: Escapes values as JSON strings, useful for embedding values that require escaping (like quotes).
    "{{ env `NAME` `default value` }}"
    "{{ must_env `NAME` }}"
    "{{ must_env `JSON_VALUE` | json_escape }}"
  7. Deploy, rollback, and scale ECS services

    v2

    Manage the lifecycle of your ECS services using the following commands. It is highly recommended to use --dry-run before executing destructive operations.

    Deployment

    • Preview changes: ecspresso deploy --config <config_file> --dry-run
    • Deploy service: ecspresso deploy --config <config_file>
    • Deploy and wait: Wait until the deployment reaches a stable state. ecspresso deploy --config <config_file> --wait-until stable

    Rollback

    • Rollback to previous task definition: ecspresso rollback --config <config_file>
    • Rollback preview: ecspresso rollback --config <config_file> --dry-run

    Scaling

    • Scale tasks: Set a specific number of tasks for the service. ecspresso scale --config <config_file> --tasks <number>
    # Deploy and wait until stable
    ecspresso deploy --config ecspresso.yml --wait-until stable
  8. Configure Amazon EBS Volumes in ECS

    v2

    To use EBS volumes, define volumeConfigurations in the service definition and both mountPoints and volumes in the task definition.

    When using ecspresso run for standalone tasks, use the --no-ebs-delete-on-termination flag to prevent the volume from being deleted when the task stops. Note that for tasks managed by ECS services, EBS volumes are always deleted when the task stops per ECS specification.

    // ecs-service-def.json
      "volumeConfigurations": [
        {
          "managedEBSVolume": {
            "filesystemType": "ext4",
            "roleArn": "arn:aws:iam::123456789012:role/ecsInfrastructureRole",
            "sizeInGiB": 10,
            "tagSpecifications": [
              {
                "propagateTags": "SERVICE",
                "resourceType": "volume"
              }
            ],
            "volumeType": "gp3"
          },
          "name": "ebs"
        }
      ]
    // ecs-task-def.json
          "mountPoints": [
            {
              "containerPath": "/mnt/ebs",
              "sourceVolume": "ebs"
            }
          ],
      "volumes": [
        {
          "name": "ebs",
          "configuredAtLaunch": true
        }
      ]
    $ ecspresso run --no-ebs-delete-on-termination
  9. Render configuration for inspection

    v2

    If you need to see the final, resolved configuration after template variables and functions have been expanded, use the render command.

    • Render task definition: ecspresso render --config <config_file> taskdef
    • Render service definition: ecspresso render --config <config_file> servicedef
    # Render resolved task definition
    ecspresso render --config ecspresso.yml taskdef
  10. Configure VPC Lattice integration

    v2

    To use VPC Lattice, you must manually create and associate a VPC Lattice target group with the ECS service. ecspresso then manages the configuration:

    1. In the Task Definition, define portMappings and ensure the name field is set.
    2. In the Service Definition, define vpcLatticeConfigurations. The portName must match the name from the task definition's portMappings.
    // Task Definition
    {
      "containerDefinitions": [
        {
          "name": "webserver",
          "portMappings": [
            {
              "name": "web-80-tcp",
              "containerPort": 80,
              "hostPort": 80,
              "protocol": "tcp",
              "appProtocol": "http"
            }
          ]
        }
      ]
    }
    
    // Service Definition
    {
      "vpcLatticeConfigurations": [
        {
          "portName": "web-80-tcp",
          "roleArn": "arn:aws:iam::123456789012:role/ecsInfrastructureRole",
          "targetGroupArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-009147df264a0bacb"
        }
      ]
    }
  11. Run and inspect ECS tasks

    v2

    Use these commands to execute one-off tasks or inspect currently running tasks.

    • Run a one-off task: Runs a standalone task using the service's task definition. ecspresso run --config <config_file>
    • Run and watch logs: Run a task and stream logs for a specific container. ecspresso run --config <config_file> --watch-container <container_name>
    • List running tasks: Retrieve a list of running tasks in JSON format. ecspresso tasks --config <config_file> --output json
    # Run and watch logs
    ecspresso run --config ecspresso.yml --watch-container app
  12. Migrate to Fargate Spot

    v2

    To migrate an existing service to use Fargate Spot, first ensure capacityProviders and defaultCapacityProviderStrategy are set for the ECS cluster. Then, define a capacityProviderStrategy in your service definition and apply it using ecspresso deploy --update-service.

    {
      "capacityProviderStrategy": [
        {
          "base": 1,
          "capacityProvider": "FARGATE",
          "weight": 1
        },
        {
          "base": 0,
          "capacityProvider": "FARGATE_SPOT",
          "weight": 1
        }
      ]
    }