Reputation: 5671
I run the following shell command to drain my ECS instance before rebooting it:
INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
aws ecs update-container-instances-state \
--region eu-central-1 \
--cluster mycluster \
--status DRAINING \
--container-instances $INSTANCE_ID
It gives me the following error:
An error occurred (InvalidParameterException) when calling the UpdateContainerInstancesState operation: instanceId shorter than 36.
Apparently this is because it wants the ECS containerInstanceId which is different from the ec2InstanceId. What is the best way to find out the containerInstanceId of the local machine?
The way I figured out so far is
aws ecs list-container-instances
to get all the container instance IDs in the clusteraws ecs describe-container-instances
to get the corresponding EC2 instance IDshttp://169.254.169.254/latest/meta-data/instance-id
) to find out the local EC2 instance IDjq
combined with grep
or some other tool to filter This seems a little complicated. Is there a simpler way?
Upvotes: 5
Views: 10888
Reputation: 127
Here's ruby code I used for this:
require 'aws-sdk-ecs'
region = JSON.parse(`curl --silent http://169.254.169.254/latest/dynamic/instance-identity/document`)['region']
instance_id = `ec2metadata --instance-id`.strip
cluster_name = `cat /etc/ecs/ecs.config | grep '^ECS_CLUSTER=' | cut -d "=" -f2`.strip
container_instance_arn = lambda do
ECS_CLIENT.describe_container_instances({
:cluster => cluster_name,
:container_instances => ECS_CLIENT.list_container_instances({
:cluster => cluster_name,
}).container_instance_arns
}).container_instances.select do |instance|
instance.ec2_instance_id == instance_id
end.first.container_instance_arn
end.call
Upvotes: 0
Reputation: 3266
Another option is to populate a custom attribute on the instance containing the instance Id. For example, in your /etc/ecs/ecs.config, you may have the following:
ECS_INSTANCE_ATTRIBUTES={\"ec2_instance\":\"i-0000000000000000000\"}
This can then be used in conjunction with the --filter parameter of list-container-instances to find the associated container instance.
aws ecs list-container-instances --cluster <MY Cluster> --filter attribute:ec2_instance==i-0000000000000000000
If you are using the cfn-init script and CloudFormation, then this can be automated when you create the EC2 instance.
....
MyLaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Metadata:
AWS::CloudFormation::Init:
config:
commands:
00_configure_ecs_agent:
command: |
#!/bin/bash
echo ECS_INSTANCE_ATTRIBUTES={\"ec2_instance\":\"$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)\"} >> /etc/ecs/ecs.config
...
References:
Upvotes: 5
Reputation: 6195
With jq installed, this is fairly straight forward.
Using the ECS Container Introspection endpoint, you get these values and pass them to the aws ecs update-container-instances-state
command.
It can be useful to do this in user data and add the results into /etc/environment
so they are always readily available.
#!/usr/bin/env bash
set -euo pipefail
CONTAINER_INSTANCE_ARN="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.ContainerInstanceArn')"
CLUSTER="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.Cluster')"
aws ecs update-container-instances-state --cluster "$CLUSTER" \
--container-instances "$CONTAINER_INSTANCE_ARN" --status "DRAINING"
Adding them to /etc/environment
via user data:
cat<<-EOF>>/etc/environment
CONTAINER_INSTANCE_ARN="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.ContainerInstanceArn')"
CLUSTER="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.Cluster')"
EOF
source /etc/environment
Notes:
-e
flag means to set the exit code if the key is not found.-r
flag means to dump output as raw text instead of json.Upvotes: 0
Reputation: 4672
If you're running a script on the instance, you can find the container instance ID from the ECS agent's introspection API.
If you're running a script from within an ECS task, you can use the container metadata file.
Upvotes: 4