Skip to content

Commit

Permalink
Merge branch 'develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
unfor19 authored Aug 22, 2020
2 parents 401d1e0 + cf502d3 commit 9c0534a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 9 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM alpine:3.8
FROM alpine:3.12

# Install packges needed
RUN apk --no-cache add ca-certificates curl bash jq py2-pip && \
RUN apk --no-cache add ca-certificates curl bash jq py3-pip && \
pip install awscli

COPY ecs-deploy /ecs-deploy
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ Usage
Note: This number must be 1 or higher (i.e. keep only the current revision ACTIVE).
Max definitions causes all task revisions not matching criteria to be deregistered, even if they're created manually.
Script will only perform deregistration if deployment succeeds.
--task-definition-file File used as task definition to deploy
--enable-rollback Rollback task definition if new version is not running before TIMEOUT
--use-latest-task-def Will use the most recently created task definition as it's base, rather than the last used.
--force-new-deployment Force a new deployment of the service. Default is false.
--skip-deployments-check Skip deployments check for services that take too long to drain old tasks
--run-task Run created task now. If you set this, service-name are not needed.
--wait-for-success Wait for task execution to complete and to receive the exitCode 0.
--launch-type The launch type on which to run your task. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
--network-configuration The network configuration for the task. This parameter is required for task definitions that use
the awsvpc network mode to receive their own elastic network interface, and it is not supported
for other network modes. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
-v | --verbose Verbose output
--version Display the version

Expand Down
125 changes: 118 additions & 7 deletions ecs-deploy
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/usr/bin/env bash

# Setup default values for variables
VERSION="3.7.1"
VERSION="3.8.0"
CLUSTER=false
SERVICE=false
TASK_DEFINITION=false
TASK_DEFINITION_FILE=false
MAX_DEFINITIONS=0
AWS_ASSUME_ROLE=false
IMAGE=false
Expand All @@ -21,6 +22,9 @@ AWS_ECS="$AWS_CLI --output json ecs"
FORCE_NEW_DEPLOYMENT=false
SKIP_DEPLOYMENTS_CHECK=false
RUN_TASK=false
RUN_TASK_LAUNCH_TYPE=false
RUN_TASK_NETWORK_CONFIGURATION=false
RUN_TASK_WAIT_FOR_SUCCESS=false

