ํด๋น ๊ธ์์๋ ์ธ๋ถ์ ์ธ AWS ์ค์ ์ ๋ํด ๋ค๋ฃจ์ง ์์ต๋๋ค. ๐ซฃ
๊ตฌ์ฒด์ ์ธ ์ค์ ์ ๋ํด์๋ ๋ค์ ๊ธ๋ค์ ์ฐธ๊ณ ํด์ฃผ์ธ์!
Github Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ CI/CD - Node.js(1)
๐ค CI/CD๋? โญ๏ธ CI CI๋ Continuous Integration์ ์ฝ์๋ก ์ง์์ ์ธ ํตํฉ์ ์๋ฏธํฉ๋๋ค. ์ฝ๊ฒ ๋งํ๋ฉด ๋น๋/ํ ์คํธ ์๋ํ ๊ณผ์ ์ด๋ผ๊ณ ํ ์ ์๋๋ฐ, CI๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌํํ ๊ฒฝ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ
www.devjoon.com
Github Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ CI/CD - Node.js(2)
AWS CodeDeploy๋ฅผ ํ์ฉํด์ ์๋ ๋ฐฐํฌ๋ฅผ ํ๊ธฐ ์ํด์๋ AWS์์ ๊ด๋ จ ์ค์ ๋ค์ ํด์ค์ผ ํฉ๋๋ค. ๐ AWS S3 ๋ฒํท ์์ฑ Github Actions์์ ๋น๋ํ ํ๋ก์ ํธ๋ฅผ AWS์ ์ ์ฅํ๊ธฐ ์ํ S3 ๋ฒํท์ด ํ์ํฉ๋๋ค. AWS > S
www.devjoon.com
๐ง ๋ธ๋ฃจ/๊ทธ๋ฆฐ ๋ฐฐํฌ๋?
๋ธ๋ฃจ/๊ทธ๋ฆฐ ๋ฐฐํฌ๋ ๋ฌด์ค๋จ ๋ฐฐํฌ ๋ฐฉ์ ์ค ํ๋์ ๋๋ค.
๋ฌด์ค๋จ ๋ฐฐํฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จ ์์ด ๋ฐฐํฌ๋ฅผ ํ๋ ๊ฒ์ ๋งํ๋๋ฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ์ ์ค๋จ๋ ๊น์?
์๋น์ค๊ฐ ์ ๋ฐ์ดํธ ๋์ด ์๋กญ๊ฒ ๋ฐฐํฌ๋ฅผ ํด์ผํ๋ ์ํฉ์ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ์กด ์๋ฒ๋ฅผ 8080 ํฌํธ์ ๋ฐฐํฌ์ค์ด๊ณ ์๋กญ๊ฒ ๋ฐฐํฌํ๋ ์๋ฒ ๋ํ 8080 ํฌํธ์ ๋ฐฐํฌ๋ฅผ ํ๋ ค๋ฉด ๊ธฐ์กด์ ์คํ๋๋ ์๋ฒ๋ฅผ ์์ ํ๊ฒ ์ข ๋ฃํ ํ์, ์๋ก์ด ์๋ฒ๋ฅผ ์คํํด์ผ ํฉ๋๋ค.
์ด๋ ๊ฒ ์๋ฒ๋ฅผ ์๋กญ๊ฒ ๋ฐฐํฌํ๋ ๊ณผ์ ์์ ์๋ฒ๊ฐ ์ ๊น ๋ด๋ ค๊ฐ๊ฒ ๋๋๋ฐ, ์ด๋ฌํ ๊ณผ์ ์ ์ค๋จ ๋ฐฐํฌ๋ผ๊ณ ํฉ๋๋ค.
์ค๋จ ๋ฐฐํฌ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฌด์ค๋จ ๋ฐฐํฌ๋ผ๋ ๊ฐ๋ ์ด ๋ฑ์ฅํ๊ณ ๋ํ์ ์ผ๋ก Rolling, Blue/Green, Canary ๋ฐฉ์์ด ์กด์ฌํฉ๋๋ค.
Blue/Green ๋ฐฐํฌ๋ ์ด์ ๋ฒ์ ์ ์๋ ์ฌ์ฉ์ ํธ๋ํฝ์ ์ด์ ๋ฒ์ ๊ณผ ๊ฑฐ์ ๋์ผํ ์ ๋ฒ์ ์ผ๋ก ์ ์ง์ ์ผ๋ก ์ด์ ํ๋ ๋ฐฐํฌ ๋ฐฉ์์ ๋๋ค.
์ข ๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ด์ ๋ฒ์ ์ธ Blue ํ๊ฒฝ(8081 ํฌํธ), ์ ๋ฒ์ ์ธ Green ํ๊ฒฝ(8082 ํฌํธ)์ด ์๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค.
๋ํ ๋ชจ๋ ์์ฒญ์ Nginx(80 ํฌํธ) ๋ก ๋ค์ด์ค๊ณ Nginx ๋ ๋ชจ๋ ์์ฒญ์ Blue ํ๊ฒฝ์์ ์ฒ๋ฆฌํ๋๋ก ํ๊ณ ์์ต๋๋ค.
์ด ๋, ์๋ก์ด ์๋ฒ๋ฅผ ๋ฐฐํฌํ๊ธฐ ์ํด์๋ Green ํ๊ฒฝ(8082 ํฌํธ)์ ์๋ฒ๋ฅผ ์คํํ ํ, Nginx ๊ฐ ๋ชจ๋ ์์ฒญ์ Green ํ๊ฒฝ์์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํธ๋ํฝ์ ์ ํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋ ํ์ ํธ๋ํฝ์ ์ ๋ฌํจ์ผ๋ก์จ ์๋น์ค๊ฐ ์ข ๋ฃ๋๊ณ ์คํ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์์ด์ง๋๋ค.
์ด๋ฅผ ํตํด ์ค๋จ ๋ฐฐํฌ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐฉ์์ด Blue/Green ๋ฐฐํฌ ๋ฐฉ์์ ๋๋ค.
(Rolling, Canary ๋ฐฐํฌ ๋ฐฉ์์ ๋ํ ์ค๋ช ์ ํด๋น ๊ฒ์๊ธ์์ ๋ค๋ฃจ์ง ์์ต๋๋ค. ๐ )
๐ก ์ ์ฒด ํ๋ฆ
์ด์ Spring Boot๋ฅผ ๋ธ๋ฃจ/๊ทธ๋ฆฐ ๋ฐฐํฌํ๊ธฐ ์ํ ์ ์ฒด์ ์ธ ํ๋ฆ์ ๋ํด ์ดํดํด๋ณด๊ฒ ์ต๋๋ค!
- ๋จผ์ Github Actions๋ฅผ ์ด์ฉํ์ฌ Github Repository์ ์ฌ๋ฆฐ ํ๋ก์ ํธ๋ฅผ ๋น๋ํฉ๋๋ค.
- ๋ฐฐํฌ์ ํ์ํ ํ์ผ๋ค๊ณผ ๋น๋๊ฐ ์๋ฃ๋ ํ๋ก์ ํธ๋ฅผ ์์ถํ์ฌ AWS S3์ ์ ๋ก๋ํฉ๋๋ค.
- ์ด์ด์ Github Actions๋ฅผ ์ด์ฉํ์ฌ AWS CodeDeploy๋ฅผ ์คํํฉ๋๋ค.
- AWS CodeDeploy๋ฅผ ์ด์ฉํ์ฌ AWS S3์ ์ ๋ก๋๋ ์์ถํ์ผ์ AWS EC2 ์ธ์คํด์ค๋ก ๊ฐ์ ธ์ต๋๋ค.
- AWS EC2์ ์์ถํ์ผ์ ๊ฐ์ ธ์จ ํ ์์ถ์ ํด์ ํฉ๋๋ค.
- ์์ถ์ ํด์ ํ๋ฉด ํ๋ก์ ํธ ๋น๋ ํ์ผ, ๋ฐฐํฌ์ ํ์ํ ์คํฌ๋ฆฝํธ๋ค์ด ์กด์ฌํฉ๋๋ค.
- AWS CodeDeploy๋ฅผ ์ด์ฉํ์ฌ ์คํฌ๋ฆฝํธ๋ค์ ์์๋๋ก ์คํํ์ฌ ๋ฐฐํฌํฉ๋๋ค.
์ด ๋, ๋ธ๋ฃจ/๊ทธ๋ฆฐ ๋ฐฐํฌ๋ฅผ ํ๊ธฐ ์ํด 7๋ฒ ๊ณผ์ ์์ 3๊ฐ์ง ๊ณผ์ ์ ๊ฑฐ์นฉ๋๋ค.
7-1. Green ํ๊ฒฝ์ ์๋ก์ด WAS ๋ฅผ ์คํํฉ๋๋ค.
7-2. Green ํ๊ฒฝ์ WAS ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋์ง Health Check ๋ฅผ ์งํํฉ๋๋ค.
7-3. Health Check ์ ์ฑ๊ณตํ๋ค๋ฉด, ํธ๋ํฝ์ Green ํ๊ฒฝ์ผ๋ก ์ ๋ฌํฉ๋๋ค.
๐ Nginx ์ค์
๋จผ์ ์ฌ์ฉ์ค์ธ EC2 ์ธ์คํด์ค์ Nginx ๋ฅผ ์ค์นํด์ผํฉ๋๋ค.
sudo apt install nginx
์ค์น๊ฐ ์๋ฃ๋๋ฉด ๋ค์ ๋ช ๋ น์ด๋ฅผ ํตํด ์ ์์ ์ผ๋ก ์คํ๋๊ณ ์๋์ง ํ์ธํด์ค๋๋ค.
sudo systemctl status nginx
๋ค์๊ณผ ๊ฐ์ด ํ์๋๋ฉด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ๋๋ค. ๐คฉ
๋ค์์ผ๋ก๋ http(80) ๋ก ์ ์ํ๋ฉด Nginx ์์ ์์ฒญ์ ๋ค๋ฅธ ํฌํธ๋ก ์ ๋ฌํ ์ ์๋๋ก ์๋ ์ค์ ์ ํด์ค๋๋ค.
sudo vim /etc/nginx/conf.d/service-url.inc ๋ก ํ์ผ ์์ฑ
# service-url.inc
# ์๋ ํ์ผ๋ก nginx๊ฐ ๋ฐ๋ผ๋ณผ ํฌํธ๋ฅผ ์ง์ ํ๋ค.
# ๋ด์ฉ์ ๋ฐฐํฌ์ ๋ง๋ค ์คํ๋๋ scripts๋ก ๋์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
set $service_url http://127.0.0.1:8081;
sudo vim /etc/nginx/nginx.conf ๋ก ์ค์ ํ์ผ ์์
# nginx.conf
http {
server {
include /etc/nginx/conf.d/service-url.inc;
location / {
# service_url๋ก ์์ฒญ ์ ๋ฌ!
proxy_pass $service_url;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
}
๋ค์๊ณผ ๊ฐ์ด ์ค์ ์ ๋ง์ณค๋ค๋ฉด Nginx ์ reverse proxy ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ Blue/Green ๋ฐฐํฌ๋ฅผ ์ ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
nginx.conf ํ์ผ์ Nginx ์ ์ค์ ํ์ผ์ธ๋ฐ proxy_pass
๊ฐ์ ์ค์ ํด์ 80 ํฌํธ๋ก ๋ค์ด์จ ์์ฒญ์ $service_url
๋ก ๋๊ฒจ์ค ์ ์๊ฒ ๋ฉ๋๋ค.
ํ์ฌ $service_url
์ 127.0.0.1:8081 ๋ก ์ค์ ํ ์ํ์ด๊ณ , ์ด ๊ฐ์ ๋์ ์ผ๋ก 8081๊ณผ 8082 ํฌํธ๋ก ์ค์ ๋ฉ๋๋ค.
$service_url
๊ฐ์ด ๋ฐ๋ ๋ Nginx ๋ฅผ reload ํ์ฌ ํธ๋ํฝ์ ์ ํํ๋ ๋ฐฉ์์
๋๋ค.
๐ Health Check ์ฉ API ์ถ๊ฐ
Nginx ์ค์ ์ ๋ง์ณค์ผ๋ฉด ์๋ก์ด ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋์ง ํ์ธํ ๋ ์ฌ์ฉํ API ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
๋ค์ API ๋ CodeDeploy ๊ฐ ์คํํ ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉ๋ฉ๋๋ค.
@RestController
public class HealthController {
@GetMapping("/health")
public String checkHealth() {
return "healthy";
}
}
๐ ์คํฌ๋ฆฝํธ ์์ฑ
์ด์ Blue/Green ๋ฐฐํฌ๋ฅผ ์ํ ์คํฌ๋ฆฝํธ๋ค์ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ์๋ก์ด ๋ฒ์ ์ ์๋ฒ๋ฅผ ์คํํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํฉ๋๋ค.
scripts/run_new_was.sh
CURRENT_PORT=$(cat /etc/nginx/conf.d/service-url.inc | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081
else
echo "[$NOW_TIME] No WAS is connected to nginx"
fi
TARGET_PID=$(lsof -Fp -i TCP:${TARGET_PORT} | grep -Po 'p[0-9]+' | grep -Po '[0-9]+')
if [ ! -z ${TARGET_PID} ]; then
echo "Kill WAS running at ${TARGET_PORT}."
sudo kill ${TARGET_PID}
fi
nohup java -jar -Dserver.port=${TARGET_PORT} /home/ubuntu/application/*.jar
echo "Now new WAS runs at ${TARGET_PORT}."
exit 0
CURRENT_PORT
: ํ์ฌ Nginx ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ํฌํธ ๋ฒํธ๋ฅผ service-url.inc ํ์ผ์์ ์ฝ์ด์ต๋๋ค.
TARGET_PORT
: ์๋ก์ด ์๋ฒ๋ฅผ ๋ฐฐํฌํ ํฌํธ๋ฅผ ํ์ฌ Nginx ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์์ง ์์ ํฌํธ๋ก ์ค์ ํฉ๋๋ค.
TARGET_PID
: ์๋ก์ด ์๋ฒ๋ฅผ ๋ฐฐํฌํ ํฌํธ์์ ํ์ฌ ์คํ์ค์ธ ํ๋ก์ธ์ค ์์ด๋์ ๋๋ค. ์๋ก์ด ์๋ฒ๋ฅผ ๋ฐฐํฌํ๊ธฐ ์ํด ๊ธฐ์กด์ ์คํ์ค์ธ ํ๋ก์ธ์ค๊ฐ ์๋ค๋ฉด ์ข ๋ฃํฉ๋๋ค.
- ๊ธฐ์กด์ ์คํ์ค์ธ ์๋ฒ๋ฅผ ์ข
๋ฃํ ๋ค ์๋ก์ด ์๋ฒ๋ฅผ
TARGET_PORT
์ ์คํํฉ๋๋ค.
๋ค์์ผ๋ก๋ ์๋กญ๊ฒ ์คํํ ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋์ง๋ฅผ ํ์ธํ๊ธฐ ์ํ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํฉ๋๋ค.
์์ ์์ฑํ๋ Health Check ์ฉ API ๋ฅผ ํ์ฉํฉ๋๋ค.
scripts/health_check.sh
CURRENT_PORT=$(cat /etc/nginx/conf.d/service-url.inc | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081
else
echo "No WAS is connected to nginx"
exit 1
fi
echo "Start health check of WAS at 'http://127.0.0.1:${TARGET_PORT}' ..."
for RETRY_COUNT in 1 2 3 4 5 6 7 8 9 10
do
echo "#${RETRY_COUNT} trying..."
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${TARGET_PORT}/health)
if [ ${RESPONSE_CODE} -eq 200 ]; then
echo "New WAS successfully running"
exit 0
elif [ ${RETRY_COUNT} -eq 10 ]; then
echo "Health check failed."
exit 1
fi
sleep 10
done
RETRY_COUNT
: 10์ด ๊ฐ๊ฒฉ์ผ๋ก ์ด 10๋ฒ ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋์ง Health Check ๋ฅผ ์๋ํฉ๋๋ค.
RESPONSE_CODE
: ์์ ์์ฑํ๋ Health Check ์ฉ API (http://127.0.0.1:${TARGET_PORT}/health) ๋ฅผ ํธ์ถํฉ๋๋ค. 200 ์ฑ๊ณต ์๋ต์ ๋ฐ์ ๊ฒฝ์ฐ, ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. (exit 0)
- 10๋ฒ ๋ชจ๋ Health Check ์ ์คํจํ ๊ฒฝ์ฐ ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋์ง ์์ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ์ฌ ์คํฌ๋ฆฝํธ๋ ์คํจํฉ๋๋ค. (exit 1)
์๋ก์ด ๋ฒ์ ์ ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋ค๋ ๊ฒ์ ํ์ธํ๋ฉด (Health Check ์ฑ๊ณต)
์ด์ Nginx ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ํฌํธ๋ฅผ ์๋ก์ด ๋ฒ์ ์ด ์คํ๋ ํฌํธ๋ก ์ ํํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋์ ๋๋ค.
scripts/switch.sh
CURRENT_PORT=$(cat /etc/nginx/conf.d/service-url.inc | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
echo "Nginx currently proxies to ${CURRENT_PORT}."
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081
else
echo "No WAS is connected to nginx"
exit 1
fi
echo "set \$service_url http://127.0.0.1:${TARGET_PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc
echo "Now Nginx proxies to ${TARGET_PORT}."
sudo service nginx reload
echo "Nginx reloaded."
- ํ์ฌ Nginx ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ํฌํธ๋ฅผ ์ค์ ํ๋ ํ์ผ์ธ /etc/nginx/conf.d/service-url.inc ํ์ผ์
TARGET_PORT
๋ก ์์ ํฉ๋๋ค.
sudo service nginx reload
: reload ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ Nginx ๊ฐ ์ค์ ํ์ผ๋ง ๋ค์ ๋ถ๋ฌ์ค๋๋ก ํฉ๋๋ค. restart ๋ช ๋ น์ด๋ ์๋ฒ๋ฅผ ๋ด๋ ธ๋ค๊ฐ ์ฌ์คํํ๋ ๋ฐ๋ฉด, reload ๋ช ๋ น์ด๋ ์ค์ ๋ง ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ์ ๋ ๋น ๋ฅด๊ฒ ๋์ํฉ๋๋ค.
๐ appspec.yml ์์ฑ
appspec.yml ํ์ผ์ AWS CodeDeploy ์์ ๋ฐฐํฌ๋ฅผ ๊ด๋ฆฌํ ๋ ์ฌ์ฉํ๋ ํ์ผ์ ๋๋ค.
์์์ ์์ฑํ 3๊ฐ์ง ์คํฌ๋ฆฝํธ๋ฅผ ์์๋๋ก ์คํํ ์ ์๋๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
appspec.yml
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/application
overwrite: yes
permissions:
- object: /home/ubuntu
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: run_new_was.sh
timeout: 180
runas: ubuntu
- location: health_check.sh
timeout: 180
runas: ubuntu
- location: switch.sh
timeout: 180
runas: ubuntu
- ์์ฑํ ์์๋๋ก ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
- ์คํฌ๋ฆฝํธ๊ฐ ์ฑ๊ณตํ ๊ฒฝ์ฐ์๋ง ๋ค์ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๊ณ ์คํจํ ๊ฒฝ์ฐ ๋ฐฐํฌ๋ ์คํจํฉ๋๋ค.
๐ Github Actions ์ํฌํ๋ก์ฐ ์์ฑ
์ ๋ง ๋ง์ง๋ง์ ๋๋ค!! ๐
Github Actions ์ํฌํ๋ก์ฐ๋ฅผ ์์ฑํด์ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ jobs ๊ฐ ์คํ๋๋๋ก ์์ฑํฉ๋๋ค.
.github/workflows/deploy.yml
name: deploy
on:
push:
branches: [ develop ]
env:
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: create secret files
working-directory: src/main/resources
run: |
touch application.yml
echo "${{ secrets.APPLICATION_YML }}" >> application.yml
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: '11'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
shell: bash
- name: Build with Gradle
run: ./gradlew build -x test
shell: bash
- name: Make zip file
run: zip -r ./code-deploy.zip ./build/libs/*.jar ./scripts/* -j ./appspec.yml
shell: bash
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./code-deploy.zip s3://$AWS_S3_BUCKET/code-deploy.zip
- name: Code Deploy
run: aws deploy create-deployment
--application-name codedeploy-application
--deployment-config-name CodeDeployDefault.OneAtATime
--deployment-group-name GROUP
--s3-location bucket=$AWS_S3_BUCKET,bundleType=zip,key=code-deploy.zip
on.push.branches
: ํน์ ๋ธ๋์น์ push ๊ฐ ๋ฐ์ํ์ ๋ ํด๋น ์ํฌํ๋ก์ฐ๊ฐ ๋์ํฉ๋๋ค. ์์ ๊ฐ์ ๊ฒฝ์ฐ์๋ develop ๋ธ๋์น์ push ๊ฐ ๋ฐ์ํ๋ฉด ์ํฌํ๋ก์ฐ๊ฐ ์คํ๋ฉ๋๋ค.
Make zip file
job : S3 ์ ์ ๋ก๋ ํด์ผํ ํ์ผ๋ค์ code-deploy.zip ์ด๋ผ๋ ํ์ผ๋ก ์์ถํ๋ ๊ณผ์ ์ ๋๋ค. ์๋ฒ๋ฅผ ์คํํ๊ธฐ ์ํด ํ์ํ ๋น๋๋ ํ๋ก์ ํธ ํ์ผ(./build/libs/*.jar), Code Deploy Agent ๊ฐ ์คํํ ์คํฌ๋ฆฝํธ ํ์ผ(./scripts/* -j), Code Deploy Agent ์ ๋ฐฐํฌ ๊ด๋ฆฌ ํ์ผ(./appspec.yml)์ ์์ถํฉ๋๋ค.
Upload to S3
job : ์์ถํ code-deploy.zip ํ์ผ์ S3 ์ ์ ๋ก๋ํฉ๋๋ค.
Code Deploy
job : Code Deploy Agent ๋ฅผ ์คํํฉ๋๋ค. S3 ์ ์ ๋ก๋๋ code-deploy.zip ํ์ผ์ EC2 ๋ก ๊ฐ์ ธ์์ ์์ถ์ ํด์ ํ๊ณ appspec.yml ํ์ผ์ ์ฐธ๊ณ ํ์ฌ ์์๋๋ก ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค.
๐คฉ ๊ฒฐ๊ณผ ํ์ธ
Current port of running WAS is 8082.
Kill WAS running at 8081.
Now new WAS runs at 8081.
Start health check of WAS at 'http://127.0.0.1:8081' ...
#1 trying...
#2 trying...
#3 trying...
New WAS successfully running
Nginx currently proxies to 8082.
Now Nginx proxies to 8081.
Nginx reloaded.
Github Actions ์ AWS CodeDeploy ๊ฐ ์ฑ๊ณตํ๋ฉด ์๋ก์ด ์๋ฒ๊ฐ ๋ฐฐํฌ๋ ํ์ Nginx ๊ฐ reload ๋์ด ํธ๋ํฝ์ ์ ํํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
$ ps -ef | grep java
ubuntu 5516 1 10 16:23 ? 00:00:21 java -jar -Dserver.port=8082 /home/ubuntu/application/application.jar
ubuntu 5692 1 26 16:25 ? 00:00:22 java -jar -Dserver.port=8081 /home/ubuntu/application/application.jar
Blue/Green ๋ฐฐํฌ ์ ๋ต์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ด ์ ๋ฒ์ ๊ณผ ๊ตฌ๋ฒ์ ์ ์๋ฒ๊ฐ ์คํ๋๋ ์ํ๊ฐ ์ ์ง๋ฉ๋๋ค.
์ ๋ฒ์ ์ ํฌํธ๋ฅผ ํ์ธํ๊ธฐ ์ํด์๋ ํ์ฌ Nginx ๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ํฌํธ๋ฅผ service-url.inc ํ์ผ์์ ํ์ธํ๋ฉด ๋ฉ๋๋ค.
์ ๋ฒ์ ๊ณผ ๊ตฌ๋ฒ์ ์ด ์คํ์ค์ด๊ธฐ ๋๋ฌธ์ ์ป์ ์ ์๋ ์ด์ ์ด ์์ต๋๋ค.
Blue/Green ๋ฐฐํฌ ์ ๋ต์ ๋ํ์ ์ธ ์ฅ์ ์ด๋ผ๊ณ ๋ ํ ์ ์๋๋ฐ, ๋ง์ฝ ์๋กญ๊ฒ ๋ฐฐํฌํ ์๋ฒ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ฉด ๋น ๋ฅด๊ฒ service-url.inc ํ์ผ์์ ํฌํธ๋ง ์์ ํ ํ Nginx ๋ฅผ reload ํ์ฌ ๋ค์ ๊ตฌ๋ฒ์ ์ ์๋ฒ๋ฅผ ์ฌ์ฉํ๋๋ก ํ ์ ์์ต๋๋ค.
'โจ ๋ฐ๋ธ์ต์ค: DevOps' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Redis ์ฃผ์ ํน์ง ์ ๋ฆฌ (0) | 2023.07.31 |
---|---|
Kafka ๊ฐ๋ ์ ๋ฆฌ (Pub/Sub ๋ชจ๋ธ, Zookeeper, Broker, Topic, Partition, Offset, Producer, Consumer) (0) | 2023.06.22 |
Github Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ CI/CD - Node.js(2) (0) | 2023.01.01 |
Github Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ CI/CD - Node.js(1) (0) | 2023.01.01 |