-
Notifications
You must be signed in to change notification settings - Fork 0
202 lines (178 loc) · 8.8 KB
/
cicd-workflow.yml
File metadata and controls
202 lines (178 loc) · 8.8 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
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 # 서비스가 안정화될 때까지 대기합니다.