function usage() {
cat <<EOM
Expand Down Expand Up @@ -53,11 +57,17 @@ Optional arguments:
-e | --tag-env-var Get image tag name from environment variable. If provided this will override value specified in image name argument.
-to | --tag-only New tag to apply to all images defined in the task (multi-container task). If provided this will override value specified in image name argument.
--max-definitions Number of Task Definition Revisions to persist before deregistering oldest revisions.
--task-definition-file File used as task definition to deploy
--enable-rollback Rollback task definition if new version is not running before TIMEOUT
--force-new-deployment Force a new deployment of the service. Default is false.
--use-latest-task-def Will use the most recently created task definition as it's base, rather than the last used.
--skip-deployments-check Skip deployments check for services that take too long to drain old tasks
--run-task Run created task now. If you set this, service-name are not needed.
--wait-for-success Wait for task execution to complete and to receive the exitCode 0.
--launch-type The launch type on which to run your task. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
--network-configuration The network configuration for the task. This parameter is required for task definitions that use
the awsvpc network mode to receive their own elastic network interface, and it is not supported
for other network modes. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
-v | --verbose Verbose output
--version Display the version
Expand Down Expand Up @@ -162,6 +172,21 @@ function assertRequiredArgumentsSet() {
exit 9
fi

if [ $RUN_TASK == false ] && [ $RUN_TASK_LAUNCH_TYPE != false ]; then
echo 'LAUNCH TYPE requires setting RUN TASK argument. You can set it using --run-task flag.'
exit 10
fi

if [ $RUN_TASK == false ] && [ $RUN_TASK_NETWORK_CONFIGURATION != false ]; then
echo 'NETWORK CONFIGURATION requires setting RUN TASK argument. You can set it using --run-task flag.'
exit 11
fi

if [ $RUN_TASK == false ] && [ $RUN_TASK_WAIT_FOR_SUCCESS != false ]; then
echo 'WAIT FOR SUCCESS requires setting RUN TASK argument. You can set it using --run-task flag.'
exit 11
fi

}

function parseImageName() {
Expand Down Expand Up @@ -303,6 +328,13 @@ function getCurrentTaskDefinition() {
}

function createNewTaskDefJson() {

if [ $TASK_DEFINITION_FILE == false ]; then
taskDefinition="$TASK_DEFINITION"
else
taskDefinition="$(cat $TASK_DEFINITION_FILE)"
fi

# Get a JSON representation of the current task definition
# + Update definition to use new image name
# + Filter the def
Expand All @@ -311,7 +343,7 @@ function createNewTaskDefJson() {
| sed -e 's~"image":.*'$imageWithoutTag'.*,~"image": "'${useImage}'",~' \
| jq '.taskDefinition' )
else
DEF=$( echo "$TASK_DEFINITION" \
DEF=$( echo "$taskDefinition" \
| sed -e "s|\(\"image\": *\".*:\)\(.*\)\"|\1${useImage}\"|g" \
| jq '.taskDefinition' )
fi
Expand All @@ -332,7 +364,11 @@ function createNewTaskDefJson() {
# Updated jq filters for AWS Fargate
REQUIRES_COMPATIBILITIES=$(echo "${DEF}" | jq -r '. | select(.requiresCompatibilities != null) | .requiresCompatibilities[]')
if `echo ${REQUIRES_COMPATIBILITIES[@]} | grep -q "FARGATE"`; then
FARGATE_JQ_FILTER='executionRoleArn: .executionRoleArn, requiresCompatibilities: .requiresCompatibilities, cpu: .cpu, memory: .memory'
FARGATE_JQ_FILTER='requiresCompatibilities: .requiresCompatibilities, cpu: .cpu, memory: .memory'

if [[ ! "$NEW_DEF_JQ_FILTER" =~ ".*executionRoleArn.*" ]]; then
FARGATE_JQ_FILTER="${FARGATE_JQ_FILTER}, executionRoleArn: .executionRoleArn"
fi
NEW_DEF_JQ_FILTER="${NEW_DEF_JQ_FILTER}, ${FARGATE_JQ_FILTER}"
fi

Expand Down Expand Up @@ -361,6 +397,14 @@ function updateServiceForceNewDeployment() {
}

function updateService() {
if [[ $(echo ${NEW_DEF} | jq ".containerDefinitions[0].healthCheck != null") == true ]]; then
checkFieldName="healthStatus"
checkFieldValue="HEALTHY"
else
checkFieldName="lastStatus"
checkFieldValue="RUNNING"
fi

UPDATE_SERVICE_SUCCESS="false"
DEPLOYMENT_CONFIG=""
if [ $MAX != false ]; then
Expand Down Expand Up @@ -397,8 +441,8 @@ function updateService() {

if [[ ! -z $RUNNING_TASKS ]] ; then
RUNNING=$($AWS_ECS describe-tasks --cluster "$CLUSTER" --tasks $RUNNING_TASKS \
| jq ".tasks[]| if .taskDefinitionArn == \"$NEW_TASKDEF\" then . else empty end|.lastStatus" \
| grep -e "RUNNING") || :
| jq ".tasks[]| if .taskDefinitionArn == \"$NEW_TASKDEF\" then . else empty end|.${checkFieldName}" \
| grep -e "${checkFieldValue}") || :

if [ "$RUNNING" ]; then
echo "Service updated successfully, new task definition running.";
Expand Down Expand Up @@ -474,7 +518,57 @@ function waitForGreenDeployment {

function runTask {
echo "Run task: $NEW_TASKDEF";
$AWS_ECS run-task --cluster $CLUSTER --task-definition $NEW_TASKDEF > /dev/null
AWS_ECS_RUN_TASK="$AWS_ECS run-task --cluster $CLUSTER --task-definition $NEW_TASKDEF"
if [ $RUN_TASK_LAUNCH_TYPE != false ]; then
AWS_ECS_RUN_TASK="$AWS_ECS_RUN_TASK --launch-type $RUN_TASK_LAUNCH_TYPE"
fi

if [ $RUN_TASK_NETWORK_CONFIGURATION != false ]; then
AWS_ECS_RUN_TASK="$AWS_ECS_RUN_TASK --network-configuration \"$RUN_TASK_NETWORK_CONFIGURATION\""
fi

TASK_ARN=$(eval $AWS_ECS_RUN_TASK | jq -r '.tasks[0].taskArn')
echo "Executed task: $TASK_ARN"

if [ $RUN_TASK_WAIT_FOR_SUCCESS == true ]; then
RUN_TASK_SUCCESS=false
every=10
i=0
while [ $i -lt $TIMEOUT ]
do

TASK_JSON=$($AWS_ECS describe-tasks --cluster "$CLUSTER" --tasks "$TASK_ARN")

TASK_STATUS=$(echo $TASK_JSON | jq -r '.tasks[0].lastStatus')
TASK_EXIT_CODE=$(echo $TASK_JSON | jq -r '.tasks[0].containers[0].exitCode')

if [ $TASK_STATUS == "STOPPED" ]; then
echo "Task finished with status: $TASK_STATUS"
if [ $TASK_EXIT_CODE != 0 ]; then
echo "Task execution failed with exit code: $TASK_EXIT_CODE"
exit 1
fi
RUN_TASK_SUCCESS=true
break;
fi

echo "Checking task status every $every seconds. Status: $TASK_STATUS"

sleep $every
i=$(( $i + $every ))
done

if [ $RUN_TASK_SUCCESS == false ]; then
echo "ERROR: New task run took longer than $TIMEOUT seconds"
exit 1
fi
fi



echo "Task $TASK_ARN executed successfully!"
exit 0

}

######################################################
Expand Down Expand Up @@ -567,6 +661,10 @@ if [ "$BASH_SOURCE" == "$0" ]; then
MAX_DEFINITIONS="$2"
shift
;;
--task-definition-file)
TASK_DEFINITION_FILE="$2"
shift
;;
--enable-rollback)
ENABLE_ROLLBACK=true
;;
Expand All @@ -582,6 +680,17 @@ if [ "$BASH_SOURCE" == "$0" ]; then
--run-task)
RUN_TASK=true
;;
--launch-type)
RUN_TASK_LAUNCH_TYPE="$2"
shift
;;
--wait-for-success)
RUN_TASK_WAIT_FOR_SUCCESS=true
;;
--network-configuration)
RUN_TASK_NETWORK_CONFIGURATION="$2"
shift
;;
-v|--verbose)
VERBOSE=true
;;
Expand Down Expand Up @@ -614,7 +723,9 @@ if [ "$BASH_SOURCE" == "$0" ]; then
# Not required creation of new a task definition
if [ $FORCE_NEW_DEPLOYMENT == true ]; then
updateServiceForceNewDeployment
waitForGreenDeployment
if [[ $SKIP_DEPLOYMENTS_CHECK != true ]]; then
waitForGreenDeployment
fi
exit 0
fi

Expand Down

0 comments on commit 9c0534a

Please sign in to comment.