-
Notifications
You must be signed in to change notification settings - Fork 0
340 lines (313 loc) · 15.1 KB
/
cicd-workflow.yml
File metadata and controls
340 lines (313 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
name: Deploy to Amazon ECS
# release, develop 브랜치에 푸시되거나 PR이 닫힐 때마다 실행되는 워크플로우입니다.
on:
push:
branches:
- "release"
- "develop"
permissions:
contents: write
pull-requests: write
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
# # 8-1. Prometheus Docker 이미지 빌드 및 푸시
# - name: Build Prometheus image - release
# if: github.ref == 'refs/heads/release'
# id: build-prom-image-release
# run: |
# cp config/prod/application-prometheus-prod.yml ./prometheus.yml
# docker build --platform linux/amd64 -f monitoring/Dockerfile -t ${{ secrets.ECR_REPO_NAME_PROMETHEUS_PROD }} .
# docker tag ${{ secrets.ECR_REPO_NAME_PROMETHEUS_PROD }}:latest ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_PROD }}:latest
# docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_PROD }}:latest
# echo "image=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_PROD }}:latest" >> $GITHUB_OUTPUT
#
# - name: Build Prometheus image - develop
# if: github.ref == 'refs/heads/develop'
# id: build-prom-image-develop
# run: |
# cp config/dev/application-prometheus-dev.yml ./prometheus.yml
# docker build --platform linux/amd64 -f monitoring/Dockerfile -t ${{ secrets.ECR_REPO_NAME_PROMETHEUS_DEV }} .
# docker tag ${{ secrets.ECR_REPO_NAME_PROMETHEUS_DEV }}:latest ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_DEV }}:latest
# docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_DEV }}:latest
# echo "image=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com/${{ secrets.ECR_REPO_NAME_PROMETHEUS_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 }}
# # ★ 추가: 프로메테우스 이미지 주입 (release)
# - name: Fill in Prometheus image - release
# if: github.ref == 'refs/heads/release'
# id: task-def-prom-release
# uses: aws-actions/amazon-ecs-render-task-definition@v1
# with:
# task-definition: ${{ steps.task-def-release.outputs.task-definition }} # 위 단계에서 만든 결과물을 입력으로 사용
# container-name: prometheus
# image: ${{ steps.build-prom-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 }}
# # ★ 추가: 프로메테우스 이미지 주입 (develop)
# - name: Fill in Prometheus image - develop
# if: github.ref == 'refs/heads/develop'
# id: task-def-prom-develop
# uses: aws-actions/amazon-ecs-render-task-definition@v1
# with:
# task-definition: ${{ steps.task-def-develop.outputs.task-definition }} # 위 단계에서 만든 결과물을 입력으로 사용
# container-name: prometheus
# image: ${{ steps.build-prom-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": ${{ toJSON(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": ${{ toJSON(github.event.head_commit.message) }},
"short": false
}
]
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEPLOY_BOT_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
# 14. Release Drafter 설정
- name: Release
if: github.ref == 'refs/heads/release'
uses: release-drafter/release-drafter@v6
with:
config-name: release-drafter-config.yml
env:
GITHUB_TOKEN: ${{ secrets.ACTION_TOKEN }}