@@ -2,7 +2,8 @@ name: Deploy to Amazon ECR & EC2
22
33on :
44 push :
5- branches : [ main ]
5+ branches :
6+ - main
67
78env :
89 AWS_REGION : ap-northeast-2
@@ -15,137 +16,50 @@ env:
1516
1617jobs :
1718 deploy :
18- name : Build → Push(ECR) → Deploy(EC2 Private)
1919 runs-on : ubuntu-latest
2020 environment : production
2121
22- steps :
23- - name : Checkout
24- uses : actions/checkout@v4
22+ steps :
23+ - uses : actions/checkout@v4
2524
26- - name : Configure AWS credentials
27- uses : aws-actions/configure-aws-credentials@0e613a0980cbf65ed5b322eb7a1e075d28913a83
28- with :
29- aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
30- aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
31- aws-region : ${{ env.AWS_REGION }}
25+ - uses : aws-actions/configure-aws-credentials@0e613a0980cbf65ed5b322eb7a1e075d28913a83
26+ with :
27+ aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
28+ aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
29+ aws-region : ${{ env.AWS_REGION }}
3230
33- - name : Login to Amazon ECR
34- id : login-ecr
35- uses : aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a
31+ - id : login-ecr
32+ uses : aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a
3633
37- - name : Build, tag, and push image to Amazon ECR
38- id : build-image
39- env :
40- ECR_REGISTRY : ${{ steps.login-ecr.outputs.registry }}
41- IMAGE_TAG : ${{ github.sha }}
42- run : |
43- set -euo pipefail
44- docker build -t "$ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG" .
45- docker push "$ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG"
46- echo "image=$ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG" >> "$GITHUB_OUTPUT"
47-
48- # === 여기부터 Private EC2로 배포(SSM RunCommand) ===
49- - name : Build SSM command script
50- id : ssm-script
51- env :
52- AWS_REGION : ${{ env.AWS_REGION }}
53- ECR_REGISTRY : ${{ steps.login-ecr.outputs.registry }}
54- IMAGE_URI : ${{ steps.build-image.outputs.image }}
55- CONTAINER_NAME : ${{ env.CONTAINER_NAME }}
56- DOCKER_RUN_ARGS : ${{ env.DOCKER_RUN_ARGS }}
57- run : |
58- set -euo pipefail
59- cat > deploy.sh <<'EOF'
60- #!/usr/bin/env bash
61- set -euo pipefail
62-
63- echo "[1/5] ECR 로그인"
64- aws ecr get-login-password --region "${AWS_REGION}" \
65- | docker login --username AWS --password-stdin "${ECR_REGISTRY}"
66-
67- echo "[2/5] 새 이미지 Pull: ${IMAGE_URI}"
68- docker pull "${IMAGE_URI}"
69-
70- echo "[3/5] 기존 컨테이너 정리: ${CONTAINER_NAME}"
71- # 동일 이름 컨테이너가 있으면 중지/삭제
72- if docker ps -a --format '{{.Names}}' | grep -wq "${CONTAINER_NAME}"; then
73- docker rm -f "${CONTAINER_NAME}" || true
74- fi
75-
76- echo "[4/5] 오래된 이미지 가비지 정리(선택)"
77- docker image prune -f || true
78-
79- echo "[5/5] 새 컨테이너 기동"
80- docker run -d --name "${CONTAINER_NAME}" ${DOCKER_RUN_ARGS} "${IMAGE_URI}"
81-
82- echo "DONE"
83- EOF
84-
85- python3 - <<'PY' >> $GITHUB_OUTPUT
86- import json
87- script = open('deploy.sh','r',encoding='utf-8').read()
88-
89- cmd = ["bash","-lc", script]
90- print("commands=" + json.dumps(cmd))
91- PY
34+ - id : build-image
35+ run : |
36+ IMAGE_TAG=${{ github.sha }}
37+ out=$(bash scripts/build_and_push.sh \
38+ "${{ steps.login-ecr.outputs.registry }}" \
39+ "${{ env.ECR_REPOSITORY }}" \
40+ "$IMAGE_TAG")
41+ echo "$out" >> "$GITHUB_OUTPUT"
9242
93- - name : Send SSM RunCommand to EC2 (by InstanceIds or by Tag)
94- id : ssm-deploy
43+ - id : ssm-deploy
9544 run : |
96- set -euo pipefail
97-
98- TARGETS_JSON="[]"
99- if [ -n "${{ env.EC2_INSTANCE_IDS }}" ]; then
100-
101- # InstanceId로 지정
102- IFS=',' read -ra IDS <<< "${{ env.EC2_INSTANCE_IDS }}"
103- ARR=""
104- for id in "${IDS[@]}"; do
105- ARR="${ARR}{\"Key\":\"InstanceIds\",\"Values\":[\"$id\"]},"
106- done
107- TARGETS_JSON="["${ARR%,}"]"
108- elif [ -n "${{ env.EC2_TAG_KEY || '' }}" ] && [ -n "${{ env.EC2_TAG_VALUE || '' }}" ]; then
109- # 태그로 지정
110- TARGETS_JSON=$(cat <<JSON
111- [
112- {"Key":"tag:${{ env.EC2_TAG_KEY }}","Values":["${{ env.EC2_TAG_VALUE }}"]}
113- ]
114- JSON
115- )
116- else
117- echo "EC2 타깃(EC2_INSTANCE_IDS 또는 EC2_TAG_KEY/EC2_TAG_VALUE)을 설정하세요." >&2
118- exit 1
119- fi
120-
45+ IMAGE_URI=${{ steps.build-image.outputs.image }}
46+ TARGETS_JSON=$(jq -n --arg ids "${{ env.EC2_INSTANCE_IDS }}" '
47+ {Key:"InstanceIds", Values: ($ids | split(","))}
48+ ' | jq -s .)
49+
50+ COMMANDS_JSON=$(jq -Rs . < scripts/deploy_container.sh)
12151 aws ssm send-command \
12252 --document-name "AWS-RunShellScript" \
123- --comment "Pull from ECR and restart container" \
124- --targets "${TARGETS_JSON}" \
125- --parameters '{"commands": '${{ steps.ssm-script.outputs.commands }}'}' \
126- --timeout-seconds 1800 \
127- --max-concurrency "1" \
128- --max-errors "0" \
53+ --comment "Deploy new container" \
54+ --targets "$TARGETS_JSON" \
55+ --parameters "{\"commands\":[\"bash\",\"-lc\",$COMMANDS_JSON]}" \
12956 --region "${{ env.AWS_REGION }}" \
13057 --output json > send-command.json
131-
58+
13259 COMMAND_ID=$(jq -r '.Command.CommandId' send-command.json)
133- echo "command-id=${COMMAND_ID}" >> "$GITHUB_OUTPUT"
134-
135- - name : Wait for SSM command to finish
136- run : |
137- set -euo pipefail
138- COMMAND_ID="${{ steps.ssm-deploy.outputs.command-id }}"
139- echo "Waiting for SSM Command $COMMAND_ID ..."
140- # 간단 폴링
141- for i in $(seq 1 120); do
142- STATUS=$(aws ssm list-commands --command-id "$COMMAND_ID" --query "Commands[0].Status" --output text --region "${{ env.AWS_REGION }}")
143- echo "SSM Status: $STATUS"
144- case "$STATUS" in
145- Success) exit 0 ;;
146- Failed|Cancelled|TimedOut) echo "SSM failed: $STATUS"; exit 1 ;;
147- esac
148- sleep 5
149- done
150- echo "Timeout waiting SSM command"
151- exit 1
60+ echo "command-id=$COMMAND_ID" >> "$GITHUB_OUTPUT"
61+
62+ - run : |
63+ bash scripts/wait_ssm.sh \
64+ "${{ env.AWS_REGION }}" \
65+ "${{ steps.ssm-deploy.outputs.command-id }}"
0 commit comments