Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: support multiple images #229

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ def
newdef
results
tasks
.idea/
.idea/
.*
!.*ignore*
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ Usage
Format: [domain][:port][/repo][/][image][:tag]
Examples: mariadb, mariadb:latest, silintl/mariadb,
silintl/mariadb:latest, private.registry.com:8000/repo/image:tag
--image-map Find and replace image names per container according to a map. Overrides --image
Format: "[image_str_contains1],[image1];[image_str_contains2],[image2]"
Examples: "ubuntu:18.04,ubuntu:20.04;nginx:1.18.0,nginx:1.19.9-alpine"
Replaces all images that contain "ubuntu:18.04" with "ubuntu:20.04" and all images
that contain "nginx:1.18.0" with "nginx:1.19.0-alpine"

Optional arguments:
-a | --aws-assume-role ARN for AWS Role to assume for ecs-deploy operations.
Expand Down Expand Up @@ -226,6 +231,22 @@ is tested.

Any new functionality and pull requests should come with tests as well (if possible).

```bash
$ git clone https://github.com/silinternational/ecs-deploy.git
$ docker build -t ecs-deploy .
$ docker run --rm -it -v $PWD/:/code/ --workdir=/code/ --entrypoint=bash \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN ecs-deploy
$ bash-5.1 ls
Dockerfile README.md codeship-services.yml composer.json ecs-deploy run-tests.sh
LICENSE action.yml codeship-steps.yml docker-compose.yml local.env.dist test.bats
$ bash-5.1 ./run-tests.sh
ok 1 check that usage() returns string and exits with status code 20
...
ok 35 test createNewTaskDefJson with multiple containers in definition and replace only tags
```

Github Actions Support
-------
Github Actions support is available. Add a code block similar to that below to your actions yaml file. Parameters are passed to the ecs-deploy tool under 'with' section. For each parameter, the parameter name followed by _cmd must be called with the appropriate parameter option like '--aws-access-key' in addition to supplying the parameter aws_access_key with the appropriate value.
Expand Down
59 changes: 52 additions & 7 deletions ecs-deploy
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ TASK_DEFINITION_FILE=false
MAX_DEFINITIONS=0
AWS_ASSUME_ROLE=false
IMAGE=false
IMAGE_MAP=false
MIN=false
MAX=false
TIMEOUT=90
VERBOSE=false
DRY_RUN=false
TAGVAR=false
TAGONLY=""
ENABLE_ROLLBACK=false
Expand Down Expand Up @@ -49,6 +51,11 @@ Required arguments:
Format: [domain][:port][/repo][/][image][:tag]
Examples: mariadb, mariadb:latest, silintl/mariadb,
silintl/mariadb:latest, private.registry.com:8000/repo/image:tag
--image-map Find and replace image names per container according to a map. Overrides --image
Format: "[image_str_contains1],[image1];[image_str_contains2],[image2]"
Examples: "ubuntu:18.04,ubuntu:20.04;nginx:1.18.0,nginx:1.19.9-alpine"
Replaces all images that contain "ubuntu:18.04" with "ubuntu:20.04" and all images
that contain "nginx:1.18.0" with "nginx:1.19.0-alpine"
--aws-instance-profile Use the IAM role associated with this instance

Optional arguments:
Expand Down Expand Up @@ -77,6 +84,7 @@ Optional arguments:
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)
--copy-task-definition-tags Copy the existing task definition tags to the new task definition revision
--dry-run Print the parsed task definition
-v | --verbose Verbose output
--version Display the version

