contents
code Buildやcircleciで実行する、ECSのタスク定義作成、停止スクリプトサンプル。
例えば、dev(開発)環境であれば、ecsを問答無用で更新、停止。
本番環境であればタスク定義のみ更新し、リリース判断時にecsのblue green deploymentなどの使い分けをする場合を想定
対象者
CICDに興味がある、code Buildの実行イメージを掴みたい人
ECSタスク定義作成スクリプト makeNewECSTaskDefinition.sh
bash ./.circleci/makeNewECSTaskDefinition.sh --SERVICE_NAME ${SERVICE_NAME_WEB} --PORT_NUM "hoge" --CPU_VOLUME "2048" --MEMORY_VOLUME "4096" --IMAGE_TAG_NAME $CIRCLE_SHA1 --ENVIRONMENT_NAME ${ENVIRONMENT_NAME} --ENVIRONMENT_FULL_NAME ${ENVIRONMENT_FULL_NAME} --AWS_ACCOUNT_ID ${AWS_ACCOUNT_ID}
makeNewECSTaskDefinition.sh
#!bin/bash
# shの使用方法説明関数
function usage() {
cat <<EOS
Usage: $0 [REQUIRED OPTIONS]
[REQUIRED OPTIONS]
--IMAGE_TAG_NAME : IMAGE_TAG_NAME
--ENVIRONMENT_FULL_NAME : ENVIRONMENT_FULL_NAME
--AWS_ACCOUNT_ID : AWS_ACCOUNT_ID
--ENVIRONMENT_NAME : ENVIRONMENT_NAME
--SERVICE_NAME : SERVICE_NAME
--PORT_NUM : PORT_NUM
--CPU_VOLUME : CPU_VOLUME
--MEMORY_VOLUME : MEMORY_VOLUME
EOS
exit 1
}
# 引数から変数への格納部分 --** という引数を明示するために必要
ARGS=($@)
for ((i = 0; i < ${#ARGS[@]}; i++)); do
case "${ARGS[$i]}" in
"--IMAGE_TAG_NAME")
i=$(expr $i + 1)
readonly IMAGE_TAG_NAME="${ARGS[$i]}"
;;
"--ENVIRONMENT_FULL_NAME")
i=$(expr $i + 1)
readonly ENVIRONMENT_FULL_NAME="${ARGS[$i]}"
;;
"--AWS_ACCOUNT_ID")
i=$(expr $i + 1)
readonly AWS_ACCOUNT_ID="${ARGS[$i]}"
;;
"--ENVIRONMENT_NAME")
i=$(expr $i + 1)
readonly ENVIRONMENT_NAME="${ARGS[$i]}"
;;
"--SERVICE_NAME")
i=$(expr $i + 1)
readonly SERVICE_NAME="${ARGS[$i]}"
;;
"--PORT_NUM")
i=$(expr $i + 1)
readonly PORT_NUM="${ARGS[$i]}"
;;
"--CPU_VOLUME")
i=$(expr $i + 1)
readonly CPU_VOLUME="${ARGS[$i]}"
;;
"--MEMORY_VOLUME")
i=$(expr $i + 1)
readonly MEMORY_VOLUME="${ARGS[$i]}"
;;
*)
usage
;;
esac
done
# 引数をチェック。必要な引数がない場合は使用方法を説明
if [ -z "${IMAGE_TAG_NAME}" -o -z "${ENVIRONMENT_FULL_NAME}" -o -z "${AWS_ACCOUNT_ID}" -o -z "${ENVIRONMENT_NAME}" -o -z "${SERVICE_NAME}" -o -z "${PORT_NUM}" -o -z "${CPU_VOLUME}" -o -z "${MEMORY_VOLUME}" ]; then
usage
fi
#jqのinstall箇所
JQ_URL="https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/jq-latest"
sudo curl --silent --show-error --location --fail --retry 3 --output /usr/bin/jq $JQ_URL
sudo chmod +x /usr/bin/jq
# 環境変数設定部分
readonly ECR_DOMAIN="${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com"
readonly ECS_CLUSTER_NAME="sample-${ENVIRONMENT_NAME}-cluster"
readonly ECS_SERVICE_NAME="sample-${ENVIRONMENT_NAME}-${SERVICE_NAME}"
readonly ECS_ROLE_NAME="sample-${ENVIRONMENT_NAME}-rehouse-web"
# タスク定義のパラメータに関して、IMAGE_TAG_NAMEの情報を置換しデータを取得
TASK_JSON_DATA=$(cat << EOS | jq
{
"containerDefinitions": [
{
"name": "${SERVICE_NAME}",
"image": "${ECR_DOMAIN}/${SERVICE_NAME}:${IMAGE_TAG_NAME}",
"cpu": 0,
"portMappings": [
{
"containerPort": ${PORT_NUM},
"hostPort": ${PORT_NUM},
"protocol": "tcp"
}
],
"essential": true,
"environment": [],
"secrets": [{
"valueFrom": "google-map-api-key",
"name": "GOOGLE_MAP_API_KEY"
}
],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/${ECS_ROLE_NAME}",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": [
"CMD-SHELL",
"curl -f http://localhost:${PORT_NUM}/healthcheck || exit 1"
],
"interval": 30,
"timeout": 8,
"retries": 3,
"startPeriod": 240
}
}
],
"family": "${ECS_SERVICE_NAME}",
"taskRoleArn": "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ECS_ROLE_NAME}-task-role",
"executionRoleArn": "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ECS_ROLE_NAME}-task-role",
"networkMode": "awsvpc",
"volumes": [],
"placementConstraints": [],
"requiresCompatibilities": ["FARGATE"],
"cpu": "${CPU_VOLUME}",
"memory": "${MEMORY_VOLUME}"
}
EOS
)
# aws cliで使用するため一度ファイル出力
echo "$TASK_JSON_DATA" > .circleci/TASK_JSON_DATA.json
# aws cliでタスク登録
aws ecs register-task-definition --family ${ECS_SERVICE_NAME} --cli-input-json fileb://.circleci/TASK_JSON_DATA.json
ECSタスク停止スクリプト stopECSTasks.sh
bash ./.circleci/stopECSTasks.sh --CLUSTER_NAME ${ECS_CLUSTER_NAME} --SERVICE_NAME sample-${ENVIRONMENT_NAME}-${SERVICE_NAME_WEB}
stopECSTasks.sh
#!bin/bash
# shの使用方法説明関数
function usage() {
cat <<EOS
Usage: $0 [REQUIRED OPTIONS]
[REQUIRED OPTIONS]
--CLUSTER_NAME : CLUSTER_NAME
--SERVICE_NAME : SERVICE_NAME
EOS
exit 1
}
# 引数から変数への格納部分 --** という引数を明示するために必要
ARGS=($@)
for ((i = 0; i < ${#ARGS[@]}; i++)); do
case "${ARGS[$i]}" in
"--CLUSTER_NAME")
i=$(expr $i + 1)
readonly CLUSTER_NAME="${ARGS[$i]}"
;;
"--SERVICE_NAME")
i=$(expr $i + 1)
readonly SERVICE_NAME="${ARGS[$i]}"
;;
*)
usage
;;
esac
done
# 引数をチェック。必要な引数がない場合は使用方法を説明
# 停止する条件を絞るためのクラスター名とサービス名(マッチしたタスクを停止する)
if [ -z "${CLUSTER_NAME}" -o -z "${SERVICE_NAME}" ]; then
usage
fi
#jqのinstall箇所
JQ_URL="https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/jq-latest"
sudo curl --silent --show-error --location --fail --retry 3 --output /usr/bin/jq $JQ_URL
sudo chmod +x /usr/bin/jq
#停止するタスク情報を上記の変数名から取得
json_data=$(aws ecs list-tasks --cluster ${CLUSTER_NAME} --query "taskArns" --service-name ${SERVICE_NAME})
json_length=`echo ${json_data} | jq length`
for i in `seq 0 $(expr ${json_length} - 1)`
do
#アカウントに紐付き、該当するタスクの名前を全て取得
taskname=`echo ${json_data} | jq .[${i}] | sed "s/\"//g"`
echo ${taskname}
#タスク消去、apiの戻り値を消去するために--query 'noResponse'を設定
aws ecs stop-task --cluster ${CLUSTER_NAME} --task ${taskname} --query 'noResponse'
done