Skip to content

Commit 76f9cf0

Browse files
authored
Merge pull request #165 from fabfuel/normoes-container-descriptions
Container descriptions cleanup
2 parents 58809fd + d913fbe commit 76f9cf0

File tree

6 files changed

+892
-15
lines changed

6 files changed

+892
-15
lines changed

README.rst

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,82 @@ To change or set the role, the service's task should run as, use the following c
260260

261261
This will set the task role to "MySpecialEcsTaskRole".
262262

263+
264+
Set CPU and memory reservation
265+
==============================
266+
- Set the `cpu` value for a task definition: :code:`--cpu <container_name> 0`.
267+
- Set the `memory` value (`hard limit`) for a task definition: :code:`--memory <container_name> 256`.
268+
- Set the `memoryreservation` value (`soft limit`) for a task definition: :code:`--memoryreservation <container_name> 256`.
269+
270+
Set privileged or essential flags
271+
=================================
272+
- Set the `privliged` value for a task definition: :code:`--privileged <container_name> True|False`.
273+
- Set the `essential` value for a task definition: :code:`--essential <container_name> True|False`.
274+
275+
Set logging configuration
276+
=========================
277+
Set the `logConfiguration` values for a task definition::
278+
279+
--log <container_name> awslogs awslogs-group <log_group_name>
280+
--log <container_name> awslogs awslogs-region <region>
281+
--log <container_name> awslogs awslogs-stream-prefix <stream_prefix>
282+
283+
284+
Set port mapping
285+
================
286+
- Set the `port mappings` values for a task definition: :code:`--port <container_name> <container_port> <host_port>`.
287+
288+
- Supports :code:`--exclusive-ports`.
289+
- The `protocol` is fixed to `tcp`.
290+
291+
Set volumes & mount points
292+
==========================
293+
- Set the `volumes` values for a task definition :code:`--volume <volume_name> /host/path`.
294+
295+
- :code:`<volume_name>` can then be used with :code:`--mount`.
296+
- Set the `mount points` values for a task definition: :code:`--mount <container_name> <volume_name> /container/path`.
297+
298+
- Supports :code:`--exclusive-mounts`.
299+
300+
- :code:`<volume_name>` is the one set by :code:`--volume`.
301+
- Set the `ulimits` values for a task definition: :code:`--ulimit <container_name> memlock 67108864 67108864`.
302+
303+
- Supports :code:`--exclusive-ulimits`.
304+
- Set the `systemControls` values for a task definition: :code:`--system-control <container_name> net.core.somaxconn 511`.
305+
306+
- Supports :code:`--exclusive-system-controls`.
307+
- Set the `healthCheck` values for a task definition: :code:`--health-check <container_name> <command> <interval> <timeout> <retries> <start_period>`.
308+
309+
310+
Set Health Checks
311+
=================
312+
- Example :code:`--health-check webserver "curl -f http://localhost/alive/" 30 5 3 0`
313+
314+
315+
Placeholder Container
316+
=====================
317+
- Add placeholder containers: :code:`--add-container <container_name>`.
318+
- To comply with the minimum requirements for a task definition, a placeholder container is set like this:
319+
+ The contaienr name is :code:`<container_name>`.
320+
+ The container image is :code:`PLACEHOLDER`.
321+
+ The container soft limit is :code:`128`.
322+
- The idea is to set sensible values with the deployment.
323+
324+
It is possible to add and define a new container with the same deployment::
325+
326+
--add-container redis --image redis redis:6 --port redis 6379 6379
327+
328+
Remove containers
329+
=================
330+
- Containers can be removed: :code:`--remove-container <container_name>`.
331+
332+
- Leaves the original containers, if all containers would be removed.
333+
334+
335+
All but the container flags can be used with `ecs deploy` and `ecs cron`.
336+
The container flags are used with `ecs deploy` only.
337+
338+
263339
Ignore capacity issues
264340
======================
265341
If your cluster is undersized or the service's deployment options are not optimally set, the cluster