Expand Down Expand Up @@ -172,8 +180,11 @@ function assertRequiredArgumentsSet() {
echo "CLUSTER is required. You can pass the value using -c or --cluster"
exit 7
fi
if [ $IMAGE_MAP != false ]; then
IMAGE=true # Overrides --image
fi
if [ $IMAGE == false ] && [ $FORCE_NEW_DEPLOYMENT == false ]; then
echo "IMAGE is required. You can pass the value using -i or --image"
echo "IMAGE or IMAGE_MAP are required. You can pass image value using -i or --image, or image map using --image-map"
exit 8
fi
if ! [[ $MAX_DEFINITIONS =~ ^-?[0-9]+$ ]]; then
Expand Down Expand Up @@ -360,7 +371,24 @@ function createNewTaskDefJson() {
# Get a JSON representation of the current task definition
# + Update definition to use new image name
# + Filter the def
if [[ "x$TAGONLY" == "x" ]]; then
if [[ "$IMAGE_MAP" != false ]]; then
local image_contains
local use_image
local DEF="false"
IFS=';' read -r -a array_image_map <<< "$IMAGE_MAP"
for image_map in "${array_image_map[@]}"; do
image_contains="$(echo "$image_map" | cut -d"," -f1)"
use_image="$(echo "$image_map" | cut -d"," -f2)"
if [[ "$DEF" == "false" ]]; then
# first image in map
DEF=$( sed -e 's~"image":.*'"${image_contains}"'.*,~"image": "'"${use_image}"'",~g' <<< "$taskDefinition")
else
# subsequent images in map
DEF=$( sed -e 's~"image":.*'"${image_contains}"'.*,~"image": "'"${use_image}"'",~g' <<< "$DEF")
fi
done
DEF=$(echo "$DEF" | jq '.taskDefinition')
elif [[ "x$TAGONLY" == "x" ]]; then
DEF=$( echo "$taskDefinition" \
| sed -e 's~"image":.*'"${imageWithoutTag}"'.*,~"image": "'"${useImage}"'",~g' \
| jq '.taskDefinition' )
Expand Down Expand Up @@ -398,7 +426,7 @@ function createNewTaskDefJson() {
NEW_DEF=$(echo "$DEF" | jq "{${NEW_DEF_JQ_FILTER}}")

# If in test mode output $NEW_DEF
if [ "$BASH_SOURCE" != "$0" ]; then
if [ "$BASH_SOURCE" != "$0" ] || [[ "$DRY_RUN" = "true" ]] ; then
echo "$NEW_DEF"
fi
}
Expand All @@ -419,7 +447,7 @@ function rollback() {

function updateServiceForceNewDeployment() {
echo 'Force a new deployment of the service'
$AWS_ECS update-service --cluster $CLUSTER --service $SERVICE --force-new-deployment > /dev/null
$AWS_ECS update-service --cluster $CLUSTER --service $SERVICE --force-new-deployment # > /dev/null
}

function updateService() {
Expand Down Expand Up @@ -663,6 +691,10 @@ if [ "$BASH_SOURCE" == "$0" ]; then
IMAGE="$2"
shift
;;
--image-map)
IMAGE_MAP="$2"
shift
;;
-t|--timeout)
TIMEOUT="$2"
shift
Expand Down Expand Up @@ -731,6 +763,9 @@ if [ "$BASH_SOURCE" == "$0" ]; then
-v|--verbose)
VERBOSE=true
;;
--dry-run)
DRY_RUN=true
;;
--version)
echo ${VERSION}
exit 0
Expand Down Expand Up @@ -766,17 +801,27 @@ if [ "$BASH_SOURCE" == "$0" ]; then
exit 0
fi

# Determine image name
parseImageName
echo "Using image name: $useImage"
if [ "$IMAGE_MAP" != false ]; then
echo "Using image-map: $IMAGE_MAP"
else
# Determine single image name
parseImageName
echo "Using image name: $useImage"
fi

# Get current task definition
getCurrentTaskDefinition
echo "Current task definition: $TASK_DEFINITION_ARN";


# create new task definition json
createNewTaskDefJson

if [ $DRY_RUN == true ]; then
echo "Dry run execution, stopping ..."
exit 0
fi

# register new task definition
registerNewTaskDefinition
echo "New task definition: $NEW_TASKDEF";
Expand Down