Ensuring idempotency
When you perform a mutating operation, you might see an exception because of timeouts or server issues occurring after the resources are mutated. This can make it difficult to determine whether the mutation occurred, and could lead to multiple retries. However, if the original operation and the subsequent retries actually performed the mutations you might have applied stacking changes or created more resources than you intended to. Idempotency ensures that an operation mutates resources no more than one time. With an idempotent request, if the original request mutated successfully, any subsequent retries complete successfully without performing any further mutation.
Topics
Idempotency in Amazon ECS
The following API actions optionally support idempotency using a client token. The corresponding Amazon CLI commands also support idempotency using a client token. A client token is a unique, case-sensitive string. To make an idempotent API request using one of these actions, specify a client token in the request. You should not reuse the same client token for other API requests. If you retry a request that completed successfully using the same client token and the same parameters, the retry succeeds without performing any further actions.
Idempotent using a client token
-
CreateService
The client token can be up to 36 ASCII characters in the range of 33-126 (inclusive).
-
CreateTaskSet
The client token can be up to 36 ASCII characters in the range of 33-126 (inclusive).
RunTask
The client token can be up to 64 ASCII characters in the range of 33-126 (inclusive).
Types of idempotency
-
cluster – Requests with the same token in the same cluster are idempotent. For example, ClientToken A can only be used as a request parameter one time for
RunTask
requests in Cluster X.RunTask
requests to other clusters are considered a separate request. Therefore, you can use ClientToken A for aRunTask
request for cluster Y.
Idempotency for RunTask
The RunTask
API supports idempotency using a client token. A client token is
a unique string that you specify when you make an API request. If you retry an API
request with the same client token and the same request parameters after it has
completed successfully, the result of the original request is returned. If you retry a
successful request using the same client token, but one or more of the parameters are
different, other than the Region or Availability Zone, the retry fails with a
ConflictException
. If you do not specify your own client token, the
Amazon SDK and Amazon Command Line Interface automatically generate a client token for the request to ensure
that it is idempotent. A client token can be any string that includes up to 64 ASCII
characters in the range of 33-126 (inclusive).
The time to live (TTL) for the RunTask
client token is 24 hours. You
should not reuse the same client token for different requests. The client token maximum
TTL is valid for whichever of the following two values is lower:
-
24 hours
-
The lifetime of the resource plus one hour
The lifetime of a resource is the timestamp at which the task was created to the timestamp at which the last status (
lastStatus
) transitioned toSTOPPED
. When you useRunTask
to launch more than one task, the lifetime of the resource equals the lifetime of the last task that transitioned toSTOPPED
.
RunTask retry rules and responses
When you retry a request because you received a 5xx exception, the retried successful response normally includes all of the information that the original request would have returned. Tasks that have been stopped for under an hour only include the task ARN, last status, and desired status.
The following is an example snippet of the response from a retry when there is one running task, one stopped task, and one task that failed to launch.
{ "failures": [ { "arn": "arn:aws:ecs:us-east-1:123456789012:container/4df26bb4-f057-467b-a079-961675296e64", "reason": "RESOURCE:MEMORY" } ], "tasks": [ { "desiredStatus": "RUNNING", "taskArn": "arn:aws:ecs:us-east-1:123456789012:task/default/fdf2c302-468c-4e55-b884-5331d816e7fb", ... }, { "taskArn": "arn:aws:ecs:us-east-1:123456789012:task/default/fdf2c302-468c-4e55-b884-5331d819999", "lastStatus": "STOPPED", ... } ] }
Failures that are over an hour old only include the number of failed tasks.
Examples
Amazon CLI command examples
To make an Amazon CLI command idempotent, add the --client-token
option.
Example: create-service
The following create-service command uses idempotency as it includes a client token.
aws ecs create-service \ --cluster MyCluster \ --service MyService \ --task-definition MyTaskDefinition:2 \ --desired-count 2 \ --launch-type FARGATE \ --platform-version LATEST \ --network-configuration "awsvpcConfiguration={subnets=["subnet-12344321"],securityGroups=["sg-12344321"],assignPublicIp="ENABLED"}" \ --client-token 550e8400-e29b-41d4-a716-44665544
Example: create-task-set
The following create-task-set command uses idempotency as it includes a client token.
aws ecs create-task-set \ --cluster MyCluster \ --service MyService \ --task-definition MyTaskDefinition:2 \ --network-configuration "awsvpcConfiguration={subnets=["subnet-12344321"],securityGroups=["sg-12344321"]}" \ --client-token 550e8400-e29b-41d4-a716-44665544
Example: run-task
The following run-task command uses idempotency as it includes a client token.
aws ecs run-task \ --cluster MyCluster \ --task-definition MyTaskDefinition:2 \ --client-token 550e8400-e29b-41d4-a716-446655440000
API request examples
To make an API request idempotent, add the clientToken
parameter.
Example: CreateService
The following CreateService API request uses idempotency as it includes a client token.
POST / HTTP/1.1 Host: ecs.us-east-1.amazonaws.com.cn Accept-Encoding: identity Content-Length: 87 X-Amz-Target: AmazonEC2ContainerServiceV20141113.CreateService X-Amz-Date: 20150429T170125Z Content-Type: application/x-amz-json-1.1 Authorization: AUTHPARAMS { "serviceName": "MyService", "taskDefinition": "MyTaskDefinition:2", "desiredCount": 10, "capacityProviderStrategy": [ { "base": "number", "capacityProvider": "FARGATE", "weight": 1 } ], "capacityProviderStrategy": [ { "base": "number", "capacityProvider": "FARGATE_SPOT", "weight": 1 } ], "clientToken": "550e8400-e29b-41d4-a716-44665544" }
Example: CreateTaskSet
The following CreateTaskSet API request uses idempotency as it includes a client token.
POST / HTTP/1.1 Host: ecs.us-east-1.amazonaws.com Accept-Encoding: identity Content-Length: 87 X-Amz-Target: AmazonEC2ContainerServiceV20141113.CreateTaskSet X-Amz-Date: 20150429T170125Z Content-Type: application/x-amz-json-1.1 Authorization: AUTHPARAMS { "serviceName": "MyService", "taskDefinition": "mytask:1", "desiredCount": 1, "capacityProviderStrategy": [ { "base": "number", "capacityProvider": "FARGATE", "weight": 1 } ], "capacityProviderStrategy": [ { "base": "number", "capacityProvider": "FARGATE_SPOT", "weight": 1 } ], "clientToken": "550e8400-e29b-41d4-a716-44665544" }
Example: RunTask
The following RunTask API request uses idempotency as it includes a client token.
POST / HTTP/1.1 Host: ecs.us-east-1.amazonaws.com Accept-Encoding: identity Content-Length: 45 X-Amz-Target: AmazonEC2ContainerServiceV20141113.RunTask X-Amz-Date: 20161121T215740Z User-Agent: aws-cli/1.11.13 Python/2.7.12 Darwin/16.1.0 botocore/1.4.66 Content-Type: application/x-amz-json-1.1 Authorization: AUTHPARAMS { "count": 1, "taskDefinition": "mytask:1", "clientToken": "550e8400-e29b-41d4-a716-446655440000" }
Retry recommendations for idempotent requests
The following table shows some common responses that you might get for idempotent API requests, and provides retry recommendations.
Response | Recommendation | Comments |
---|---|---|
200 (OK) |
Do not retry |
The original request completed successfully. Any subsequent retries return successfully. |
400-series response codes (client errors) |
Do not retry |
There is a problem with the request, from among the following:
If the request involves a resource that is in the process of changing states, retrying the request could possibly succeed. |
500-series response codes (server errors) |
Retry |
The error is caused by an Amazon server-side issue and is generally transient. Repeat the request with an appropriate back-off strategy. |