์ ๋ฒ ๊ธ์ ๋ด์ฉ์ด ๊ธธ์ด์ง์ ๋ฐ๋ผ, ๋๋์ด์ ๊ธ์ ์์ฑํ๋ค.
๊ธฐ์กด ๊ธ์ ๋ง์ง๋ง ๋ถ๋ถ์ ์ต์ข CICD ํ์ผ์ ๋ํ ๊ฒฐ๊ณผ๋ฌผ์ ์์ฑํ๊ณ ๋์ด ๋ฌ๋ค.
name: Continuous Integration and Deployment
on:
pull_request:
branches:
- develop
types: [closed]
jobs:
### step 1. code integration check
CI:
runs-on: self-hosted
if: github.event.pull_request.merged == true
env:
BRANCH: develop
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ env.BRANCH }}
token: ${{ secrets.ACCESS_TOKEN }}
- name: Set node environment
uses: actions/setup-node@v4
with:
node-version: 20.11.1 # see .nvmrc
- name: Caching Primes # for this case, node_modules
id: cache-primes
uses: actions/cache@v4
with:
path: node_modules
key: npm-packages-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies if no cache
if: steps.cache-primes.outputs.cache-hit != 'true'
run: npm install
- run: npm run check:lint
- run: npm run check:type
### step 2. publish code to external environment
CD:
needs: CI # If CI is done, then do CD
runs-on: self-hosted
steps:
- name: AWS credential
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # IAM access key
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # IAM access
aws-region: ${{ secrets.AWS_REGION }}
# 1. ECR
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2 # result : registry (ECR repo uri)
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REPO_URI: ${{ steps.login-ecr.outputs.registry }}
ECR_REPO_NAME: ${{ secrets.ECR_REPO_NAME }}
IMAGE_TAG: ${{ github.sha }}
run: |
IMAGE_NAME='${{ env.ECR_REPO_URI }}/${{ env.ECR_REPO_NAME }}:${{ env.IMAGE_TAG }}'
docker build -t ${IMAGE_NAME} .
docker push ${IMAGE_NAME}
docker system prune --volumes -a -f
echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT
# 2. ECS
# https://fig.io/manual/aws/ecs/describe-task-definition
- name: Generate task-definition.json from latest active ECS task definition
run: |
aws ecs describe-task-definition \
--task-definition ${{ secrets.ECS_TASK_DEFINITION }} \
--query taskDefinition \
> task-definition.json
- name: Render Amazon ECS task definition
id: render-task-definition
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
# this step exports the task-definition as an output automatically (used from next step)
task-definition: task-definition.json
container-name: ${{ secrets.ECS_TASK_CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-task-definition.outputs.task-definition }}
service: ${{ secrets.ECS_SERVICE }}
cluster: ${{ secrets.ECS_CLUSTER }}
wait-for-service-stability: true
CI๋ ์ฌ์ค์ lint์ type ์ฒดํฌ๋ฅผ ํ๋ ๊ฒ์ ๋ถ๊ณผํด์ ํน๋ณํ ๋ด์ฉ์ ์์ง๋ง, CD ๋ถ๋ถ์ ์๋ฌด๋๋ composite action์ด ๋ง๋ค๋ณด๋, ๊ฐ๊ฐ์ ์ก์ ๋ค์ด ์ค๋ช ํ๋ ์กฐ๊ฑด๋ค์ ์ ์ดํดํด์ผ ํ๋ค.
์ฐ์ ๋๋ ECR ๋ฐ ECS๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ์๋ค.
AWS์ ๋ํ ์ค๋ช ์ ์ ๊ธฐ์๋ ๋๋ ์์ง ๊ณต๋ถ๊ฐ ๋ถ์กฑํ๊ธฐ์ ๊ทธ๋ฅ ํ์ํ ํต์ฌ๋ง ์ค๋ช ์ผ๋ก ๋จ๊ฒจ๋๋๋ค.
์ฐธ๊ณ ๋ก, ์ ๋ ๊ฒ ํ ํ์ผ๋ก ์ ๋ ฅํ์ง ์๊ณ ๋น์ฐํ CIํ์ผ, CD ํ์ผ์ ๋ถ๋ฆฌํด์ ์์ฑํ๋ ๊ฒ์ด ๋ซ๋ค. ์ ๋ด์ฉ์ ํ ์คํธ๋ฅผ ์ํด์ ํ ํ์ผ์ ๋ค ์์ฑํ ๋ฒ์ ์ด๋ค.
๊ฐ์ธ์ ์ผ๋ก ๋์ปค๋ฅผ ํตํ ํ๋ก ํธ์๋ ๋ฐฐํฌ์ ๋ํด ๊ฐ์ธ์ ์ผ๋ก ๋๋ผ๋ ์์ฌ์ด ์ ์ด ์ข ์์ด์ nginx๋ฅผ ํตํ ๋ฌด์ค๋จ ๋ฐฐํฌ๋ฅผ ๊ตฌํํ์๊ณ , ์ด์ ๋ํด์ ๋ค์๊ธ์ ๊ธฐ์ ํด๋๋ค.
์ด ๊ธฐ๋ก์ ๋์ค์ ๋์ปค๋ฅผ ํตํด ๋ฐฐํฌํด์ผ ํ๋ ๊ฐ๋ฐ ํ๊ฒฝ์ผ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด์ ๋ฌธ์ํํ๋ ๋ด์ฉ์ด๋ค.
1. AWS credential
steps:
- name: AWS credential
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # IAM access key
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # IAM secret key
aws-region: ${{ secrets.AWS_REGION }}
์ฐ์ AWS์ ์ ๊ทผํ์ฌ ์์
์ ํ๊ธฐ ์ํด์๋ credential์ ์ป์ด์ผ ํ๋ค.
region์ ์ด๋ ค์ธ ๊ฒ ์์ํ
๋ฐ, access key๋ secret access key๋ ์ด๋์ ์ป๋์ง ์ฒ์ํ๋ ์ฌ๋์ ์์ํ ๊ฒ์ด๋ค.
์ด credential์ ์ป๊ธฐ ์ํ access,key์ secret key๋ ์๋์ ๊ฐ์ ์ฅ์์์ ์ป์ ์ ์๋ค. ( ์ด๋ฏธ ๋ฐฑ์๋ ๋ถ๋ค์๊ฒ IAM ๊ณ์ ์ ๋ถ์ฌ๋ฐ์๋ค๋ ์ ์ ํ์์ ์์ฑํ๋ค)
2. ECR login and push image to ECR
# 1. ECR
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2 # result : registry (ECR repo uri)
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REPO_URI: ${{ steps.login-ecr.outputs.registry }}
ECR_REPO_NAME: ${{ secrets.ECR_REPO_NAME }}
IMAGE_TAG: ${{ github.sha }}
run: |
IMAGE_NAME='${{ env.ECR_REPO_URI }}/${{ env.ECR_REPO_NAME }}:${{ env.IMAGE_TAG }}'
docker build -t ${IMAGE_NAME} .
docker push ${IMAGE_NAME}
docker system prune --volumes -a -f
echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT
ECR์ด๋ผ๋ ๊ฒ์ ๋๋ ์ด๋ฒ์ ์ฒ์ ๋ค์ด๋ดค๋ค. ๊ทธ๋ฐ๋ฐ ์๊ฐ๋ณด๋ค ์ด๋ ค์ด ๊ฐ๋ ์ ์๋๊ณ ๊ทธ๋ฅ ๋น๋๋ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํด์ ECS์ ์๋ฃ(?) ๋ก ์ฐ์ด๊ธฐ ์ํ S3๊ฐ์ ์ ์ฅ์๋ผ๊ณ ์ฌ๊ธฐ๋ฉด ๊ฐ์ฅ ์ดํดํ๊ธฐ ์ฌ์ ๋ค.
์ฐ์ ๊ฒ์์ฐฝ์ ecr์ ์
๋ ฅํ์ฌ ์๋์ ๋ณด์ด๋ ํ๋ผ์ด๋น ECR ๋ ์ง์คํธ๋ฆฌ๋ฅผ ํด๋ฆญํ๋ค.
์ดํ, ์์ ํญ์์ "Repositories"๋ฅผ ํด๋ฆญํ ๋ค, ๋ ํฌ์งํ ๋ฆฌ ์์ฑ์ ํด๋ฆญํด์ ์์ฑํ๋ฉด ๋๋ค. ์์ฑํญ์ ์๋ UI ์ ๋ ฅ๋ด์ฉ์ ๋ชน์ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ์๋ตํ๋ค.
์์ฑ ํ ๋ง๋ค์ด์ง๋ ์ ๋ ํญ ์ค์ ๋๋ฒ์งธ๊ฐ ๋ฐ๋ก git action secret์ ECR_REPO_NAME์ผ๋ก ๋ค์ด๊ฐ์ผ ํ๋ ๊ฐ์ด ๋๋ค. ( ECR_REPO_URI ๋ git action step์์ ECR๋ก ๋ก๊ทธ์ธํ๋ ์๊ฐ ์๋์ผ๋ก ๋ฐ์์์ง )
ECR_REPO_URI๋ ์ถํ ECS์ ์์ ์ ์๋ฅผ ์์ฑํ ๋ ์ฌ์ฉ๋์ผ ํ๋ฏ๋ก ๋ฏธ๋ฆฌ ๋ณต์ฌํด๋์.
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REPO_URI: ${{ steps.login-ecr.outputs.registry }} <-- ์๊ธฐ
ECR_REPO_NAME: ${{ secrets.ECR_REPO_NAME }} <-- ์๊ธฐ
IMAGE_TAG: ${{ github.sha }} # automatically generated
run: |
IMAGE_NAME='${{ env.ECR_REPO_URI }}/${{ env.ECR_REPO_NAME }}:${{ env.IMAGE_TAG }}'
docker build -t ${IMAGE_NAME} .
docker push ${IMAGE_NAME}
docker system prune --volumes -a -f
echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT
์ดํ run์ ํด๋นํ๋ ๋ถ๋ถ์ ๋จ์ํ docker ์ด๋ฏธ์ง ์์ฑ ํ ์ด๋ฅผ pushํ๋ ๊ณผ์ ์ด ๋ค์ด๊ฐ์๋ค.
IMAGE_NAME์ ์์๋ฆฌ์ REPO_URI๊ฐ ์์ผ๋ฏ๋ก, docker build๋ฅผ ํตํด ๋ง๋ค์ด์ง๋ ์ด๋ฏธ์ง๋ ์ด URI๋ก push๋๊ฒ ๋๋ค.
์ดํ, ๋ด MAC OS์๋ ๋น๋ํ๋ฉด์ ๋์ปค ์ค๋ฒ๋ ์ด๊ฐ ์์ฑ๋๊ฒ ๋๋ค. ์ด ์ค๋ฒ๋ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ๋ ์ด์ด ๊ฐ๋ ์ฒ๋ผ ๋ง๋ค์ด ์์๊ฐ๋ ๋์ปค์ ํน์ฑ์, ๋ถํ์ํ ๋ ์ด์ด๋ฅผ ์ฌ์์ฐํ์ง ์๋๋ก ์บ์ฑํ๊ฒ ๋๋๋ฐ, ์ด๊ฒ์ด ์ฉ๋์ด ์๋นํ ํธ์ด๋ผ ๋น๋๋ฅผ ํ ๋๋ง๋ค ๊ณ์ ์๊ธฐ๊ธฐ ๋๋ฌธ์ ์ง์์ค์ผ ํ๋ค.
ํนํ, ์ฉ๋์ด ํ์ ์ ์ธ EC2๋ฅผ ์ฌ์ฉํ๊ณ ์์ ๊ฒฝ์ฐ, ์ด ์์์ ๋์ปค๋ก ๋น๋ํ๋ฉด ์ค๋ฒ๋ ์ด๊ฐ ๊ณ์ ์์ฌ์ ๋์ค์๊ฐ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ถ์กฑ์ผ๋ก EC2๊ฐ ๋ฉ์ถฐ๋ฒ๋ฆฌ๋ ์ผ๊น์ง ์ผ์ด๋๋ ์ ๊ด๋ฆฌํด์ค์ผ ํ๋ค.
๊ทธ ๋ช
๋ น์ด๊ฐ run ํํธ์์ ๋ฐ์์ ๋๋ฒ์งธ์ค์ธ docker system prune --volumes -a -f
์ ํด๋นํ๋ค.
๋ณผ๋ฅจ ๋ฐ, ์ฌ์ฉํ์ง ์๋ ์ด๋ฏธ์ง ์ปจํ
์ด๋ ๋คํธ์ํฌ ๋ฑ์ ๋ฐ์ด๋ฒ๋ฆฐ๋ค.
์ฐธ๊ณ ๋ก, run์ ๋ง์ง๋ง์ค์ธ
echo ... >> $GITHUB_OUTPUT
๋ฌธ๋ฒ์ git action์์ ์ ๊ณตํ๋ ๋ฌธ๋ฒ์ผ๋ก, ์ ๋ ๊ฒ ํ ์คํญ์์ export ๋๋ ๊ฐ์ ๋ค๋ฅธ step์์ ${{ steps.์คํญ ์์ด๋.outputs.image }} ์ด๋ฐ์์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค.
IMAGE_TAG: ${{ github.sha }} ์ด๋ฏธ์ง ํ๊ทธ๋ ๋ฌด์กฐ๊ฑด github์ด ์ ๊ณตํด์ฃผ๋ ํด์ฑ๋ ๊ฐ์ ์ฌ์ฉํ์ฌ ๊ธฐ์กด์ ์ด๋ฏธ์ง์ ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ค์ ํด์ค์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๋ฐฐํฌ๋ฅผ ํ์์๋ ๋ถ๊ตฌํ๊ณ ์๋ก์ด ECR์ ์ด๋ฏธ์ง๊ฐ ECS์์ ๋ฐฐํฌ๋์ง ์๋ ์ํฉ์ ๋ณด๊ฒ ๋ ๊ฒ์ด๋ค. ์ด๋ด ๊ฒฝ์ฐ ์ง์ ECS์ ๋ค์ด๊ฐ์ ๋ฒ์ ์ ๋ฐ๊ฟ์ค์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์๊ธด๋ค.
3. ECS deployment
๋ฐฉ๊ธ ์ ECR์ด AWS์ ์ด๋ฏธ์ง ํ๋ธ์ ๊ฐ์ ์ญํ ์ ํ๋ค๋ฉด, ECS๋ ์ด ์ด๋ฏธ์ง๋ฅผ ์ด์ฉํด์ ์ ํด์ง ๋ฐฐํฌ์ ๋ต (๋กค๋ง or ๋ธ๋ฃจ๊ทธ๋ฆฐ) ์ ๋ฐ๋ผ ์ปจํ ์ด๋๋ฅผ ๋์์ฃผ๋ ์ญํ ์ ํ๋ค.
์ด ECS๊ฐ ์กฐ๊ธ ๊ฑด๋ค๊ฒ ๋ง์์๋ค. (๋ก๋๋ฐธ๋ฐ์, ํ๊ฒ๊ทธ๋ฃน ๋ฑ๋ฑ)
์ฐ์ , ๋ง์ฝ ํ ๋ด์ ์ด๋ฏธ ์ฌ์ฉ์ค์ธ ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ์๋ค๋ฉด ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ณ , ์๋ค๋ฉด ๋จผ์ ์ฐ์ ์ ์ผ๋ก ๋ง๋ค์ด์ค์ผ ํ๋ค.
๊ทธ ์ด์ ๋ ๋์ค์ ํ์ธํด๋ณด๋ฉด ์๊ฒ ์ง๋ง ECS ์์ฒด๋ง์ผ๋ก๋ EC2์ฒ๋ผ ํผ๋ธ๋ฆญ DNS ๊ฐ์๊ฒ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ์ ๋์ปค ์ด๋ฏธ์ง๊ฐ ๋ฐฐํฌ๋ ECS์ ์ ๊ทผํ๋ ค๋ฉด ๋ก๋๋ฐธ๋ฐ์์ ์ฎ์ด ์ ๊ทผํ๋ ๋ฐฉ์์ ์ทจํด์ผ ํ๋ค. (๊ทธ๋ฆฌ๊ณ ์ฌ์ค EC2์ ๋ฐฐํฌํ ๋์๋ ๋น์ฐํ๊ฒ ์ง๋ง ๋ก๋๋ฐธ๋ฐ์๋ ํ์ํ๋ค. ํฌํธํฌ์๋ฉ์ ์ํด์๋ผ๋, ๋คํธ์ํฌ ์์ฒญ ๋ถ์ฐ ๋ฐ https ์ ์ฉ์ ์ํด์๋ผ๋ ...)
AWS๊ฐ ์ต์ํ ์ฌ๋๋ค์๊ฒ๋ ๋ก๋๋ฐธ๋ฐ์์ ์๋์๋ฆฌ๋ฅผ ๊ตณ์ด ์๊ฐ ์ํด๋ ๋๊ฒ ์ง๋ง, ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ํ์ํ ์ด์ ์ ๋ํด์ nginx๋ฅผ ๋ง์ง์ํ๋ค๊ฐ ๊นจ๋ซ๋ ์๊ฐ์ด ์์์ด์ ์ ๋ฆฌํ ๊ฒธ ๋จ๊ฒจ๋ณธ๋ค.
Nginx๋, ํ๋ง๋๋ก ๋งํด์ ์น ์๋ฒ์ด๋ค.
์ด ์น ์๋ฒ๋ ์ธ์คํด์ค ๋ด์์ ์น ์ดํ๋ฆฌ์ผ์ด์ ์๋ฒ(WAS) ๋ค์๊ฒ ์ค๋ ์์ฒญ์ ๋์ ์์ ํ์ฌ ์ด๋ฅผ ๋ชฉํํ๋ ์๋ฒ์๊ฒ ์ ๋ฌํ๊ณ , ์ฌ๊ธฐ์ ์ค๋ ์๋ต์ ๋ค์ ๋คํธ์ํฌ๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌํด์ฃผ๋ ์ญํ ์ ์ฃผ ๋ชฉ์ ์ผ๋ก ํ๋ค.
(์ถํ nginx๋ฅผ ํตํ ๋ฌด์ค๋จ ๋ฐฐํฌ์ ๋ํด์ ์์ฑํ ์์ ์ด๋ผ ์ฌ๊ธฐ์๋ ์ด์ ๋๋ง ์๊ฐํ๊ฒ ๋ค)
nginx์ ๊ฐ์ด ํ๋ก์ ์๋ฒ๊ฐ ์ค๊ฐ์์ ์์ฒญ์ ๋ถ๋ฐฐํด์ค ๊ฒฝ์ฐ, ํ๋์ ์๋ฒ์ ๊ณผ์ค๋๊ฒ ์์ฒญ์ด ๊ฐ์ง ์๊ณ ์ ์ ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์์ ์ ์ ์์์ผ์ค ์ ์๊ณ , ์บ์ฑ ๋ฐ ์ํธํ์ ๊ฐ์ ์ฅ์ ๋ค๋ ์กด์ฌํ๋ค.
์ฌํผ, ๋ก๋๋ฐธ๋ฐ์ฑ์ ๋ํ ์๋ฒ๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ, ์ด ์๋ฒ๊ฐ ์๊ฐํด๋ด์ผ ํ๋ ๋ด์ฉ์ ์ด๋ ํฌํธ๋ก ์ด๋ ค์๋ ์๋ฒ์ ์์ฒญ์ ์ ๋ฌํด์ค์ผํ๋์ง์ ๋ํด์์ผ ๊ฒ์ด๋ค.
๋ง์ฝ ๊ธฐ๋ณธ http ๊ธฐ๋ณธ ํฌํธ์ธ 80๋ฒ์ผ๋ก ์ดํ๋ฆฌ์ผ์ด์ ์ด ๊ตฌ๋๋๊ณ ์์ ๊ฒฝ์ฐ๋ ์๊ด์์ง๋ง, 1023๋ฒ ๋ฏธ๋ง์ ์์ฝ ํฌํธ์ธ "Well-known-port" ๋ค์ด ์๋ ๊ทธ ์ธ์ ํฌํธ์ ์ด๋ ค์๋ ์ดํ๋ฆฌ์ผ์ด์ ์ผ ๊ฒฝ์ฐ, http ์์ฒญ์ด ๋ค์ด์ฌ ๋ ์ด ์์ฒญ์ ํด๋น ํฌํธ๋ก ํฌ์๋ฉ์ ํด์ค์ผํ๋ ์ํฉ์ด ๋ฒ์ด์ง๋ค.
์ด๋ฐ ์ญํ ์ nginx ๋ด๋ถ ์ค์ ์์ ํ ์ ์๋ฏ์ด, load balancer๋ ๋์ผํ ์ญํ ์ ํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ํฌํธ ํฌ์๋ฉ์ ๋ํ ์ ์๋ค์ด ๋ฐ๋ก Target group(๋์ ๊ทธ๋ฃน)
์ด๋ค.
๋๋ต ์ด์ ๋์ ๊ฐ๋ ์ ์ก๊ณ ๋ค์ ๋ก๋๋ฐธ๋ฐ์์ ์ค์ ์ผ๋ก ๋์๊ฐ๋ณด๋ฉด,
์ผ๋จ ๋ก๋๋ฐธ๋ฐ์ ์์ฒด์ ์ด๋ฆ์ ์ ์ํ๊ณ , ์ด ๋ก๋๋ฐธ๋ฐ์๊ฐ ํ๊ฒํ ํ VPC์ ์๋ธ๋ท์ ๋งคํํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฐฉํ๋ฒฝ ์ญํ ์ ํด์ค ๋ณด์๊ทธ๋ฃน
์ ์ค์ ํด์ค๋ค. EC2๋ฅผ ์ฐ๋ค๋ณด๋ฉด ์์ฃผ ๋ณด๊ฒ๋๋, ์ธ๋ฐ์ด๋์ ์์๋ฐ์ด๋์ ๋ํ ์ ์๋ค์ด ๋์ด์๋ ๊ฐ์ฒด์ด๋ค. (์ฆ, ์ด๋ ํฌํธ๋ก ๋ค์ด์ค๋ ์ ๊ทผ์ ํ์ฉํด์ค๊ฑฐ๊ณ , ์ด๋ ํฌํธ๋ก ๋๊ฐ ์ ์๊ฒ ํด์ค๊ฒ์ธ์ง์ ๋ํ ์ ์ ๋ชจ์์ง )
๊ทธ ๋ค์์๋ ๋ฆฌ์ค๋์ ๋ํ ์ ์๋ฅผ ํด์ค์ผํ๋ค.
์๊น ์์์ ๋ณธ ์ด๋ฏธ์ง๋๋ก, ๋ฐฉํ๋ฒฝ์ ํต๊ณผํ ์์ฒญ์ ๋ํด์ ์ด์ ์ง์ ์ ์ผ๋ก ๊ฐ๊ฐ์ ํฌํธ์ ๋ฐ๋ฅธ ํฌ์๋ฉ์ ๋ํ ์ ์๋ฅผ ํด์ค ์ฐจ๋ก์ด๋ค(๋์๊ทธ๋ฃน). ๋์๊ทธ๋ฃน ์์ฑ์ ๋๋ฌ์ ๋ค์ด๊ฐ๋ค.
์ ๋ง ํธํ ๋ถ๋ถ์ค ํ๋์ธ๋ฐ, ECS๋ฅผ ์ฌ์ฉํ๋ฉด EC2๋์๋ ๋ค๋ฅด๊ฒ ์์์ ์๋น์ค๋ก ๋ฐฐํฌ๋์ด์๋ ์ปจํ ์ด๋์ ํฌํธ์ ๋งค์นญ์์ผ์ฃผ๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ๋ฐ๋ก ์ง์ ํ์ง ์๊ณ ๊ทธ๋ฅ 80 ํฌํธ ์ ๊ทผ์ ๋ํ ํ๊ฒ๊ทธ๋ฃน ์์ฒด๋ง ์ง์ ํด๋๋ค.
๋ฐ๋ผ์ ECS๊ฐ ์์์ ๋ฐฐ์ ํด ์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์์์ฒ๋ผ ๊ธฐ๋ณธ ์ค์ ๋ Ipv4๋ถ๋ถ์ ์ ๊ฑฐํ๊ณ ๋ง๋ค์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
๋ค ๋์์ผ๋ฉด ๋ก๋ ๋ฐธ๋ฐ์๋ก ๋ค์ ๋์์์ ๋ฆฌ์คํฐ ๋ถ๋ถ์ ๋์๊ทธ๋ฃน์ ์๋ก๊ณ ์นจ์ ๋๋ฅธ ํ, ์๊น ๋ง๋ค์ด๋์๋ ๋์๊ทธ๋ฃน๊ณผ ๋ฆฌ์ค๋๋ฅผ ์ฐ๊ฒฐ์์ผ์ฃผ๋ฉด ๋๋ค.
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ECS๋ก ๋์ด๊ฐ๊ฒ ๋๋ค.
๋จผ์ ECS ๋ด์์ ์ฌ์ฉ๋ ์์ ์ ์(task-definition)์ ๋ง๋ค์ด์ผ ํ๋ค
์์ ์ ์๋, ECS๊ฐ ํน์ ECR์ ์ฌ๋ผ๊ฐ์๋ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ปจํ ์ด๋๋ฅผ ์์ฑํ ๋, ์ผ๋ง๋งํผ์ ์์์ ๋ถ๋ฐฐํ ๊ฒ์ด๊ณ ์ด๋ค OS๋ฅผ ์ฐ๊ณ , ์ปจํ ์ด๋ ์์ฑํ๋ฉด ์ปจํ ์ด๋ ํฌํธ๋ ๋ช์ด๊ณ ... ๋ฑ๋ฑ์ ์คํ ์ ์์์ ๊ฐ์ ๊ฒ์ JSON ํํ๋ก ์์ฑํ๋ ๊ฒ์ ๋ปํ๋ค.
๋ฐฐํฌ๋ฅผ ํ๊ฒ ๋์ด ์๋ก์ด ECS ์ด๋ฏธ์ง๊ฐ ์์ฑ๋๋ค๋ฉด, ์๋ก์ด ํ์คํฌ๋ฅผ ์ ์ํ๊ณ ์ด๊ฒ์ผ๋ก ECS์์ ํธ์คํ ํ ์ ์๊ฒ ํ๋ ์์ ์ด ํ์ํ๋ค. ๋ฌผ๋ก , ์ฐ๋ฆฌ๋ ์๋ํ ๊ณผ์ ์ผ๋ก ์ด๊ฒ์ ๋์ฒดํ ๊ฒ์ด๋ค.
๊ฐ ์์์ ๋ํด์ ์์ธํ ์ค๋ช ์ AWS ๊ณต์ ๋ฌธ์ ๋ฅผ ์ฐธ์กฐํ๋๋ก ํ๊ณ , ์ฌ๊ธฐ์๋ ์์ํ๊ฒ ์ฌ์ฉ์ ์ํ ๋ถ๋ถ๋ง ์ง๊ณ ๋์ด๊ฐ๋ ค๊ณ ํ๋ค.
ECS๋ฅผ ๊ฒ์ํด์ ์ ํ ์คํฌ ์ ์ ์์ฑ์ ๋๋ฅธ๋ค.
๋งจ ์ฒ์์ ๋ง๋๊ฒ ๋๋ ๊ฒ์ ํ์คํฌ ์ ์ ํจ๋ฐ๋ฆฌ ์ด๋ฆ์ด๋ค.
ํ์คํฌ ์ ์๋ ํ๋์ ํจ๋ฐ๋ฆฌ ์ ์ ์ด๋ฆ์ ๊ธฐ๋ฐ์ผ๋ก ๊ณ์ํด์ ์๋ก์ด ๋ฒ์ ์ ํ์คํฌ๋ค์ด ์์ด๊ธฐ ๋๋ฌธ์ ์ด๋ ๊ฒ ํจ๋ฐ๋ฆฌ ์ด๋ฆ์ผ๋ก ๊ฐ์ธ์ฃผ๋ ๊ฒ์ด๋ผ ์ดํดํ์๋ค.
๋ค๋ฅธ ๋ด์ฉ๋ค๋ ์ค์ํ๊ธด ํ๋ฐ, ๊ทธ๊ฒ๋ค์ ๊ทธ๋ฅ ๊ธฐ๋ณธ์ผ๋ก ๋๋๋ผ๋ ์ ์ผ ์ค์ํ๊ฑด ์ฐ๋ฆฌ์ docker image๊ฐ ์ปจํ
์ด๋ํํ ๋ ํ์ํ ์ ๋ณด๋ค์ ์์ฑํด์ฃผ์ด์ผ ํ๋ค.
์๋์ ํ๊ฒฝ ๋ณ์ ๋ถ๋ถ์ ์ง์ ์ ๋ ๊ฒ ์
๋ ฅํด๋ ๋๊ณ , S3์ ํ์ผํํ๋ก ์ ์ฅํ๋ค๊ฐ ์ถ๊ฐํ์ฌ๋ ๋๋ค.
์ด ์์ ์ ์์์ ๋ฐ๋ผ์ ECS๊ฐ ์ปจํ ์ด๋๋ฅผ ์์ฑํด์ค๊ฒ์ด๋ค.
๋ก์ปฌ์์ ์ง์ docker์ ์ด์ฉํด์ ์ปจํ ์ด๋ ๋์ธ ๋๋ฅผ ์๊ฐํด๋ณด๋ฉด ์ดํด์ ๋์์ด ๋ ๊ฒ์ด๋ค.
docker run -it -d -p 20160:20160 -e PORT=20160 testimage
์ฌํผ ๊ทธ๋ ๊ฒ ํ์คํฌ ์ ์๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด, ์๋์ ๊ฐ์ ํ๋ฉด์ผ ๊ฒ์ธ๋ฐ
์์ ๋ณด์ด๋ ํ์คํฌ ์ ์ ์ด๋ฆ์ด git action secret์ ECS_TASK_DEFINITION
๋ถ๋ถ์ ๋ค์ด๊ฐ ๊ฐ์ด ๋๋ค.
- name: Generate task-definition.json from latest active ECS task definition
run: |
aws ecs describe-task-definition \
--task-definition ${{ secrets.ECS_TASK_DEFINITION }} \ <-- ์ฌ๊ธฐ
--query taskDefinition \
> task-definition.json
Run ํํธ๋ ๊ฐ๋จํ ์ค๋ช ํ๋ฉด aws cli๋ฅผ ์ด์ฉํ์ฌ task ์ ์์ ๋ํ json์ ์ถ์ถํ๋ ๋ฌธ๋ฒ์ด๋ค. (์์ฑ ํ task-definition.json์ด๋ผ๋ ์ด๋ฆ์ ํ์ผ์ ์ ์ฅ์ํค๊ฒ ํ์๋ค. ์ด ํ์ผ์ ์๋์ผ๋ก ๋ค์ ์คํญ์์ ๋์ผ ์ด๋ฆ์ผ๋ก ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํ๋ค )
์์ธํ ์ต์ ์ค๋ช ์ task-definition cli ๊ณต์๋ฌธ์์ ์ฐธ์กฐํ๋๋ก ํ๋ค.
๊ทธ๋ฌ๋ฉด ์ด ๋ค์ ์คํญ์ผ๋ก ๋์ด๊ฐ๋ณด๋๋ก ํ์.
- name: Render Amazon ECS task definition
id: render-task-definition
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
# this step exports the task-definition as an output automatically (used for next step)
task-definition: task-definition.json
container-name: ${{ secrets.ECS_TASK_CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
ํด๋น ์คํญ์ ๋ฐ์์จ task-definition json์ ์ค์ ECS์ ๋์๊ฐ๊ธฐ ์ํ definition์ผ๋ก ๋๋๋งํ๋ ์ญํ ์ ํ๋ค. (์์ธํ ๋ด๋ถ ๊ตฌ์กฐ๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค)
aws-actions์์ ์ ๊ณตํด์ฃผ๋ aws-actions/amazon-ecs-render-task-definition@v1
์ ํ์ฉํ๋ฉด ๋๋ฉฐ, ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ git action secret์ผ๋ก ์ ์ํด์ค์ผ ํ๋ ๋ถ๋ถ์ ์๊น task-definition์ ์์ฑํ ๋ ์ปจํ
์ด๋ ์ด๋ฆ์ผ๋ก ์ ํด๋์๋ ๊ฒ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ผ ์ด์ ํ ์คํธ ์ ์๋ ๋ค ํ์์ผ๋, ์ด ํ์คํฌ๋ฅผ ๊ธฐ๋ฐํ์ฌ ์ค์ ์ปจํ ์ด๋๋ฅผ ๋์์ค ํ๊ฒฝ์ธ ECS ํด๋ฌ์คํฐ ์ ์๋ฅผ ํ๋ฌ ๊ฐ์ผํ๋ค. (EC2๋ก ๋์ฒดํด์ ์๊ฐํ๋ฉด ์ดํดํ๊ธฐ ํธํ๋ค.)
ํด๋ฌ์คํฐ ๊ทธ ์์ฒด๋ ์๋น์ค๋ค์ ๋ฌถ์ด์ฃผ๋ ์งํฉ์ ์ด๋ฆ๋ง ํด๋นํ๋ ๋๋์ด๋ผ ์ฌ์ค ์ด๋ฆ ์ ์๋ง ํ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋์ ์์ฑํ ๋ค ํด๋ฌ์คํฐ ๋ด์์ ๋ฌถ์ฌ ์์ ์๋น์ค๋ค์ ์ ์ํด์ผํ๋ค.
์๋น์ค๋ ๋จ์ํ๊ฒ ์๊ฐํ๋ฉด ๋ฐฐํฌ ํ๊ฒฝ์ ๋์์ ธ ์๋ ์ดํ๋ฆฌ์ผ์ด์
์๋น์ค๋ค์ด๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค. ์์ธํ๊ฑด ์๋์ ์ฌ์ง์ ๋ณด๋ฉด ๋ ์ดํด๊ฐ ์ฌ์ธ๊ฒ์ด๋ค.
์ค๊ฐ์ ๋ณด์ด๋ ํจ๋ฐ๋ฆฌ๊ฐ ์๊น ์ฐ๋ฆฌ๊ฐ ์ ์ํ๋ ํ์คํฌ ์ ์์ ํจ๋ฐ๋ฆฌ ์ด๋ฆ์ด๋ค.
ํ์ฌ ๋ฒ์ ์ 14๋ก ๋์ด์๋๋ฐ, ์ ๋ฒ์ ์ ๊ณ์ ๋ฐ๋๊ฒ์ด๋ค.(๋ฐฐํฌ๋ฅผ ํ ๋๋ง๋ค)
์๋น์ค์ ๋ํ ์ด๋ฆ์ ์ ์ํด์ฃผ๊ณ , ๋ฐฐํฌ ์ต์ ์ ๊ฐ์ผํ๋๋ฐ,
์ฌ์ค ๋ธ๋ฃจ/๊ทธ๋ฆฐ ๋ฐฐํฌ์๋ต์ ์ ํํ๋ ค๋ฉด AWS code deploy๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํด์ผํ๋ค.
๊ทธ ๋ถ๋ถ๊น์ง ๋ฃ๊ธฐ๋ ๋๋ฌด ์๊ฐ์ด ๊ฑธ๋ ค์ ์ผ๋จ ๋กค๋ง์
๋ฐ์ดํธ๋ก ์งํํ๋ ค๊ณ ํ๋ค.
์ฐธ๊ณ ๋ก, ๋กค๋ง ์ ๋ฐ์ดํธ์ ๋ธ๋ฃจ/๊ทธ๋ฆฐ ์ ๋ฐ์ดํธ๋ ๋ฌด์ค๋จ ๋ฐฐํฌ ๊ธฐ๋ฒ๋ค์ด๋ฉฐ, ์ฐจ์ด์ ๋ํด์๋ ๊ฐ๋จํ ์ค๋ช ํ์๋ฉด
- ๋กค๋ง ์ ๋ฐ์ดํธ : ํ์ฌ ๋์์ ธ ์๋ ์๋น์ค๋ฅผ ์ ์งํ๊ณ ์๋ ์ํ์์, ์ ์ง์ ์ผ๋ก ์๋น์ค๋ค์ ํ๋ํ๋ ์ ๋ฐ์ดํธํด๋๊ฐ๋ฉด์ ๊ต์ฒดํ๋ ๋ฐฉ์. ํ์ฐ์ ์ผ๋ก ๋๊ฐ์ง ๋ฒ์ ์ด ๋์์ ํธ์คํ ๋๋ ์๊ฐ์ด ์กด์ฌํจ.
- ๋ธ๋ฃจ/๊ทธ๋ฆฐ ์ ๋ฐ์ดํธ : ํ์ฌ ์๋น์ค๋ฅผ ์ ์งํ๊ณ ์๋ ์ํ์์, ๋ค๋ฅธ ๋ฒ์ ์ ์๋น์ค๋ค์ ํต์งธ๋ก ์์ฑํ ํ, ๋ก๋๋ฐธ๋ฐ์ฑ์ ์๋ก์ด ๋ฒ์ ์ผ๋ก ์นํํ ๋ค ๊ธฐ์กด ์๋น์ค๋ฅผ ์ฃฝ์ด๋ ๋ฐฉ๋ฒ. ๋ฐฐํฌํ ๋ ๋ ์๋น์ค๋ฅผ ๋ค ๋์ธ ์์์ด ํ์ํจ(์ฆ ๋๋ฐฐ)
์ฌํผ, ์ดํ ์๊น ๋ง๋ค์ด๋์๋ ๋ก๋๋ฐธ๋ฐ์ ์ค์ ๋ ๋ถ๋ฌ์จ ํ, ์๋น์ค๋ฅผ ์์ฑ ์๋ฃํด์ฃผ๋ฉด ๋๋ค.
์ดํ, ๋ค์ git action step์ secret์ ํด๋นํ๋ ๊ฐ์ ๋ฑ๋กํด์ฃผ๋ฉด ๋๋ค.
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-task-definition.outputs.task-definition }}
service: ${{ secrets.ECS_SERVICE }} <--- ์ด๊ฑฐ
cluster: ${{ secrets.ECS_CLUSTER }} <--- ์ด๊ฑฐ
wait-for-service-stability: true
์ด๋ ๊ฒ ํด๋๋ฉด, ์ด์ ๋ค ์๋ฃ๋์๋ค.
์ด์ git action์ ์กฐ๊ฑด์ ๋ง์ถฐ์ ์คํ๋ ๊ฒ์ด๋ค. ๋๋ develop์ pull request๊ฐ close๋๋ ์๊ฐ์ ์คํ๋๊ฒ ํด๋์๊ธฐ ๋๋ฌธ์ ์๋์ฒ๋ผ CD action์ด ์งํ๋๋ฉฐ
on:
pull_request:
branches:
- develop
types: [closed]
task defininition์๋ ์ ๋๋ก ์๋ก์ด ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๊ฒ ๋๋ฉด์ CD ๊ณผ์ ์ผ๋ก ์์ฑ๋ ์๋ก์ด ์ด๋ฏธ์ง๊ฐ ๋ฑ๋ก๋๊ฒ ๋๊ณ ,
ECS ํด๋ฌ์คํฐ ๋ด์ ์๋น์ค์๋ ํด๋น ์ต์ ์ ์ด๋ฏธ์ง๊ฐ ๊ตฌ๋๋๊ฒ ๋๋ค.
ํด๋น ๊ตฌ๋๋ ์ปจํ
์ด๋์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ๋ก๋ ๋ฐธ๋ฐ์๋ฅผ ํตํด ๋ค์ด๊ฐ์ผ ํ๋ค.
์ฐ๋ฆฌ์ ๋ก๋ ๋ฐธ๋ฐ์๋ ํด๋ฌ์คํฐ ์๋น์ค์ ๋ค์ด๊ฐ์ ๋ก๋๋ฐธ๋ฐ์ ๋ถ๋ถ์ ๋๋ฅธ ํ, DNS ์ฃผ์๋ฅผ ํตํด ์ ๊ทผํด๋ณผ ์ ์๋ค.
๊ธด ์ฌ์ ์ด์๋ค... ์ฌ์ค ์ด ๊ณผ์ ํ๋ํ๋๊ฐ ์ํํ ๊ณผ์ ์ด ์๋์๊ธฐ ๋๋ฌธ์ ํด์ผํ ๊ฒ์ด ์ ๋ง ๋ง์๋๋ฐ,
๊ทธ๋๋ ๊ทธ ๊ณผ์ ์ ๊ฒช์ผ๋ฉด์ ๋ฐฐ์๊ฐ ๊ฒ์ด ์ ๋ง ๋ง์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ก์ผ๋ก ๋จ๊ธฐ๋ฉด์๋ ์์ง๋ ๋ง์ด ์ ์งํด์ผ ํจ์ ๋๋๋ค.
์ด๋ ๊ฒ ์ ๋ฆฌํด๋์ผ๋ ๋์ค์ (๋ด๊ฐ) ๋ค์ ๊ตฌํํ๋ผ๊ณ ํ ๋ ๋์์ด ๋ง์ด ๋๊ฒ ์ง ํํ.