ecs_deploy/cli.py

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,20 @@ def get_client(access_key_id, secret_access_key, region, profile):
3030
@click.option('-t', '--tag', help='Changes the tag for ALL container images')
3131
@click.option('-i', '--image', type=(str, str), multiple=True, help='Overwrites the image for a container: <container> <image>')
3232
@click.option('-c', '--command', type=(str, str), multiple=True, help='Overwrites the command in a container: <container> <command>')
33+
@click.option('-h', '--health-check', type=(str, str, int, int, int, int), multiple=True, help='Overwrites the healthcheck in a container: <container> <command> <interval> <timeout> <retries> <start_period>')
34+
@click.option('--cpu', type=(str, int), multiple=True, help='Overwrites the cpu value for a container: <container> <cpu>')
35+
@click.option('--memory', type=(str, int), multiple=True, help='Overwrites the memory value for a container: <container> <memory>')
36+
@click.option('--memoryreservation', type=(str, int), multiple=True, help='Overwrites the memory reservation value for a container: <container> <memoryreservation>')
37+
@click.option('--privileged', type=(str, bool), multiple=True, help='Overwrites the privileged value for a container: <container> <privileged>')
38+
@click.option('--essential', type=(str, bool), multiple=True, help='Overwrites the essential value for a container: <container> <essential>')
3339
@click.option('-e', '--env', type=(str, str, str), multiple=True, help='Adds or changes an environment variable: <container> <name> <value>')
3440
@click.option('--env-file', type=(str, str), default=((None, None),), multiple=True, required=False, help='Load environment variables from .env-file')
3541
@click.option('-s', '--secret', type=(str, str, str), multiple=True, help='Adds or changes a secret environment variable from the AWS Parameter Store (Not available for Fargate): <container> <name> <parameter name>')
42+
@click.option('-u', '--ulimit', type=(str, str, int, int), multiple=True, help='Adds or changes a ulimit variable in the container description (Not available for Fargate): <container> <ulimit name> <softlimit value> <hardlimit value>')
43+
@click.option('--system-control', type=(str, str, str), multiple=True, help='Adds or changes a system control variable in the container description (Not available for Fargate): <container> <namespace> <value>')
44+
@click.option('-p', '--port', type=(str, int, int), multiple=True, help='Adds or changes a port mappings in the container description (Not available for Fargate): <container> <container port value> <host port value>')
45+
@click.option('-m', '--mount', type=(str, str, str), multiple=True, help='Adds or changes a mount points in the container description (Not available for Fargate): <container> <container port value> <host port value>')
46+
@click.option('-l', '--log', type=(str, str, str, str), multiple=True, help='Adds or changes a log configuration in the container description (Not available for Fargate): <container> <log driver> <option name> <option value>')
3647
@click.option('-r', '--role', type=str, help='Sets the task\'s role ARN: <task role ARN>')
3748
@click.option('-x', '--execution-role', type=str, help='Sets the execution\'s role ARN: <execution role ARN>')
3849
@click.option('--task', type=str, help='Task definition to be deployed. Can be a task ARN or a task family with optional revision')
@@ -56,7 +67,14 @@ def get_client(access_key_id, secret_access_key, region, profile):
5667
@click.option('--sleep-time', default=1, type=int, help='Amount of seconds to wait between each check of the service (default: 1)')
5768
@click.option('--slack-url', required=False, help='Webhook URL of the Slack integration. Can also be defined via environment variable SLACK_URL')
5869
@click.option('--slack-service-match', default=".*", required=False, help='A regular expression for defining, which services should be notified. (default: .* =all). Can also be defined via environment variable SLACK_SERVICE_MATCH')
59-
def deploy(cluster, service, tag, image, command, env, env_file, secret, role, execution_role, task, region, access_key_id, secret_access_key, profile, timeout, newrelic_apikey, newrelic_appid, newrelic_region, newrelic_revision, comment, user, ignore_warnings, diff, deregister, rollback, exclusive_env, exclusive_secrets, sleep_time, slack_url, slack_service_match='.*'):
70+
@click.option('--exclusive-ulimits', is_flag=True, default=False, help='Set the given ulimits exclusively and remove all other pre-existing ulimits from all containers')
71+
@click.option('--exclusive-system-controls', is_flag=True, default=False, help='Set the given system controls exclusively and remove all other pre-existing system controls from all containers')
72+
@click.option('--exclusive-ports', is_flag=True, default=False, help='Set the given port mappings exclusively and remove all other pre-existing port mappings from all containers')
73+
@click.option('--exclusive-mounts', is_flag=True, default=False, help='Set the given mount points exclusively and remove all other pre-existing mount points from all containers')
74+
@click.option('--volume', type=(str, str), multiple=True, required=False, help='Set volume mapping from host to container in the task definition.')
75+
@click.option('--add-container', type=str, multiple=True, required=False, help='Add a placeholder container in the task definition.')
76+
@click.option('--remove-container', type=str, multiple=True, required=False, help='Remove a container from the task definition.')
77+
def deploy(cluster, service, tag, image, command, health_check, cpu, memory, memoryreservation, privileged, essential, env, env_file, secret, ulimit, system_control, port, mount, log, role, execution_role, task, region, access_key_id, secret_access_key, profile, timeout, newrelic_apikey, newrelic_appid, newrelic_region, newrelic_revision, comment, user, ignore_warnings, diff, deregister, rollback, exclusive_env, exclusive_secrets, sleep_time, exclusive_ulimits, exclusive_system_controls, exclusive_ports, exclusive_mounts, volume, add_container, remove_container, slack_url, slack_service_match='.*'):
6078
"""
6179
Redeploy or modify a service.
6280
@@ -74,12 +92,27 @@ def deploy(cluster, service, tag, image, command, env, env_file, secret, role, e
7492
deployment = DeployAction(client, cluster, service)
7593

7694
td = get_task_definition(deployment, task)
95+
# If there is a new container, add it at frist.
96+
td.add_containers(add_container)
97+
td.remove_containers(remove_container)
7798
td.set_images(tag, **{key: value for (key, value) in image})
7899
td.set_commands(**{key: value for (key, value) in command})
100+
td.set_health_checks(health_check)
101+
td.set_cpu(**{key: value for (key, value) in cpu})
102+
td.set_memory(**{key: value for (key, value) in memory})
103+
td.set_memoryreservation(**{key: value for (key, value) in memoryreservation})
104+
td.set_privileged(**{key: value for (key, value) in privileged})
105+
td.set_essential(**{key: value for (key, value) in essential})
79106
td.set_environment(env, exclusive_env, env_file)
80107
td.set_secrets(secret, exclusive_secrets)
108+
td.set_ulimits(ulimit, exclusive_ulimits)
109+
td.set_system_controls(system_control, exclusive_system_controls)
110+
td.set_port_mappings(port, exclusive_ports)
111+
td.set_mount_points(mount, exclusive_mounts)
112+
td.set_log_configurations(log)
81113
td.set_role_arn(role)
82114
td.set_execution_role_arn(execution_role)
115+
td.set_volumes(volume)
83116

84117
slack = SlackNotification(
85118
getenv('SLACK_URL', slack_url),
@@ -133,9 +166,20 @@ def deploy(cluster, service, tag, image, command, env, env_file, secret, role, e
133166
@click.option('-i', '--image', type=(str, str), multiple=True, help='Overwrites the image for a container: <container> <image>')
134167
@click.option('-t', '--tag', help='Changes the tag for ALL container images')
135168
@click.option('-c', '--command', type=(str, str), multiple=True, help='Overwrites the command in a container: <container> <command>')
169+
@click.option('--cpu', type=(str, int), multiple=True, help='Overwrites the cpu value for a container: <container> <cpu>')
170+
@click.option('--memory', type=(str, int), multiple=True, help='Overwrites the memory value for a container: <container> <memory>')
171+
@click.option('--memoryreservation', type=(str, int), multiple=True, help='Overwrites the memory reservation value for a container: <container> <memoryreservation>')
172+
@click.option('--privileged', type=(str, bool), multiple=True, help='Overwrites the memory reservation value for a container: <container> <memoryreservation>')
136173
@click.option('-e', '--env', type=(str, str, str), multiple=True, help='Adds or changes an environment variable: <container> <name> <value>')
174+
@click.option('-s', '--secret', type=(str, str, str), multiple=True, help='Adds or changes a secret environment variable from the AWS Parameter Store (Not available for Fargate): <container> <name> <parameter name>')
175+
@click.option('-u', '--ulimit', type=(str, str, int, int), multiple=True, help='Adds or changes a ulimit variable in the container description (Not available for Fargate): <container> <ulimit name> <softlimit value> <hardlimit value>')
176+
@click.option('--system-control', type=(str, str, str), multiple=True, help='Adds or changes a system control variable in the container description (Not available for Fargate): <container> <namespace> <value>')
177+
@click.option('-p', '--port', type=(str, int, int), multiple=True, help='Adds or changes a port mappings in the container description (Not available for Fargate): <container> <container port value> <host port value>')
178+
@click.option('-m', '--mount', type=(str, str, str), multiple=True, help='Adds or changes a mount points in the container description (Not available for Fargate): <container> <container port value> <host port value>')
179+
@click.option('-l', '--log', type=(str, str, str, str), multiple=True, help='Adds or changes a log configuration in the container description (Not available for Fargate): <container> <log driver> <option name> <option value>')
137180
@click.option('--env-file', type=(str, str), default=((None, None),), multiple=True, required=False, help='Load environment variables from .env-file')
138181
@click.option('-r', '--role', type=str, help='Sets the task\'s role ARN: <task role ARN>')
182+
@click.option('-x', '--execution-role', type=str, help='Sets the execution\'s role ARN: <execution role ARN>')
139183
@click.option('--region', help='AWS region (e.g. eu-central-1)')
140184
@click.option('--access-key-id', help='AWS access key id')
141185
@click.option('--secret-access-key', help='AWS secret access key')
@@ -150,9 +194,15 @@ def deploy(cluster, service, tag, image, command, env, env_file, secret, role, e
150194
@click.option('--deregister/--no-deregister', default=True, help='Deregister or keep the old task definition (default: --deregister)')
151195
@click.option('--rollback/--no-rollback', default=False, help='Rollback to previous revision, if deployment failed (default: --no-rollback)')
152196
@click.option('--exclusive-env', is_flag=True, default=False, help='Set the given environment variables exclusively and remove all other pre-existing env variables from all containers')
197+
@click.option('--exclusive-secrets', is_flag=True, default=False, help='Set the given secrets exclusively and remove all other pre-existing secrets from all containers')
153198
@click.option('--slack-url', required=False, help='Webhook URL of the Slack integration. Can also be defined via environment variable SLACK_URL')
154199
@click.option('--slack-service-match', default=".*", required=False, help='A regular expression for defining, deployments of which crons should be notified. (default: .* =all). Can also be defined via environment variable SLACK_SERVICE_MATCH')
155-
def cron(cluster, task, rule, image, tag, command, env, env_file, role, region, access_key_id, secret_access_key, newrelic_apikey, newrelic_appid, newrelic_region, newrelic_revision, comment, user, profile, diff, deregister, rollback, exclusive_env, slack_url, slack_service_match):
200+
@click.option('--exclusive-ulimits', is_flag=True, default=False, help='Set the given ulimits exclusively and remove all other pre-existing ulimits from all containers')
201+
@click.option('--exclusive-system-controls', is_flag=True, default=False, help='Set the given system controls exclusively and remove all other pre-existing system controls from all containers')
202+
@click.option('--exclusive-ports', is_flag=True, default=False, help='Set the given port mappings exclusively and remove all other pre-existing port mappings from all containers')
203+
@click.option('--exclusive-mounts', is_flag=True, default=False, help='Set the given mount points exclusively and remove all other pre-existing mount points from all containers')
204+
@click.option('--volume', type=(str, str), multiple=True, required=False, help='Set volume mapping from host to container in the task definition.')
205+
def cron(cluster, task, rule, image, tag, command, cpu, memory, memoryreservation, privileged, env, env_file, secret, ulimit, system_control, port, mount, log, role, execution_role, region, access_key_id, secret_access_key, newrelic_apikey, newrelic_appid, newrelic_region, newrelic_revision, comment, user, profile, diff, deregister, rollback, exclusive_env, exclusive_secrets, slack_url, slack_service_match, exclusive_ulimits, exclusive_system_controls, exclusive_ports, exclusive_mounts, volume):
156206
"""
157207
Update a scheduled task.
158208
@@ -170,8 +220,20 @@ def cron(cluster, task, rule, image, tag, command, env, env_file, role, region,
170220

171221
td.set_images(tag, **{key: value for (key, value) in image})
172222
td.set_commands(**{key: value for (key, value) in command})
223+
td.set_cpu(**{key: value for (key, value) in cpu})
224+
td.set_memory(**{key: value for (key, value) in memory})
225+
td.set_memoryreservation(**{key: value for (key, value) in memoryreservation})
226+
td.set_privileged(**{key: value for (key, value) in privileged})
173227
td.set_environment(env, exclusive_env, env_file)
228+
td.set_secrets(secret, exclusive_secrets)
229+
td.set_ulimits(ulimit, exclusive_ulimits)
230+
td.set_system_controls(system_control, exclusive_system_controls)
231+
td.set_port_mappings(port, exclusive_ports)
232+
td.set_mount_points(mount, exclusive_mounts)
233+
td.set_log_configurations(log)
174234
td.set_role_arn(role)
235+
td.set_execution_role_arn(execution_role)
236+
td.set_volumes(volume)
175237

176238
slack = SlackNotification(
177239
getenv('SLACK_URL', slack_url),
@@ -555,22 +617,21 @@ def print_diff(task_definition, title='Updating task definition'):
555617
def inspect_errors(service, failure_message, ignore_warnings, since, timeout):
556618
error = False
557619
last_error_timestamp = since
558-
559620
warnings = service.get_warnings(since)
560621
for timestamp in warnings:
561622
message = warnings[timestamp]
562623
click.secho('')
563624
if ignore_warnings:
564625
last_error_timestamp = timestamp
565626
click.secho(
566-
text='%s\nWARNING: %s' % (timestamp, message),
627+
'%s\nWARNING: %s' % (timestamp, message),
567628
fg='yellow',
568629
err=False
569630
)
570631
click.secho('Continuing.', nl=False)
571632
else:
572633
click.secho(
573-
text='%s\nERROR: %s\n' % (timestamp, message),
634+
'%s\nERROR: %s\n' % (timestamp, message),
574635
fg='red',
575636
err=True
576637
)

0 commit comments

Comments
 (0)