Skip to content

Instantly share code, notes, and snippets.

@nvmker
Last active February 18, 2021 16:05
Show Gist options
  • Save nvmker/1f5ec69bfe85ba84ca3f8c792a639636 to your computer and use it in GitHub Desktop.
Save nvmker/1f5ec69bfe85ba84ca3f8c792a639636 to your computer and use it in GitHub Desktop.
AWS ECS Deployment script for updating existing service from creating new revision of existing task definition
#!/bin/bash
helpFunction() {
echo ""
echo "Pass AWS credentials through environment variables"
echo ""
echo "Usage: $0 -r aws-region -c my-cluster -s my-ecs-service -i my-image-id -t my-image-tag"
echo -e "\t-r AWS Region"
echo -e "\t-c AWS ECS Cluster name"
echo -e "\t-s AWS ECS Service name"
echo -e "\t-i Docker image ID"
echo -e "\t-t Docker image tag"
exit 1 # Exit script after printing help
}
while getopts "r:c:s:i:t:" opt; do
case "$opt" in
r) AWS_REGION="$OPTARG" ;;
c) CLUSTER="$OPTARG" ;;
s) SERVICE="$OPTARG" ;;
i) IMAGE="$OPTARG" ;;
t) TAG="$OPTARG" ;;
?) helpFunction ;; # Print helpFunction in case parameter is non-existent
esac
done
# Print helpFunction in case parameters are empty
if [ -z "$AWS_REGION" ] || [ -z "$CLUSTER" ] || [ -z "$SERVICE" ] || [ -z "$IMAGE" ] || [ -z "$TAG" ]; then
echo "Some or all of the parameters are empty"
helpFunction
fi
# Populate variable with service description
SRV_DESCR=$(aws ecs describe-services --region "${AWS_REGION}" \
--cluster "${CLUSTER}" \
--services "${SERVICE}")
# Get current task definition arn from service description
CURR_TASK_DEF_ARN=$(echo "$SRV_DESCR" | jq -r ".services[0].taskDefinition")
# Get current task definition json
CURR_TASK_DEF_JSON=$(aws ecs describe-task-definition \
--region "${AWS_REGION}" \
--task-definition "$CURR_TASK_DEF_ARN")
# Get family from current task definition
TASK_DEF_FAMILY=$(echo "$CURR_TASK_DEF_JSON" | jq -r '.taskDefinition.family')
echo "Generating a new task definition JSON..."
echo "$CURR_TASK_DEF_JSON" \
| jq -r '.taskDefinition' \
| jq -r '{ "family", "containerDefinitions", "volumes", "placementConstraints"}' \
| jq -r '.containerDefinitions[0].image='\""${IMAGE}":"${TAG}"\" > ./task_definition.json
echo "Creating a new revision of task definition..."
NEW_TASK_DEF=$(aws ecs register-task-definition \
--region "${AWS_REGION}" \
--cli-input-json file://task_definition.json \
| jq -r '.taskDefinition' \
| jq -r '{ "taskDefinitionArn", "revision" }')
# Populate variables
NEW_TASK_DEF_ARN=$(echo "$NEW_TASK_DEF" | jq -r '.taskDefinitionArn')
NEW_TASK_DEF_REV=$(echo "$NEW_TASK_DEF" | jq -r '.revision')
echo "Updating service with new revision of task definition..."
UPDATED_SERVICE=$(aws ecs update-service \
--region "${AWS_REGION}" \
--cluster "${CLUSTER}" \
--service "${SERVICE}" \
--task-definition "${TASK_DEF_FAMILY}":"${NEW_TASK_DEF_REV}")
echo "Deployments:"
echo "$UPDATED_SERVICE" | jq -r ".service.deployments"
# Checking deployment status
for ATTEMPT in {1..20}; do
DEPLOYMENT_COMPLETE=$(aws ecs describe-services \
--region "${AWS_REGION}" \
--services "${SERVICE}" \
--cluster "${CLUSTER}" \
| jq -r --arg arn "${NEW_TASK_DEF_ARN}" '.services[0].deployments
| .[]| select(.taskDefinition == $arn)
| (.desiredCount == .runningCount and .status == "PRIMARY")')
echo "Checking deployment status..."
echo "Complete: $DEPLOYMENT_COMPLETE"
if [ "$DEPLOYMENT_COMPLETE" == "true" ]; then
break
elif [[ "$ATTEMPT" -ne "20" && "$DEPLOYMENT_COMPLETE" == "false" ]]; then
echo "Sleeping..."
sleep 30
continue
else
echo "Deployment failed."
exit 1
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment