์ด๋ฒ๊ธ์์๋ ์ง๋๋ฒ๊น์ง ๊ตฌ์ถํ ECS ํ๊ฒฝ์์, ์ค๋ฅ ๋ฐ์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ ์ผ๋ก ๋กค๋ฐฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
ํนํ GitHub Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ์ฌ ์๋ํ๋ ๋ฐฐํฌ ๋ฐ ๋กค๋ฐฑ ํ๋ก์ธ์ค๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฌ์ผ๋ก ์ค๋ช ๋๋ฆด ์์ ์ ๋๋ค.
ํํ๋ก์ด ์ ๊ธฐ ๋ฐฐํฌ์ ๋ , ๋ ๊ทธ๋ฌ๋ฏ ๋ฐฐํฌ ๋ฒํผ์ ๋๋ฅด๊ณ ์ปคํผ ํ ์์ ์ฌ์ ๋ฅผ ์ฆ๊ธฐ๋ฉฐ ๋ฐฐํฌ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ ธ์ต๋๋ค.
์ปคํผ๋ฅผ ๋ค ๋ง์๊ณ ๋์์ผ ๋ฐฐํฌ ์๋ฃ ๋ฉ์์ง๋ฅผ ํ์ธํ๋ฉฐ "์ค๋๋ ๋ฌด์ฌํ ๋์ด๊ฐ๊ตฌ๋"๋ผ๋ ์๋์ ํ์จ์ ๋ด์ฌ์์ต๋๋ค.๊ทธ๋ฌ๋ ์ฝ 2์๊ฐ ํ, ํ ๊ณ ๊ฐ์ผ๋ก๋ถํฐ "ํน์ ๊ธฐ๋ฅ ์ฌ์ฉ ์ ํ์ด์ง๊ฐ ๋ค์ด๋๋ค"๋ ์ ๊ณ ๊ฐ ์ ์๋์์ต๋๋ค.
ํด๋น ๊ธฐ๋ฅ์ ๋น์ผ ์๋กญ๊ฒ ๋ฐฐํฌ๋ ๊ฒ์ผ๋ก, ์ํฉ์ ์ฌ๊ฐ์ฑ์ ๋ํ์ต๋๋ค.๋ฌธ์ ์ ์์ธ์ ์กฐ์ฌํ ๊ฒฐ๊ณผ, ๋ฐฑ์๋์ ์ฌ์ ์ ํ์ํ API ๋ฐฐํฌ ์ผ์ ์ด ๋ด๋ถ ์ปค๋ฎค๋์ผ์ด์ ์ค๋ฅ๋ก ์ธํด ์งํ๋์ง ์์ ์ํ์์ ํ์ธํ ์ ์์์ต๋๋ค.
๋ฐฑ์๋์์๋ ์์ง ๊ฐ๋ฐ์ด ์งํ ์ค์ด์์ผ๋, ํ๋ก ํธ์๋์์๋ ์ด๋ฏธ ๋ฐฐํฌ๋ ์ํฉ์ด์๊ธฐ์ ๊ธด๊ธํ๊ฒ ๋กค๋ฐฑ์ ๊ฒฐ์ ํ๊ฒ ๋์์ต๋๋ค.๋ฐฐํฌํ๋ ๋ธ๋์น๋ฅผ ์ฌํ์ธํ๊ณ ๋น๋๋ถํฐ ๋ฐฐํฌ๊น์ง ์งํํ๋ ๋ฐ ์ด 30๋ถ์ด ์์๋์์ต๋๋ค.
๋น๋ก ๋น์ฅ์ ์๊ธฐ๋ ํด์๋์์ผ๋, ์ด๋ฌํ ์ํฉ์ด ์ฌ๋ฐ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ๋ณด๋ค ์ ์ํ๊ณ ํจ์จ์ ์ผ๋ก ๋์ํ ์ ์๋ ์์คํ ์ ํ์์ฑ์ ์ ์คํ ๋๋ผ๊ฒ ๋์์ต๋๋ค.
์ด์ ๋ฐ๋ผ, ๋กค๋ฐฑ ์์คํ ์ ๊ฐ์ ์ ๊ฒฐ์ฌํ๊ฒ ๋์์ต๋๋ค.
ํ์ํ ๋ฐฐํฌ ๋ฒ์ ์ ์ ๋ฐ ๊ฒฐ์
โป ํนํ 2๋ฒ๊ณผ 3๋ฒ ๋จ๊ณ์์๋ ์์ ์๊ฐ์ด ๋ง๊ณ , ์ค์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ๋ ์์์ ์ ๋ ํด์ผ ํฉ๋๋ค.
๋น๋ ๋ฐ ๋ฐฐํฌ
esc ์ code deploy ๊ฐ ์ฐ๋ ๋์ด ์์ผ๋ฉด task definition์ ์๋ก ๋ง๋ค์ด ์ฌ๋ฆฌ๋ฉด ํด๋น ํ ์คํฌ๋ฅผ ์๋ก ์ํ ํฉ๋๋ค.
์ด๋ฅผ ์ด์ฉํ์ฌ ๋กค๋ฐฑ์ ๊ตฌํ ํฉ๋๋ค.
ํจ์จ์ ์ธ ๋ฒ์ ์ ์ ๋ฐ ๋กค๋ฐฑ ์ ์ฐจ
๋ฐฐํฌ ์๊ฐ ๋จ์ถ
๋ฌธ์ ๋ฐ์ ์ ๋น ๋ฅธ ๋์ฒ
ํจ์จ์ ์ธ ๋ฒ์ ์ ์ ๋ฐ ๋กค๋ฐฑ ์ ์ฐจ
๋ฒ์ ๊ด๋ฆฌ ์์คํ ๊ฐ์
๋ฐฐํฌ ํ๊ธฐ ์ ์ ๋ ธ์ ์ ๋ฐฐํฌ ํธ๋ ์ปค์ ๋ด์ฉ๊ณผ ๋ฒ์ ์ ์ ์ด ๋ด์ฉ์ ๋ฐ๋ก ํ์ธ ํ๋๋ก ํ๊ธฐ
๋ฐฐํฌ ์ package.json์ ์๋ versoin์ ์ฌ์ฉํด ecr์ ํด๋น ๋ฒ์ ๊ณผ latest๋ฅผ ๋๋ค push ํ๋ค.
- name: 'VERSION ์ถ์ถ ๋ฐ ๊ฒ์ฆ'
id: set-version
run: |
# package.json์์ version ์ถ์ถ
VERSION=$(jq -r '.version' apps/web1/package.json)
VERSION="v${VERSION}"
# ๋ฒ์ ๊ฐ์ด ์ฌ๋ฐ๋ฅธ์ง ๊ฒ์ฆ
if [[ ! $VERSION =~ ^v[0-9a-zA-Z._-]+$ ]]; then
echo "์ ํจํ์ง ์์ ๋ฒ์ ํ์์
๋๋ค: $VERSION"
exit 1
fi
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "ํ์ ๋ ๋ฒ์ : $VERSION"
- name: '๋์ปค ์ด๋ฏธ์ง ๋น๋ & ECR ํธ์ฌ '
id: build-image
run: |
DOCKER_BUILDKIT=1 docker build \
docker build
docker tag ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:latest ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:${{ env.VERSION }}
docker push ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:${{ env.VERSION }}
docker push ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:latest
๋ฒ์ ์กฐํ ์๋ํ
workflow_dispatch:
inputs:
version:
description: '๋ฒ์ ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์ ex) v1.0.0'
required: true
default: 'latest'
- name: 'ECR image tag ํ์ธ'
run: |
aws ecr describe-images \
--repository-name web1 \
--image-ids imageTag=${{ env.VERSION }} \
>/dev/null 2>&1 && echo "Image found" || { echo "Image not found"; exit 1; }
๋กค๋ฐฑ ์ ์ฐจ ์ต์ ํ
- name: 'task-definition ์
๋ฐ์ดํธ'
run: |
sed -i -e 's|\(web1\)"|\1:${{ env.VERSION }}"|g' \
-e 's|\(web1\)"|\1:${{ env.VERSION }}"|g' \
./deploy/ops/web1/task-definition.json
- name: '[ROLLBACK] ECS ๋กค๋ฐฑ ๋ฐฐํฌ'
run: |
aws ecs deploy \
--task-definition ./deploy/ops/web1/task-definition.json \
~~ ๋๋จธ์ง arg
๋ฌธ์ํ๋ ๊ธ์ ํ์ธํ์ฌ ๋ฐฐํฌ ํ๋ฏ๋ก ์ฝ๋๋ฅผ ๋ณด๊ณ ๋ด์ฉ์ ํ์ธ ์ ํด๋ ๋๋ฉฐ
์ด๋ฏธ ecr์ ๋ฑ๋ก๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฌ์ฉํจ์ผ๋ก ๋น๋ ์๊ฐ์ ์ค์ผ ์ ์์ต๋๋ค.
๊ทธ๋์ ๋ฐฐํฌ ์๊ฐ(3๋ถ)๋ง ์์ผ๋ฉด ์์ ์ ์ธ ๋กค๋ฐฑ์ ์ํ ํ ์ ์์ต๋๋ค. ์ฌ์ง์ด ํน์ ๊ฐ๋ฐ์์๊ฒ ์์กดํ์ง ์๊ณ ๋๊ตฌ๋ ๋กค๋ฐฑ์ ์ํ ํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ด์ ๋ค์ ๋ง์ ๋๊ณ ํ ์คํฌ๋ฅผ ์ํํ๋ฌ ๊ฐ ์ ์๊ฒ ๋์์ต๋๋ค.(์ ๋ง?)
์ ํฌ ์๋น์ค ์ฝ๋๋ ๋ชจ๋ ธ๋ ํฌ๋ก ๊ตฌ์ฑ๋์ด ์์ด tag๋ฅผ ํ์ฉํ ๋ฒ์ ๊ด๋ฆฌ ์๋ํ๊ฐ ์ด๋ ค์ด ์ํฉ์ ๋๋ค. ์ด๋ก ์ธํด ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฌ์ ํ ์๋์ผ๋ก ์ํํด์ผ ํ๋ค๋ ์ ์ด ์์ฝ์ต๋๋ค.
ํน์ ์ด ๊ธ์ ์ฝ๋ ๋ ์๋ถ๋ค ์ค์ ํด๋น ๋ฌธ์ ๋ฅผ ๊ฒช์ผ์๊ฑฐ๋ ํด๊ฒฐ์ฑ ์ ์์๋ ๋ถ์ ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค.
์ด๋ฒ ๊ฐ์ ์์
์ ํตํด ๋ฐฐํฌ ํ๋ก์ธ์ค์ ํจ์จ์ฑ๊ณผ ์์ ์ฑ์ด ํฌ๊ฒ ํฅ์๋์์ต๋๋ค. ํนํ, ECR ์ด๋ฏธ์ง์ ์ฌํ์ฉ๊ณผ ์๋ํ๋ ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ํตํด ๋น๋ ๋ฐ ๋กค๋ฐฑ ์๊ฐ์ ๋จ์ถํ ์ ์์๋
์ ์ด ๋ง์กฑ์ค๋ฝ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ๋๊ตฌ๋ ์ฝ๊ฒ ๋กค๋ฐฑ์ ์ํํ ์ ์๋๋ก ์์คํ
์ ๊ฐ์ํํ ๊ฒ์ด ์ด๋ฒ ์์
์ ํฐ ์ฑ๊ณผ ์ค ํ๋์์ต๋๋ค.
๋ค๋ง, ๋ชจ๋
ธ๋ ํฌ ๊ตฌ์กฐ๋ก ์ธํด ํ๊ทธ ๊ธฐ๋ฐ ๋ฒ์ ๊ด๋ฆฌ ์๋ํ๊ฐ ์ด๋ ค์ด ์ ์ ์ฌ์ ํ ์์ ๋ก ๋จ์ ์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ถ๊ฐ์ ์ธ ์ฐ๊ตฌ์ ๋
ธ๋ ฅ์ด ํ์ํ๋ฉฐ, ์์ผ๋ก๋ ๊ณ์ํด์ ๊ฐ์ ์์
์ ์งํํด์ผ ํ๋ค๊ณ ๋๊ผ์ต๋๋ค.
์ ๋ ์์ ์ QA์์ ๋ฏธ์ฒ ์ก์ง๋ชปํ ๋ฒ๊ทธ๊ฐ ํ๋ฌ๋์ ์์ ๋ฐ๊ฒฌ๋ผ์ ๊ธํ๊ฒ ๋กค๋ฐฑํ๋ค ์์๋๋ฌ๋ ๊ฒฝํ์ด ์๋๋ฐ ํ์คํ ์ด๋ ๊ฒ ๋กค๋ฐฑํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ์ก์๋์ผ๋ฉด ๋์ค์ ์ ์ฉํ๊ฒ ๋ค์ ์ข์ ๊ธ ๊ฐ์ฌํฉ๋๋ค ๐
์ค๋ฌด์์ ์ค์ ๋ก ๊ฒช์ผ์ ๋ฌธ์ ์ํฉ๊ณผ ๊ทธ์ ๋ํ ํด๊ฒฐ ๊ณผ์ ์ ํ์ค๊ฐ ์๊ฒ ์ ๋ด์์ฃผ์
์ ์ ๋ง ์ธ์ ๊น์์ต๋๋ค.
์์ง ์ ๋ ์ง์ ๊ฒฝํํด๋ณธ ์ ์ ์์ง๋ง, ๊ธ์ ์ฝ์ผ๋ฉด์ ๋์ค์ ๋น์ทํ ์ํฉ์ด ์๊ฒผ์ ๋ ์ด๋ค ์ ๋ค์ ๋ฏธ๋ฆฌ ๊ณ ๋ คํด์ผ ํ ์ง ๋ง์ด ๋ฐฐ์ธ ์ ์์์ต๋๋ค. ์ข์ ๊ธ ๊ฐ์ฌํฉ๋๋ค!
๋ฌธ์ ์ํฉ์ ์์ํ๊ฒ ์ค๋ช
ํด์ฃผ์ ํ๋กค๋ก๊ทธ๊ฐ ํนํ ์ธ์์ ์ด์์ด์. "ํํ๋ก์ด ๋ฐฐํฌ๋ " ์ฌ๋ฐ์์ต๋๋ค ใ
ใ
ใ
ใ
๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฌ์ ํ ์๋์ผ๋ก ์ํํ๋ค๋๊ฒ์ ๋ํด์ ์ด๋ป๊ฒํ๋ฉด ํธํ๊ฒ ๋๋๋ฆด์ ์์์ง์๋ํ ๊ณ ๋ฏผ์ ์ ๋ ํจ๊ป ํด๋ณด๊ฒ ์ต๋๋ค ๋์ค์ ๊ด๋ จ ๋ด์ฉ์ผ๋ก ๊ฐ์ด ๋ํ๋๋๋ฉด ์ข๊ฒ ์ต๋๋ค. ์ ์ฝ์์ต๋๋ค :)
์๊ธฐ ์ํฉ์ ๊ณ๊ธฐ๋ก ์ค์ ์ด์ ํ๊ฒฝ์ ๋ง๋ ์๋ํ๋ ๋กค๋ฐฑ ์์คํ ์ ๊ตฌ์ถํ์ ๊ณผ์ ์ด ์ธ์ ๊น์์ต๋๋ค ใ ใ ๋๊ตฌ๋ 3๋ถ ๋ง์ ๋กค๋ฐฑํ ์ ์๋๋ก ๋ง๋ ์ค์ฉ์ ์ธ ์ ๊ทผ์ด ์ ๋ง ๋ฉ์ง๋ค์ฉ !!! ๋์ค์ ์ด๋ ๊ฒ ๋กค๋ฐฑํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ์ก์๋์ ์ ์๋๋ก ์ ์ฉํ๊ฒ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค bb
๋ฌธ์ ์ค๋ช ์ ์ฝ์ผ๋ฉด์ ๋ง์น ๊ทธ ์๊ฐ์ ์๋๋ฏํ ๋๋์ ๋ฐ์์ต๋๋ค๐
๋จ์ํ ๋ฌธ์ ํด๊ฒฐ ํ ๋!์ด ์๋๋ผ ํด๊ฒฐ ๊ณผ์ ์์ ๋๊ผ๋ ๋ถํธํจ์ ๊ฐ์ ํ๊ธฐ ์ํด ๊ฐ์ ๋ชฉํ๋ถํฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๊น์ง ๋์ถํด๋ธ ๋ถ๋ถ์ด ์ธ์๊น์์ต๋๋ค :) ์ข์ ๊ธ ๊ฐ์ฌํฉ๋๋ค!