Package: ecs-deploy
ECS Deployecs-deploysimplifies deployments on Amazon ECS by providing a convenience CLI tool for complex actions, which are executed pretty often.Key Featuressupport for complex task definitions (e.g. multiple containers & task role)easily redeploy the current task definition (includingdocker pullof eventually updated images)deploy new versions/tags or all containers or just a single container in your task definitionscale up or down by adjusting the desired count of running tasksadd or adjust containers environment variablesrun one-off tasks from the CLIautomatically monitor deployments in New RelicTL;DRDeploy a new version of your service:$ ecs deploy my-cluster my-service --tag 1.2.3Redeploy the current version of a service:$ ecs deploy my-cluster my-serviceScale up or down a service:$ ecs scale my-cluster my-service 4Updating a cron job:$ ecs cron my-cluster my-task my-ruleUpdate a task definition (without running or deploying):$ ecs update my-taskInstallationThe project is available on PyPI. Simply run:$ pip install ecs-deployRun via DockerInstead of installingecs-deploylocally, which requires a Python environment, you can runecs-deployvia Docker. All versions starting from 1.7.1 are available on Docker Hub:https://cloud.docker.com/repository/docker/fabfuel/ecs-deployRunningecs-deployvia Docker is easy as:docker run fabfuel/ecs-deploy:1.10.2In this example, the stable version 1.10.2 is executed. Alternatively you can use Docker tagsmasterorlatestfor the latest stable version or Docker tagdevelopfor the newest development version ofecs-deploy.Please be aware, that when runningecs-deployvia Docker, the configuration - as described below - does not apply. You have to provide credentials and the AWS region via the command as attributes or environment variables:docker run fabfuel/ecs-deploy:1.10.2 ecs deploy my-cluster my-service --region eu-central-1 --access-key-id ABC --secret-access-key ABCConfigurationAsecs-deployis based on boto3 (the official AWS Python library), there are several ways to configure and store the
authentication credentials. Please read the boto3 documentation for more details
(http://boto3.readthedocs.org/en/latest/guide/configuration.html#configuration). The simplest way is by running:$ aws configureAlternatively you can pass the AWS credentials (via–access-key-idand–secret-access-key) or the AWS
configuration profile (via–profile) as options when you runecs.AWS IAMIf you are usingecs-deploywith a role or user account that does not have full AWS access, such as in a deploy script, you will
need to use or create an IAM policy with the correct set of permissions in order for your deploys to succeed. One option is to use the
pre-specifiedAmazonECS_FullAccess(https://docs.aws.amazon.com/AmazonECS/latest/userguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonECS_FullAccess) policy. If you would prefer to create a role with a more minimal set of permissions,
the following are required:ecs:ListServicesecs:UpdateServiceecs:ListTasksecs:RegisterTaskDefinitionecs:DescribeServicesecs:DescribeTasksecs:ListTaskDefinitionsecs:DescribeTaskDefinitionecs:DeregisterTaskDefinitionIf using custom IAM permissions, you will also need to set theiam:PassRolepolicy for each IAM role. See herehttps://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.htmlfor more information.Note that not every permission is required for every action you can take inecs-deploy. You may be able to adjust permissions based on your specific needs.ActionsCurrently the following actions are supported:deployRedeploy a service either without any modifications or with a new image, environment variable, docker label, and/or command definition.scaleScale a service up or down and change the number of running tasks.runRun a one-off task based on an existing task-definition and optionally override command, environment variables and/or docker labels.updateUpdate a task definition by creating a new revision to set a new image,
environment variable, docker label, and/or command definition, etc.cron (scheduled task)Update a task definition and update a events rule (scheduled task) to use the
new task definition.UsageFor detailed information about the available actions, arguments and options, run:$ ecs deploy --help
$ ecs scale --help
$ ecs run --helpExamplesAll examples assume, that authentication has already been configured.DeploymentSimple RedeployTo redeploy a service without any modifications, but pulling the most recent image versions, run the following command.
This will duplicate the current task definition and cause the service to redeploy all running tasks.:$ ecs deploy my-cluster my-serviceDeploy a new tagTo change the tag forallimages inallcontainers in the task definition, run the following command:$ ecs deploy my-cluster my-service -t 1.2.3Deploy a new imageTo change the image of a specific container, run the following command:$ ecs deploy my-cluster my-service --image webserver nginx:1.11.8This will modify thewebservercontainer only and change its image to “nginx:1.11.8”.Deploy several new imagesThe-ior–imageoption can also be passed several times:$ ecs deploy my-cluster my-service -i webserver nginx:1.9 -i application my-app:1.2.3This will change thewebserver’s container image to “nginx:1.9” and theapplication’s image to “my-app:1.2.3”.Deploy a custom task definitionTo deploy any task definition (independent of which is currently used in the service), you can use the--taskparameter. The value can be:A fully qualified task ARN:$ ecs deploy my-cluster my-service --task arn:aws:ecs:eu-central-1:123456789012:task-definition/my-task:20A task family name with revision:$ ecs deploy my-cluster my-service --task my-task:20Or just a task family name. It this case, the most recent revision is used:$ ecs deploy my-cluster my-service --task my-taskImportantecswill still create a new task definition, which then is used in the service.
This is done, to retain consistent behaviour and to ensure the ECS agent e.g. pulls all images.
But the newly created task definition will be based on the given task, not the currently used task.Set an environment variableTo add a new or adjust an existing environment variable of a specific container, run the following command:$ ecs deploy my-cluster my-service -e webserver SOME_VARIABLE SOME_VALUEThis will modify thewebservercontainer definition and add or overwrite the environment variableSOME_VARIABLEwith the value “SOME_VALUE”. This way you can add new or adjust already existing environment variables.Adjust multiple environment variablesYou can add or change multiple environment variables at once, by adding the-e(or–env) options several times:$ ecs deploy my-cluster my-service -e webserver SOME_VARIABLE SOME_VALUE -e webserver OTHER_VARIABLE OTHER_VALUE -e app APP_VARIABLE APP_VALUEThis will modify the definitionof two containers.
Thewebserver’s environment variableSOME_VARIABLEwill be set to “SOME_VALUE” and the variableOTHER_VARIABLEto “OTHER_VALUE”.
Theapp’s environment variableAPP_VARIABLEwill be set to “APP_VALUE”.Set environment variables exclusively, remove all other pre-existing environment variablesTo reset all existing environment variables of a task definition, use the flag--exclusive-env$ ecs deploy my-cluster my-service -e webserver SOME_VARIABLE SOME_VALUE --exclusive-envThis will removeall otherexisting environment variables ofall containersof the task definition, except for the variableSOME_VARIABLEwith the value “SOME_VALUE” in the webserver container.Set a secret environment variable from the AWS Parameter StoreImportantThis option was introduced by AWS in ECS Agent v1.22.0. Make sure your ECS agent version is >= 1.22.0 or else your task will not deploy.To add a new or adjust an existing secret of a specific container, run the following command:$ ecs deploy my-cluster my-service -s webserver SOME_SECRET KEY_OF_SECRET_IN_PARAMETER_STOREYou can also specify the full arn of the parameter:$ ecs deploy my-cluster my-service -s webserver SOME_SECRET arn:aws:ssm:<aws region>:<aws account id>:parameter/KEY_OF_SECRET_IN_PARAMETER_STOREThis will modify thewebservercontainer definition and add or overwrite the environment variableSOME_SECRETwith the value of theKEY_OF_SECRET_IN_PARAMETER_STOREin the AWS Parameter Store of the AWS Systems Manager.Set secrets exclusively, remove all other pre-existing secret environment variablesTo reset all existing secrets (secret environment variables) of a task definition, use the flag--exclusive-secrets$ ecs deploy my-cluster my-service -s webserver NEW_SECRET KEY_OF_SECRET_IN_PARAMETER_STORE --exclusive-secretThis will removeall otherexisting secret environment variables ofall containersof the task definition, except for the new secret variableNEW_SECRETwith the value coming from the AWS Parameter Store with the name “KEY_OF_SECRET_IN_PARAMETER_STORE” in the webserver container.Set environment via .env filesInstead of setting environment variables separately, you can pass a .env file per container to set the whole environment at once. You can either point to a local file or a file stored on S3, via:$ ecs deploy my-cluster my-service --env-file my-app env/my-app.env

$ ecs deploy my-cluster my-service --s3-env-file my-app arn:aws:s3:::my-ecs-environment/my-app.envSet secrets via .env filesInstead of setting secrets separately, you can pass a .env file per container to set all secrets at once.This will expect an env file format, but any values will be set as thevalueFromparameter in the secrets config.
This value can be either the path or the full ARN of a secret in the AWS Parameter Store. For example, with a secrets.env
file like the following:`SOME_SECRET=arn:aws:ssm:<awsregion>:<awsaccountid>:parameter/KEY_OF_SECRET_IN_PARAMETER_STORE`$ ecs deploy my-cluster my-service –secret-env-file webserver env/secrets.envThis will modify thewebservercontainer definition and add or overwrite the environment variableSOME_SECRETwith the value of theKEY_OF_SECRET_IN_PARAMETER_STOREin the AWS Parameter Store of the AWS Systems Manager.Set a docker labelTo add a new or adjust an existing docker labels of a specific container, run the following command:$ ecs deploy my-cluster my-service -d webserver somelabel somevalueThis will modify thewebservercontainer definition and add or overwrite the docker label “somelabel” with the value “somevalue”. This way you can add new or adjust already existing docker labels.Adjust multiple docker labelsYou can add or change multiple docker labels at once, by adding the-d(or–docker-label) options several times:$ ecs deploy my-cluster my-service -d webserver somelabel somevalue -d webserver otherlabel othervalue -d app applabel appvalueThis will modify the definitionof two containers.
Thewebserver’s docker label “somelabel” will be set to “somevalue” and the label “otherlabel” to “othervalue”.
Theapp’s docker label “applabel” will be set to “appvalue”.Set docker labels exclusively, remove all other pre-existing docker labelsTo reset all existing docker labels of a task definition, use the flag--exclusive-docker-labels$ ecs deploy my-cluster my-service -d webserver somelabel somevalue --exclusive-docker-labelsThis will removeall otherexisting docker labels ofall containersof the task definition, except for the label “somelabel” with the value “somevalue” in the webserver container.Modify a commandTo change the command of a specific container, run the following command:$ ecs deploy my-cluster my-service --command webserver "nginx"This will modify thewebservercontainer and change its command to “nginx”. If you have
a command that requires arguments as well, then you can simply specify it like this as you would normally do:$ ecs deploy my-cluster my-service –command webserver “ngnix -c /etc/ngnix/ngnix.conf”This works fine as long as any of the arguments do not contain any spaces. In case arguments to the
command itself contain spaces, then you can use the JSON format:$ ecs deploy my-cluster my-service –command webserver ‘[“sh”, “-c”, “while true; do echo Time files like an arrow $(date); sleep 1; done;”]’More about this can be looked up in documentation.https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitionsSet a task roleTo change or set the role, the service’s task should run as, use the following command:$ ecs deploy my-cluster my-service -r arn:aws:iam::123456789012:role/MySpecialEcsTaskRoleThis will set the task role to “MySpecialEcsTaskRole”.Set CPU and memory reservationSet thecpuvalue for a task:--task-cpu 0.Set thecpuvalue for a task container:--cpu <container_name> 0.Set thememoryvalue (hard limit) for a task:--task-memory 256.Set thememoryvalue (hard limit) for a task container:--memory <container_name> 256.Set thememoryreservationvalue (soft limit) for a task definition:--memoryreservation <container_name> 256.Set privileged or essential flagsSet theprivilegedvalue for a task definition:--privileged <container_name> True|False.Set theessentialvalue for a task definition:--essential <container_name> True|False.Set logging configurationSet thelogConfigurationvalues for a task definition:--log <container_name> awslogs awslogs-group <log_group_name>
--log <container_name> awslogs awslogs-region <region>
--log <container_name> awslogs awslogs-stream-prefix <stream_prefix>Set port mappingSet theport mappingsvalues for a task definition:--port <container_name> <container_port> <host_port>.Supports--exclusive-ports.Theprotocolis fixed totcp.Set volumes & mount pointsSet thevolumesvalues for a task definition--volume <volume_name> /host/path.<volume_name>can then be used with--mount.Set themount pointsvalues for a task definition:--mount <container_name> <volume_name> /container/path.Supports--exclusive-mounts.<volume_name>is the one set by--volume.Set theulimitsvalues for a task definition:--ulimit <container_name> memlock 67108864 67108864.Supports--exclusive-ulimits.Set thesystemControlsvalues for a task definition:--system-control <container_name> net.core.somaxconn 511.Supports--exclusive-system-controls.Set thehealthCheckvalues for a task definition:--health-check <container_name> <command> <interval> <timeout> <retries> <start_period>.Set Health ChecksExample--health-check webserver "curl -f http://localhost/alive/" 30 5 3 0Placeholder ContainerAdd placeholder containers:--add-container <container_name>.To comply with the minimum requirements for a task definition, a placeholder container is set like this:The container name is<container_name>.The container image isPLACEHOLDER.The container soft limit is128.The idea is to set sensible values with the deployment.It is possible to add and define a new container with the same deployment:--add-container redis --image redis redis:6 --port redis 6379 6379Remove containersContainers can be removed:--remove-container <container_name>.Leaves the original containers, if all containers would be removed.All but the container flags can be used withecs deployandecs cron.
The container flags are used withecs deployonly.Ignore capacity issuesIf your cluster is undersized or the service’s deployment options are not optimally set, the cluster
might be incapable to run blue-green-deployments. In this case, you might see errors like these:ERROR: (service my-service) was unable to place a task because no container instance met all of
its requirements. The closest matching (container-instance 123456-1234-1234-1234-1234567890) is
already using a port required by your task. For more information, see the Troubleshooting
section of the Amazon ECS Developer Guide.There might also be warnings about insufficient memory or CPU.To ignore these warnings, you can run the deployment with the flag--ignore-warnings:$ ecs deploy my-cluster my-service --ignore-warningsIn that case, the warning is printed, but the script continues and waits for a successful
deployment until it times out.Deployment timeoutThe deploy and scale actions allow defining a timeout (in seconds) via the--timeoutparameter.
This instructs ecs-deploy to wait for ECS to finish the deployment for the given number of seconds.To run a deployment without waiting for the successful or failed result at all, set--timeoutto the value of-1.Multi-Account SetupIf you manage different environments of your system in multiple differnt AWS accounts, you can now easily assume a
deployment role in the target account in which your ECS cluster is running. You only need to provide--accountwith the AWS account id and--assume-rolewith the name of the role you want to assume in the target account.
ecs-deploy automatically assumes this role and deploys inside your target account:Example:$ ecs deploy my-cluster my-service --account 1234567890 --assume-role ecsDeployRoleScalingScale a serviceTo change the number of running tasks and scale a service up and down, run this command:$ ecs scale my-cluster my-service 4Running a TaskRun a one-off taskTo run a one-off task, based on an existing task-definition, run this command:$ ecs run my-cluster my-taskYou can define just the task family (e.g.my-task) or you can run a specific revision of the task-definition (e.g.my-task:123). And optionally you can add or adjust environment variables like this:$ ecs run my-cluster my-task:123 -e my-container MY_VARIABLE "my value"Run a task with a custom commandYou can override the command definition via option-cor--commandfollowed by the container name and the
command in a natural syntax, e.g. no conversion to comma-separation required:$ ecs run my-cluster my-task -c my-container "python some-script.py param1 param2"The JSON syntax explained above regarding modifying a command is also applicable here.Run a task in a Fargate ClusterIf you want to run a one-off task in a Fargate cluster, additional configuration is required, to instruct AWS e.g. which
subnets or security groups to use. The required parameters for this are:launchtypesecuritygroupsubnetpublic-ipExample:$ ecs run my-fargate-cluster my-task --launchtype=FARGATE --securitygroup sg-01234567890123456 --subnet subnet-01234567890123456 --public-ipYou can pass multiplesubnetas well as multiplesecuritygroupvalues. thepublic-ipflag determines, if the task receives a public IP address or not.
Please seeecs run--helpfor more details.MonitoringWith ECS deploy you can track your deployments automatically. Currently only New Relic is supported:New RelicTo record a deployment in New Relic, you can provide the the API Key (Attention: this is a specific REST API Key, not the license key) and the application id in two ways:Via cli options:$ ecs deploy my-cluster my-service --newrelic-apikey ABCDEFGHIJKLMN --newrelic-appid 1234567890Or implicitly via environment variablesNEW_RELIC_API_KEYandNEW_RELIC_APP_ID$ export NEW_RELIC_API_KEY=ABCDEFGHIJKLMN
$ export NEW_RELIC_APP_ID=1234567890
$ ecs deploy my-cluster my-serviceOptionally you can provide additional information for the deployment:--comment"New feature X"- comment to the deployment--userjohn.doe- the name of the user who deployed with--newrelic-revision1.0.0- explicitly set the revision to use for the deploymentNote: If neither--tagnor--newrelic-revisionare provided, the deployment will not be recorded.TroubleshootingIf the service configuration in ECS is not optimally set, you might be seeing
timeout or other errors during the deployment.TimeoutThe timeout error means, that AWS ECS takes longer for the full deployment cycle then ecs-deploy is told to wait. The deployment itself still might finish successfully, if there are no other problems with the deployed containers.You can increase the time (in seconds) to wait for finishing the deployment via the--timeoutparameter. This time includes the full cycle of stopping all old containers and (re)starting all new containers. Different stacks require different timeout values, the default is 300 seconds.The overall deployment time depends on different things:the type of the application. For example node.js containers tend to take a long time to get stopped. But nginx containers tend to stop immediately, etc.are old and new containers able to run in parallel (e.g. using dynamic ports)?the deployment options and strategy (Maximum percent > 100)?the desired count of running tasks, compared tothe number of ECS instances in the clusterAlternative ImplementationThere are some other libraries/tools available on GitHub, which also handle the deployment of containers in AWS ECS. If you prefer another language over Python, have a look at these projects:Shellecs-deploy -https://github.com/silinternational/ecs-deployRubybroadside -https://github.com/lumoslabs/broadside