From adc33748e658b1b48021de64bb6afa6f904e78d9 Mon Sep 17 00:00:00 2001 From: catomat0 Date: Tue, 23 Jun 2026 18:25:54 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor:=20ssm+oidc=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd.yml | 73 +++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 0d229b5..9d0ae2e 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -3,10 +3,15 @@ name: CD - build/push image & deploy to EC2 on main push on: push: branches: ["main"] + workflow_dispatch: # main 머지 전 테스팅 - 실 배포 시 각주 처리할 것 env: IMAGE_NAME: deare-backend +permissions: + id-token: write + contents: read + jobs: deploy: runs-on: ubuntu-latest @@ -52,40 +57,38 @@ jobs: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - # 4) docker-compose-dev.yml을 EC2로 복사 -> 추후 docker-compose-prod 교체 - - name: Copy docker-compose-dev.yml to EC2 - uses: appleboy/scp-action@v1 - with: - host: ${{ secrets.EC2_HOST }} - username: ${{ secrets.EC2_USER }} - key: ${{ secrets.EC2_SSH_KEY }} - source: "docker-compose-dev.yml" - target: "/home/ubuntu/deare" - - # 5) EC2에서 pull + up (down은 실패 시에만) / #87 수정 - - name: Deploy on EC2 (pull + up -d, fallback to down) - uses: appleboy/ssh-action@v1.2.4 + # 4) OIDC로 AWS 임시 자격증명 획득 + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 with: - host: ${{ secrets.EC2_HOST }} - username: ${{ secrets.EC2_USER }} - key: ${{ secrets.EC2_SSH_KEY }} - script: | - set -e - cd /home/ubuntu/deare - - ENV_FILE=/home/ubuntu/deare/.env.prod - COMPOSE_FILE=/home/ubuntu/deare/docker-compose-dev.yml + role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} + aws-region: ap-northeast-2 - - docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE pull app - - if docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d; then - echo "compose up succeeded without down" - else - echo "compose up failed. fallback to down -> up" - docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE down - docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d - fi - - docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE ps - docker image prune -f + # 5) SSM으로 EC2에 배포 (pull + up -d, fallback to down) + - name: Deploy on EC2 via SSM + run: | + COMMAND_ID=$(aws ssm send-command \ + --instance-ids "${{ secrets.EC2_INSTANCE_ID }}" \ + --document-name "AWS-RunShellScript" \ + --parameters 'commands=[ + "set -e", + "cd /home/ubuntu/deare", + "ENV_FILE=/home/ubuntu/deare/.env.prod", + "COMPOSE_FILE=/home/ubuntu/deare/docker-compose-dev.yml", + "docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE pull app", + "if docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d; then echo compose up succeeded without down; else docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE down && docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE up -d; fi", + "docker-compose --env-file $ENV_FILE -f $COMPOSE_FILE ps", + "docker image prune -f" + ]' \ + --query "Command.CommandId" \ + --output text) + + aws ssm wait command-executed \ + --command-id "$COMMAND_ID" \ + --instance-id "${{ secrets.EC2_INSTANCE_ID }}" + + aws ssm get-command-invocation \ + --command-id "$COMMAND_ID" \ + --instance-id "${{ secrets.EC2_INSTANCE_ID }}" \ + --query "StandardOutputContent" \ + --output text From fc27f8822925d2609497ff65d33f4dad7f2b2093 Mon Sep 17 00:00:00 2001 From: catomat0 Date: Tue, 23 Jun 2026 18:48:52 +0900 Subject: [PATCH 2/3] =?UTF-8?q?chore:=20=ED=83=80=EC=9E=84=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=84=B8=ED=8C=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd.yml | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 9d0ae2e..5e118f5 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -83,12 +83,40 @@ jobs: --query "Command.CommandId" \ --output text) - aws ssm wait command-executed \ - --command-id "$COMMAND_ID" \ - --instance-id "${{ secrets.EC2_INSTANCE_ID }}" + # waiter 대신 직접 폴링 (10초 간격, 최대 60회 = 600초) + for i in $(seq 1 60); do + STATUS=$(aws ssm get-command-invocation \ + --command-id "$COMMAND_ID" \ + --instance-id "${{ secrets.EC2_INSTANCE_ID }}" \ + --query "Status" \ + --output text 2>/dev/null || echo "Pending") + + echo "[$i/60] Status: $STATUS" + + if [[ "$STATUS" == "Success" || "$STATUS" == "Failed" || "$STATUS" == "Cancelled" || "$STATUS" == "TimedOut" ]]; then + break + fi + sleep 10 + done + + # 성공/실패 무관하게 stdout, stderr 항상 출력 + echo "=== stdout ===" aws ssm get-command-invocation \ --command-id "$COMMAND_ID" \ --instance-id "${{ secrets.EC2_INSTANCE_ID }}" \ --query "StandardOutputContent" \ --output text + + echo "=== stderr ===" + aws ssm get-command-invocation \ + --command-id "$COMMAND_ID" \ + --instance-id "${{ secrets.EC2_INSTANCE_ID }}" \ + --query "StandardErrorContent" \ + --output text + + # 상태 기반 종료 코드 결정 + if [[ "$STATUS" != "Success" ]]; then + echo "Deploy failed with status: $STATUS" + exit 1 + fi From 13a7ef7a7e5b2b505504f90c57fed8406fa56ab0 Mon Sep 17 00:00:00 2001 From: catomat0 Date: Tue, 23 Jun 2026 19:01:40 +0900 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20ec2-=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20=EA=B8=B0?= =?UTF-8?q?=EA=B0=84=20=EB=A7=A4=EC=B9=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 5e118f5..27c120f 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -70,6 +70,7 @@ jobs: COMMAND_ID=$(aws ssm send-command \ --instance-ids "${{ secrets.EC2_INSTANCE_ID }}" \ --document-name "AWS-RunShellScript" \ + --timeout-seconds 600 \ --parameters 'commands=[ "set -e", "cd /home/ubuntu/deare",