Skip to content

v1.0.0: release 1차 운영 배포 (#43) #99

v1.0.0: release 1차 운영 배포 (#43)

v1.0.0: release 1차 운영 배포 (#43) #99

Workflow file for this run

name: Deploy to Amazon ECS
# release, develop 브랜치에 푸시되거나 PR이 닫힐 때마다 실행되는 워크플로우입니다.
on:
push:
branches:
- "release"
- "develop"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 1. JDK 17 세팅
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# 2. 환경변수(yml)가 있는 서브모듈 가져오기
- name: Checkout
uses: actions/checkout@v3
with:
token: ${{ secrets.ACTION_TOKEN }}
submodules: true
# 2-1. 환경변수(yml) 파일이 있는지 확인
- name: Check if config files exist - dev
if: github.ref == 'refs/heads/develop'
run: |
echo "Current Directory: $(pwd)"
cd config
echo "Current Directory: $(pwd)"
cd dev
echo "Current Directory: $(pwd)"
ls -al
- name: Check if config files exist - prod
if: github.ref == 'refs/heads/release'
run: |
echo "Current Directory: $(pwd)"
cd config
echo "Current Directory: $(pwd)"
cd prod
echo "Current Directory: $(pwd)"
ls -al
# 3. AWS 자격 증명 구성
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
# # 4. AWS CLI 설치 (사전 설치되어 있지 않은 경우)
# - name: Install AWS CLI (if not pre-installed)
# run: |
# sudo apt-get update
# sudo apt-get install -y awscli
# AWS SSM으로 현재 redis의 포트 확인 커멘드 설정
- name: Get Redis port from AWS SSM
if: github.ref == 'refs/heads/develop'
id: send_cmd
run: |
cmd_id=$(aws ssm send-command \
--document-name "AWS-RunShellScript" \
--targets "Key=instanceIds,Values=${{ secrets.EC2_INSTANCE_ID }}" \
--comment "Deploy script via CI" \
--parameters 'commands=[
"if netstat -tuln | grep -q \":6379 \"; then echo 6379; \
elif netstat -tuln | grep -q \":6380 \"; then echo 6380; \
else echo none; fi"
]' \
--region ap-northeast-2 \
--query "Command.CommandId" --output text)
echo "cmd_id=$cmd_id" >> $GITHUB_OUTPUT
# AWS SSM 커멘드를 실행하여 현재 redis의 포트 확인 및 교체할 port 저장
- name: Get Redis port command result
if: github.ref == 'refs/heads/develop'
id: get_cmd_result
run: |
redis_port=$(aws ssm get-command-invocation \
--command-id ${{ steps.send_cmd.outputs.cmd_id }} \
--instance-id ${{ secrets.EC2_INSTANCE_ID }} \
--region ap-northeast-2 \
--query 'StandardOutputContent' \
--output text | tr -d '\n')
echo "현재 열려있는 Redis 포트: $redis_port"
if [ "$redis_port" = "6379" ]; then
next_port="6380"
elif [ "$redis_port" = "6380" ]; then
next_port="6379"
else
next_port="6379"
echo "Redis를 신규로 띄웁니다"
fi
echo "next_redis_port=$next_port" >> $GITHUB_OUTPUT
# 호스트 포트 수정
- name: Update Redis hostPort in task-definition-dev.json
if: github.ref == 'refs/heads/develop'
run: |
jq --arg port "${{ steps.get_cmd_result.outputs.next_redis_port }}" \
'(.containerDefinitions[] | select(.name == "redis-dev").portMappings[] | select(.containerPort == 6379)).hostPort = ($port | tonumber)' \
task-definition-dev.json > tmp.json && mv tmp.json task-definition-dev.json
echo "수정된 task-definition.json의 Redis portMappings:"
jq '.containerDefinitions[] | select(.name == "redis-dev") | .portMappings[].hostPort' task-definition-dev.json
# - name: Update spring.data.redis.port in application.yml
# if: github.ref == 'refs/heads/develop'
# run: |
# echo "Before modification:"
# grep "spring.data.redis.port" config/dev/application-dev.yml
#
# sed -i "s/\(spring.data.redis.port:\).*/\1 ${{ steps.get_cmd_result.outputs.redis_port }}/" config/dev/application-dev.yml
#
# echo "After modification:"
# grep "spring.data.redis.port" config/dev/application-dev.yml
# 5. Gradle 실행 권한 부여
- name: Grant execute permission for Gradle
run: chmod +x ./gradlew
# 6. Gradle로 빌드
- name: Build with Gradle
run: ./gradlew clean build
# 7. Amazon ECR에 로그인
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
# 8. Docker 이미지 빌드 및 태그, Amazon ECR에 이미지 푸시
- name: Build Docker image and tag, push image to Amazon ECR - release
if: github.ref == 'refs/heads/release'
id: build-image-release
run: |
docker build --platform linux/amd64 -t ${{ secrets.ECR_REPO_NAME_PROD }} .
docker tag ${{ secrets.ECR_REPO_NAME_PROD }}:latest ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROD }}:latest # 이미지를 ECR 리포지토리로 태깅합니다.
docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROD }}:latest # 이미지를 ECR에 푸시합니다.
echo "image=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROD }}:latest" >> $GITHUB_OUTPUT
- name: Build Docker image and tag, push image to Amazon ECR - develop
if: github.ref == 'refs/heads/develop'
id: build-image-develop
run: |
docker build --platform linux/amd64 -t ${{ secrets.ECR_REPO_NAME_DEV }} .
docker tag ${{ secrets.ECR_REPO_NAME_DEV }}:latest ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_DEV }}:latest # 이미지를 ECR 리포지토리로 태깅합니다.
docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_DEV }}:latest # 이미지를 ECR에 푸시합니다.
echo "image=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_DEV }}:latest" >> $GITHUB_OUTPUT
# 9. Amazon ECS 태스크 정의에 새 이미지 ID 채우기
- name: Fill in the new image ID in the Amazon ECS task definition - release
if: github.ref == 'refs/heads/release'
id: task-def-release
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition-prod.json
container-name: ${{ secrets.ECS_CONTAINER_NAME_PROD }}
image: ${{ steps.build-image-release.outputs.image }}
- name: Mask ECS container name secret - release
if: github.ref == 'refs/heads/release'
run: |
echo "ECS_CONTAINER_NAME_PROD is ${{ secrets.ECS_CONTAINER_NAME_PROD }}"
echo "Container Names in task-definition-prod.json:"
cat task-definition-prod.json | jq -r '.containerDefinitions[].name'
- name: Fill in the new image ID in the Amazon ECS task definition - develop
if: github.ref == 'refs/heads/develop'
id: task-def-develop
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition-dev.json
container-name: ${{ secrets.ECS_CONTAINER_NAME_DEV }}
image: ${{ steps.build-image-develop.outputs.image }}
# 10. ECS에 배포
- name: Deploy to ECS - release
if: github.ref == 'refs/heads/release'
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def-release.outputs.task-definition }} # ECS 태스크 정의 파일을 지정합니다.
service: ${{ secrets.ECS_SERVICE_NAME_PROD }}
cluster: ${{ secrets.ECS_CLUSTER_NAME }}
wait-for-service-stability: true # 서비스가 안정화될 때까지 대기합니다.
- name: Deploy to ECS - develop
if: github.ref == 'refs/heads/develop'
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def-develop.outputs.task-definition }} # ECS 태스크 정의 파일을 지정합니다.
service: ${{ secrets.ECS_SERVICE_NAME_DEV }}
cluster: ${{ secrets.ECS_CLUSTER_NAME }}
wait-for-service-stability: true # 서비스가 안정화될 때까지 대기합니다.
# 11. 배포 알림 메세지 설정
- name: Set Slack message based on branch
id: set-slack-message
run: |
if [[ "${{ github.ref_name }}" == "develop" ]]; then
echo "SLACK_MESSAGE=✅ 개발계(develop) 배포 완료 🎉" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "release" ]]; then
echo "SLACK_MESSAGE=🚀 운영계(release) 배포 완료!" >> $GITHUB_ENV
else
echo "SLACK_MESSAGE=⚙️ '${{ github.ref_name }}' 브랜치로 배포되었습니다." >> $GITHUB_ENV
fi
# 12. Slack 배포 성공 알림(개발, 운영 서버)
- name: Notify Slack - release
if: success()
id: slack-success
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"channel": "#server-deploy",
"attachments": [
{
"color": "#36a64f",
"title": "🔔 ${{ github.repository }} 배포 알림",
"title_link": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"text": "${{ env.SLACK_MESSAGE }}",
"fields": [
{
"title": "브랜치",
"value": "${{ github.ref_name }}",
"short": true
},
{
"title": "배포자",
"value": "${{ github.actor }}",
"short": true
},
{
"title": "커밋 메시지",
"value": "${{ github.event.head_commit.message }}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEPLOY_BOT_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
# 13. Slack 배포 실패 알림(개발, 운영 서버)
- name: Notify Slack - failure
if: failure() # 이 스텝은 job 실패 시에만 실행됨
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"channel": "#server-deploy",
"attachments": [
{
"color": "#ff0000", # 실패는 빨간색
"title": "🚨 배포 실패: ${{ github.repository }}",
"title_link": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"text": "${{ github.ref_name }} 브랜치에 배포 실패 ❌",
"fields": [
{
"title": "브랜치",
"value": "${{ github.ref_name }}",
"short": true
},
{
"title": "커밋 메시지",
"value": "${{ github.event.head_commit.message }}",
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEPLOY_BOT_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK