-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·138 lines (120 loc) · 5.08 KB
/
Copy pathdeploy.sh
File metadata and controls
executable file
·138 lines (120 loc) · 5.08 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
#!/usr/bin/env bash
# AWS deployment: build image → push to ECR → deploy to ECS
# Usage: ./deploy.sh [--gpu]
set -euo pipefail
# ---------------------------------------------------------------------------
# Config — override with environment variables
# ---------------------------------------------------------------------------
AWS_REGION="${AWS_REGION:-us-east-1}"
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID:?Set AWS_ACCOUNT_ID}"
ECR_REPO="${ECR_REPO:-llm-studio}"
ECS_CLUSTER="${ECS_CLUSTER:-llm-studio-cluster}"
ECS_SERVICE="${ECS_SERVICE:-llm-studio-service}"
ECS_TASK_FAMILY="${ECS_TASK_FAMILY:-llm-studio-task}"
IMAGE_TAG="${IMAGE_TAG:-$(git rev-parse --short HEAD)}"
GPU_SUPPORT="${1:-}"
ECR_URI="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO}"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
log() { echo "[$(date '+%H:%M:%S')] $*"; }
die() { echo "ERROR: $*" >&2; exit 1; }
confirm() {
read -rp "$1 [y/N] " ans
[[ "${ans,,}" == "y" ]] || die "Aborted."
}
# ---------------------------------------------------------------------------
# Pre-flight checks
# ---------------------------------------------------------------------------
log "Pre-flight checks"
command -v aws >/dev/null 2>&1 || die "aws CLI not found"
command -v docker >/dev/null 2>&1 || die "docker not found"
aws sts get-caller-identity --query "Account" --output text >/dev/null \
|| die "AWS credentials not configured (run: aws configure)"
log "Deploying image tag: ${IMAGE_TAG}"
log "Target: ${ECR_URI}:${IMAGE_TAG}"
[[ "${GPU_SUPPORT}" == "--gpu" ]] && log "GPU support: enabled"
confirm "Proceed with deployment?"
# ---------------------------------------------------------------------------
# Run tests before deploying
# ---------------------------------------------------------------------------
log "Running test suite"
if command -v python3 >/dev/null 2>&1 && [ -d "venv" ]; then
venv/bin/pytest tests/ -q || die "Tests failed — aborting deploy"
else
log "WARNING: venv not found, skipping tests"
fi
# ---------------------------------------------------------------------------
# Build Docker image
# ---------------------------------------------------------------------------
log "Building Docker image"
DOCKERFILE="Dockerfile"
if [[ "${GPU_SUPPORT}" == "--gpu" ]]; then
DOCKERFILE="Dockerfile.gpu"
[ -f "${DOCKERFILE}" ] || die "${DOCKERFILE} not found. Create a GPU Dockerfile first."
fi
docker build \
--file "${DOCKERFILE}" \
--tag "${ECR_URI}:${IMAGE_TAG}" \
--tag "${ECR_URI}:latest" \
--build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--build-arg GIT_COMMIT="${IMAGE_TAG}" \
.
# ---------------------------------------------------------------------------
# Push to ECR
# ---------------------------------------------------------------------------
log "Authenticating with ECR"
aws ecr get-login-password --region "${AWS_REGION}" \
| docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
log "Creating ECR repository if it doesn't exist"
aws ecr describe-repositories --repository-names "${ECR_REPO}" --region "${AWS_REGION}" >/dev/null 2>&1 \
|| aws ecr create-repository --repository-name "${ECR_REPO}" --region "${AWS_REGION}"
log "Pushing image to ECR"
docker push "${ECR_URI}:${IMAGE_TAG}"
docker push "${ECR_URI}:latest"
# ---------------------------------------------------------------------------
# Update ECS task definition
# ---------------------------------------------------------------------------
log "Fetching current task definition"
TASK_DEF=$(aws ecs describe-task-definition \
--task-definition "${ECS_TASK_FAMILY}" \
--region "${AWS_REGION}" \
--query "taskDefinition" \
--output json)
# Swap in the new image URI
NEW_TASK_DEF=$(echo "${TASK_DEF}" \
| python3 -c "
import sys, json
td = json.load(sys.stdin)
for c in td['containerDefinitions']:
if c['name'] == 'app':
c['image'] = '${ECR_URI}:${IMAGE_TAG}'
for k in ['taskDefinitionArn','revision','status','requiresAttributes',
'compatibilities','registeredAt','registeredBy']:
td.pop(k, None)
print(json.dumps(td))
")
log "Registering new task definition"
NEW_TASK_ARN=$(aws ecs register-task-definition \
--cli-input-json "${NEW_TASK_DEF}" \
--region "${AWS_REGION}" \
--query "taskDefinition.taskDefinitionArn" \
--output text)
log "New task definition: ${NEW_TASK_ARN}"
# ---------------------------------------------------------------------------
# Deploy to ECS service
# ---------------------------------------------------------------------------
log "Updating ECS service"
aws ecs update-service \
--cluster "${ECS_CLUSTER}" \
--service "${ECS_SERVICE}" \
--task-definition "${NEW_TASK_ARN}" \
--force-new-deployment \
--region "${AWS_REGION}" \
--output text --query "service.serviceName"
log "Waiting for deployment to stabilise (this may take a few minutes)"
aws ecs wait services-stable \
--cluster "${ECS_CLUSTER}" \
--services "${ECS_SERVICE}" \
--region "${AWS_REGION}"
log "Deployment complete: ${ECR_URI}:${IMAGE_TAG}"