Skip to content

Commit 98c082c

Browse files
[Infra] 무중단 배포 (blue-green) 로직 추가
* feat: 무중단 배포 로직 추가 (terraform) * feat: 무중단 배포(deploy.yml)
1 parent 2de68b1 commit 98c082c

2 files changed

Lines changed: 117 additions & 29 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ jobs:
105105
echo "INSTANCE_ID=$INSTANCE_ID" >> $GITHUB_ENV
106106
echo $INSTANCE_ID
107107
108-
- name: AWS SSM Send-Command
108+
- name: AWS SSM Send-Command (Blue-Green Deployment)
109109
uses: peterkimzz/aws-ssm-send-command@master
110110
id: ssm
111111
with:
@@ -116,10 +116,75 @@ jobs:
116116
working-directory: /
117117
comment: Deploy
118118
command: |
119-
docker pull ghcr.io/${{ needs.buildImageAndPush.outputs.owner_lc }}/${{ needs.buildImageAndPush.outputs.image_name }}:latest && \
120-
docker stop app1 2>/dev/null || true && \
121-
docker rm app1 2>/dev/null || true && \
122-
docker run -d --name app1 --network common -p 8080:8080 \
119+
set -e
120+
121+
IMAGE="ghcr.io/${{ needs.buildImageAndPush.outputs.owner_lc }}/${{ needs.buildImageAndPush.outputs.image_name }}:latest"
122+
HAPROXY_CFG="/usr/local/etc/haproxy/haproxy.cfg"
123+
124+
echo "=== Blue-Green Deploy Start ==="
125+
126+
# 현재 활성 backend 확인
127+
CURRENT_BACKEND=$(docker exec ha_proxy_1 grep "use_backend" $HAPROXY_CFG | awk '{print $2}')
128+
echo "Current backend: $CURRENT_BACKEND"
129+
130+
if [ "$CURRENT_BACKEND" = "blue_backend" ]; then
131+
NEW_CONTAINER="app1_temp"
132+
OLD_CONTAINER="app1"
133+
TARGET_BACKEND="green_backend"
134+
else
135+
NEW_CONTAINER="app1"
136+
OLD_CONTAINER="app1_temp"
137+
TARGET_BACKEND="blue_backend"
138+
fi
139+
140+
echo "New container: $NEW_CONTAINER"
141+
echo "Old container: $OLD_CONTAINER"
142+
echo "Target backend: $TARGET_BACKEND"
143+
144+
# 이미지 pull
145+
docker pull $IMAGE
146+
147+
# 신규 컨테이너 정리
148+
docker stop $NEW_CONTAINER 2>/dev/null || true
149+
docker rm $NEW_CONTAINER 2>/dev/null || true
150+
151+
# 신규 컨테이너 실행
152+
docker run -d \
153+
--name $NEW_CONTAINER \
154+
--network common \
123155
-e DOPPLER_TOKEN=${{ secrets.DOPPLER_TOKEN }} \
124-
ghcr.io/${{ needs.buildImageAndPush.outputs.owner_lc }}/${{ needs.buildImageAndPush.outputs.image_name }}:latest && \
125-
docker image prune -f
156+
$IMAGE
157+
158+
# Health check (최대 60초)
159+
for i in {1..30}; do
160+
if docker exec $NEW_CONTAINER curl -fs http://localhost:8080/actuator/health > /dev/null; then
161+
echo "✅ Health check passed"
162+
break
163+
fi
164+
165+
if [ "$i" -eq 30 ]; then
166+
echo "❌ Health check failed"
167+
docker logs $NEW_CONTAINER
168+
docker stop $NEW_CONTAINER
169+
docker rm $NEW_CONTAINER
170+
exit 1
171+
fi
172+
173+
sleep 2
174+
done
175+
176+
# HAProxy backend 전환
177+
sed -i "s/use_backend .*/use_backend $TARGET_BACKEND if host_api/" $HAPROXY_CFG
178+
docker kill -s HUP ha_proxy_1
179+
echo "✅ HAProxy switched to $TARGET_BACKEND"
180+
181+
# 안정화 대기
182+
sleep 20
183+
184+
# 이전 컨테이너 정리
185+
docker stop $OLD_CONTAINER 2>/dev/null || true
186+
docker rm $OLD_CONTAINER 2>/dev/null || true
187+
188+
docker image prune -f
189+
190+
echo "=== Blue-Green Deploy Completed ==="

infra/main.tf

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,6 @@ resource "aws_subnet" "subnet_2" {
6363
}
6464
}
6565

66-
# 추후 필요 시 추가
67-
# resource "aws_subnet" "subnet_3" {
68-
# vpc_id = aws_vpc.vpc_1.id
69-
# cidr_block = "10.0.3.0/24"
70-
# availability_zone = "${var.region}c"
71-
# map_public_ip_on_launch = true
72-
#
73-
# tags = {
74-
# Name = "${local.name}-subnet-3"
75-
# Team = var.team_tag
76-
# }
77-
# }
78-
7966
resource "aws_internet_gateway" "igw_1" {
8067
vpc_id = aws_vpc.vpc_1.id
8168

@@ -109,15 +96,6 @@ resource "aws_route_table_association" "association_2" {
10996
route_table_id = aws_route_table.rt_1.id
11097
}
11198

112-
# 추후 필요시 추가
113-
# resource "aws_route_table_association" "association_3" {
114-
# subnet_id = aws_subnet.subnet_3.id
115-
# route_table_id = aws_route_table.rt_1.id
116-
# }
117-
#DB 서브넷 넣으면 ssh로 접근해서관리해야함
118-
# 9090, 3300,
119-
# 3300
120-
12199
resource "aws_security_group" "sg_1" {
122100
name = "${local.name}-security-group"
123101

@@ -277,6 +255,51 @@ docker run -d \
277255
-v /dockerProjects/npm_1/volumes/etc/letsencrypt:/etc/letsencrypt \
278256
jc21/nginx-proxy-manager:latest
279257
258+
# haproxy 설치 (블루-그린 무중단 배포)
259+
mkdir -p /dockerProjects/ha_proxy_1/volumes/usr/local/etc/haproxy
260+
261+
cat > /dockerProjects/ha_proxy_1/volumes/usr/local/etc/haproxy/haproxy.cfg <<'EOF'
262+
global
263+
log stdout format raw local0
264+
maxconn 4096
265+
266+
defaults
267+
log global
268+
mode http
269+
option httplog
270+
timeout connect 5s
271+
timeout client 60s
272+
timeout server 60s
273+
274+
frontend http_front
275+
bind *:80
276+
acl host_api hdr(host) -i api.waitfair.shop
277+
use_backend blue_backend if host_api
278+
279+
# Blue 백엔드
280+
backend blue_backend
281+
option httpchk GET /actuator/health
282+
http-check expect status 200
283+
default-server inter 2s rise 2 fall 3
284+
server blue app1:8080 check
285+
286+
# Green 백엔드
287+
backend green_backend
288+
option httpchk GET /actuator/health
289+
http-check expect status 200
290+
default-server inter 2s rise 2 fall 3
291+
server green app1_temp:8080 check
292+
EOF
293+
294+
docker run -d \
295+
--name ha_proxy_1 \
296+
--restart unless-stopped \
297+
--network common \
298+
-p 80:80 \
299+
-e TZ=Asia/Seoul \
300+
-v /dockerProjects/ha_proxy_1/volumes/usr/local/etc/haproxy:/usr/local/etc/haproxy:ro \
301+
haproxy:2.9-alpine
302+
280303
281304
# redis 설치
282305
docker run -d \

0 commit comments

Comments
 (0)