-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathecs
More file actions
executable file
·256 lines (211 loc) · 6.58 KB
/
ecs
File metadata and controls
executable file
·256 lines (211 loc) · 6.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/bin/bash
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
# set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
function aws_setup {
if [ -z ${AWS_REGION+x} ]; then
AWS_REGION=$(aws configure get region)
fi
if [ -z ${AWS_ACCOUNT_ID+x} ]; then
AWS_ACCOUNT_ID=$(aws ec2 describe-security-groups --query 'SecurityGroups[0].OwnerId' --output text)
fi
if [ -z ${ECR_REGISTRY+x} ]; then
ECR_REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
fi
if [ -z ${AWS_LOGGED_IN+x} ]; then
$(aws ecr get-login --no-include-email)
AWS_LOGGED_IN=1
fi
}
function sourceDestinationInput {
# $1 is source as NAME:TAG
assert_name_tag_arg "Source NAME:TAG must be specified" $1
SOURCE_APP=${1%:*}
SOURCE_TAG=${1#*:}
SOURCE="$1"
# $2 is dest as NAME[:TAG]
assert_arg "Destination ECR_REPRO_NAME[:TAG] must be specified" $2
if [[ $2 == *":"* ]]; then
DEST_REPRO=${2%:*}
DEST_TAG=${2#*:}
else
DEST_REPRO="$2"
DEST_TAG="${SOURCE_APP}_${SOURCE_TAG}"
fi
}
function push {
sourceDestinationInput $1 $2
# Check if we can identify remote ECR repository
aws_setup
# Tag for remote ECR repository
docker tag "${SOURCE}" "${ECR_REGISTRY}/${DEST_REPRO}:${DEST_TAG}"
# push to remote ECR repository
docker push "${ECR_REGISTRY}/${DEST_REPRO}"
#Remove tags for image to avoid re-push
docker rmi "${ECR_REGISTRY}/${DEST_REPRO}:${DEST_TAG}"
}
function pull {
# $1 is source as NAME:TAG
assert_name_tag_arg "Source ECR_REPRO_NAME:TAG must be specified" $1
SOURCE="$1"
# Check if we can identify remote ECR repository
aws_setup
# Pull from repro
docker pull "${ECR_REGISTRY}/${SOURCE}"
}
function deploy {
sourceDestinationInput $1 $2
# use global vars created in sourceDestinationInput
ECS_CLUSTER_NAME="${DEST_REPRO}"
ECS_SERVICE_NAME="${SOURCE_APP}"
ECS_TASK_DEFINITION_NAME="${ECS_CLUSTER_NAME}-${ECS_SERVICE_NAME}"
# Get current task definition and update image to pushed TAG
IMAGE="${ECR_REGISTRY}/${DEST_REPRO}:${DEST_TAG}"
echo "Image: $IMAGE"
CONTAINER_DEF=$( \
aws ecs describe-task-definition --task-definition "${ECS_TASK_DEFINITION_NAME}" | \
jq '.taskDefinition.containerDefinitions[0]' | \
jq -r ".image= \"${IMAGE}\" " \
)
# Create new task revision using updated def
aws ecs register-task-definition --family "${ECS_TASK_DEFINITION_NAME}" --container-definitions "${CONTAINER_DEF}"
# Update service using old def
aws ecs update-service --cluster "${ECS_CLUSTER_NAME}" --service "${ECS_SERVICE_NAME}" --task-definition "${ECS_TASK_DEFINITION_NAME}"
}
function container {
# $1 is container name, $2 is cluster name
assert_arg "Container name must be specified" $1
assert_arg "Cluster name must be specified" $2
ECS_TASK_DEFINITION_NAME="$2-$1"
CONTAINER_DEF=$( \
aws ecs describe-task-definition --task-definition "${ECS_TASK_DEFINITION_NAME}" | \
jq '.taskDefinition.containerDefinitions[0]' \
)
echo "$CONTAINER_DEF" >&2
}
function image {
# $1 is container name, $2 is cluster name
assert_arg "Container name must be specified" $1
assert_arg "Cluster name must be specified" $2
ECS_TASK_DEFINITION_NAME="$2-$1"
IMAGE=$( \
aws ecs describe-task-definition --task-definition "${ECS_TASK_DEFINITION_NAME}" | \
jq '.taskDefinition.containerDefinitions[0].image' \
)
echo "$IMAGE" >&2
}
function docker_build {
assert_arg "Container name must be specified" $1
if [ -e pom.xml ]; then
mvn clean install
fi
CONTAINER_NAME=$1
GIT_STATUS=$(git status -s)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
GIT_COMMIT=$(git show -s --format='%h')
# Retrieving TAG may return error and contain non valid repro characters. Lets do later...
# GIT_TAG=$(git describe --exact-match "$GIT_COMMIT")
if [[ ! -z $GIT_STATUS ]]; then
echo "Has staged uncommited files"
TAG="${GIT_BRANCH}-${GIT_COMMIT}-SNAPSHOT"
else
if [[ ! -z $GIT_TAG ]]; then
TAG="${GIT_BRANCH}-${GIT_COMMIT}-${GIT_TAG}"
else
TAG="${GIT_BRANCH}-${GIT_COMMIT}"
fi
fi
# Build local image
docker build -t "${CONTAINER_NAME}:${TAG}" .
# Remove all dangling images (without name,tags)
DANGLING=$(docker images -f dangling=true -q)
if [[ ! -z $DANGLING ]]; then
docker rmi -f $DANGLING
fi
# If repro name is supplied, lets push image
if [[ ! -z $2 ]]; then
echo "push to $2"
push "${CONTAINER_NAME}:${TAG}" $2
echo "image tag: ${CONTAINER_NAME}_${TAG}"
fi
# lets list all images with container name to remind user to clean-up...
docker images "${CONTAINER_NAME}*"
}
function repositories {
aws ecr describe-repositories | jq -r "[.repositories[].repositoryName]"
}
function clusters {
aws ecs list-clusters | jq -r ".clusterArns"
}
function services {
# Cluster must be specified
if [ -z ${CLUSTER+x} ]; then
echo "-c CLUSTER_SHORT_NAME must be specified using the services command!"
exit 1
fi
aws ecs list-services --cluster "$CLUSTER" | jq -r ".serviceArns"
}
function assert_arg {
if [ -z ${2+x} ]; then
echo "$1" >&2
exit 1
fi
}
function assert_name_tag_arg {
assert_arg $1 $2
if [[ $2 != *":"* ]]; then
echo "$1" >&2
exit 1
fi
}
case "$1" in
push)
push $2 $3
;;
pull)
pull $2
;;
deploy)
deploy $2 $3
;;
container)
container $2 $3
;;
image)
image $2 $3
;;
repositories)
repositories
;;
clusters)
clusters
;;
build)
docker_build $2 $3
;;
services)
shift;
while getopts ":c::" opt; do
case $opt in
c)
CLUSTER="$OPTARG"
;;
\?)
echo "Invalid option for services: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
services
;;
*)
echo "Invalid command: $1"
echo $"Usage: $0 {push|pull|deploy|repositories|clusters|services}"
exit 1
;;
esac