Deploy Migration Test Environment #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 'Deploy Migration Test Environment' | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| branch: | |
| description: '테스트할 브랜치 이름' | |
| required: true | |
| default: 'develop' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: terraform-migration | |
| cancel-in-progress: false | |
| env: | |
| AWS_REGION: ap-northeast-2 | |
| jobs: | |
| build-lambda-handler: | |
| name: Build Lambda Handler | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.inputs.branch }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies and create zip file | |
| run: | | |
| mkdir -p build/lambda-package | |
| pip install -r ./terraform-db-migration/lambda_src/requirements.txt -t ./build/lambda-package | |
| cp ./terraform-db-migration/lambda_src/handler.py ./build/lambda-package/ | |
| cd ./build/lambda-package | |
| zip -r ../migration_lambda.zip . | |
| - name: Upload Lambda artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lambda-build | |
| path: ./build/migration_lambda.zip | |
| terraform-apply-migration: | |
| name: Terraform Apply MIGRATION | |
| runs-on: ubuntu-latest | |
| needs: build-lambda-handler | |
| outputs: | |
| tf_outputs_json: ${{ steps.get-outputs.outputs.data }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.inputs.branch }} | |
| - name: Download Lambda artifact | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: lambda-build | |
| path: ./terraform-db-migration/build | |
| - uses: hashicorp/setup-terraform@v3 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Terraform Init (migration) | |
| run: terraform init | |
| working-directory: ./terraform-db-migration | |
| - name: Terraform Apply MIGRATION | |
| run: terraform apply -auto-approve | |
| working-directory: ./terraform-db-migration | |
| - name: Get Terraform Outputs | |
| id: get-outputs | |
| run: | | |
| echo "data<<EOF" >> $GITHUB_OUTPUT | |
| terraform output -json >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| working-directory: ./terraform-db-migration | |
| build-and-run-migration: | |
| name: Build Image and Run Migration Sequence | |
| runs-on: ubuntu-latest | |
| needs: terraform-apply-migration | |
| steps: | |
| - name: Checkout specific branch | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.inputs.branch }} | |
| - name: Parse Terraform Outputs and Set Env | |
| id: parse-tf | |
| run: | | |
| TF_OUTPUTS='${{ needs.terraform-apply-migration.outputs.tf_outputs_json }}' | |
| ECR_REPOSITORY=$(echo "$TF_OUTPUTS" | jq -r '.ecr_repository_name.value' | awk -F/ '{print $NF}') | |
| echo "ECR_REPOSITORY=$ECR_REPOSITORY" >> $GITHUB_ENV | |
| echo "PROD_ECS_CLUSTER_NAME=$(echo "$TF_OUTPUTS" | jq -r '.prod_ecs_cluster_name.value')" >> $GITHUB_ENV | |
| echo "PROD_ECS_SERVICE_NAME=$(echo "$TF_OUTPUTS" | jq -r '.prod_ecs_api_service_name.value')" >> $GITHUB_ENV | |
| echo "LAMBDA_FUNCTION_NAME=$(echo "$TF_OUTPUTS" | jq -r '.migration_lambda_function_name.value')" >> $GITHUB_ENV | |
| echo "VPC_SUBNET=$(echo "$TF_OUTPUTS" | jq -r '.private_subnet_id.value')" >> $GITHUB_ENV | |
| echo "TASK_SECURITY_GROUP=$(echo "$TF_OUTPUTS" | jq -r '.task_security_group_id.value')" >> $GITHUB_ENV | |
| echo "CLONED_RDS_ADDRESS=$(echo "$TF_OUTPUTS" | jq -r '.cloned_rds_address.value')" >> $GITHUB_ENV | |
| echo "CLONED_S3_BUCKET_NAME=$(echo "$TF_OUTPUTS" | jq -r '.cloned_s3_bucket_name.value')" >> $GITHUB_ENV | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: 21 | |
| java-package: jdk | |
| architecture: 'x64' | |
| cache: 'gradle' | |
| - name: Get TEST_JWT_SECRET_KEY from SSM | |
| id: get-test-secret | |
| run: | | |
| SECRET_VALUE=$(aws ssm get-parameter --name "/common/TEST_JWT_SECRET_KEY" --with-decryption --query "Parameter.Value" --output text) | |
| echo "TEST_JWT_SECRET_KEY=$SECRET_VALUE" >> $GITHUB_ENV | |
| - name: Build with Gradle | |
| run: | | |
| chmod +x gradlew | |
| ./gradlew clean build -Dspring.profiles.active=migration | |
| env: | |
| TEST_JWT_SECRET_KEY: ${{ env.TEST_JWT_SECRET_KEY }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Build, tag, and push image to Amazon ECR | |
| id: build-image | |
| env: | |
| ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
| run: | | |
| IMAGE_TAG="migration-test-$(date +'%Y%m%d-%H%M%S')" | |
| docker build -t $ECR_REGISTRY/${ECR_REPOSITORY}:${IMAGE_TAG} . | |
| docker push $ECR_REGISTRY/${ECR_REPOSITORY}:${IMAGE_TAG} | |
| echo "image_uri=$ECR_REGISTRY/${ECR_REPOSITORY}:${IMAGE_TAG}" >> $GITHUB_OUTPUT | |
| - name: Get Latest PROD Task Definition Info | |
| id: get-prod-info | |
| run: | | |
| TASK_DEF_ARN=$(aws ecs describe-services --cluster "${{ env.PROD_ECS_CLUSTER_NAME }}" --services "${{ env.PROD_ECS_SERVICE_NAME }}" --query "services[0].taskDefinition" --output text) | |
| CONTAINER_NAME=$(aws ecs describe-task-definition --task-definition "$TASK_DEF_ARN" --query "taskDefinition.containerDefinitions[0].name" --output text) | |
| echo "task_definition_arn=$TASK_DEF_ARN" >> $GITHUB_OUTPUT | |
| echo "container_name=$CONTAINER_NAME" >> $GITHUB_OUTPUT | |
| - name: Create New Task Definition with Updated Image | |
| id: update-task-def | |
| run: | | |
| TASK_DEF=$(aws ecs describe-task-definition --task-definition "${{ steps.get-prod-info.outputs.task_definition_arn }}" --query "taskDefinition") | |
| NEW_TASK_DEF=$(echo "$TASK_DEF" | jq --arg IMAGE "${{ steps.build-image.outputs.image_uri }}" ' | |
| .containerDefinitions[0].image = $IMAGE | | |
| del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .placementConstraints, .compatibilities, .registeredAt, .registeredBy) | |
| ') | |
| NEW_TASK_DEF_ARN=$(aws ecs register-task-definition --cli-input-json "$NEW_TASK_DEF" --query "taskDefinition.taskDefinitionArn" --output text) | |
| echo "new_task_definition_arn=$NEW_TASK_DEF_ARN" >> $GITHUB_OUTPUT | |
| - name: Invoke Pre-processing Lambda | |
| run: | | |
| META=$(aws lambda invoke \ | |
| --function-name "${{ env.LAMBDA_FUNCTION_NAME }}" \ | |
| --payload '{"task":"preprocess"}' \ | |
| --cli-binary-format raw-in-base64-out \ | |
| response.json) | |
| echo "$META" | jq . | |
| echo "$META" | jq -e '.FunctionError == null' >/dev/null || { echo "Preprocess Lambda failed"; exit 1; } | |
| - name: Run DB Migration ECS Task | |
| id: ecs-run-task | |
| run: | | |
| MIGRATION_RDS_URL="jdbc:mysql://${{ env.CLONED_RDS_ADDRESS }}/eatda?useUnicode=true&characterEncoding=UTF-8" | |
| TASK_ARN=$(aws ecs run-task \ | |
| --cluster ${{ env.PROD_ECS_CLUSTER_NAME }} \ | |
| --task-definition ${{ steps.update-task-def.outputs.new_task_definition_arn }} \ | |
| --launch-type EC2 \ | |
| --overrides '{ "containerOverrides": [ { "name": "${{ steps.get-prod-info.outputs.container_name }}", "environment": [ { "name": "SPRING_PROFILES_ACTIVE", "value": "migration" }, { "name": "MIGRATION_RDS_URL", "value": "'"${MIGRATION_RDS_URL}"'" }, { "name": "MIGRATION_S3_BUCKET", "value": "${{ env.CLONED_S3_BUCKET_NAME }}" } ] } ] }' \ | |
| --query "tasks[0].taskArn" --output text) | |
| echo "task_arn=$TASK_ARN" >> $GITHUB_OUTPUT | |
| if [ -z "$TASK_ARN" ] || [ "$TASK_ARN" = "None" ]; then | |
| echo "Failed to start ECS task"; exit 1; | |
| fi | |
| - name: Wait for ECS Task to Complete | |
| run: | | |
| aws ecs wait tasks-stopped --cluster ${{ env.PROD_ECS_CLUSTER_NAME }} --tasks ${{ steps.ecs-run-task.outputs.task_arn }} | |
| - name: Invoke Post-processing Lambda | |
| run: | | |
| aws lambda invoke --function-name ${{ env.LAMBDA_FUNCTION_NAME }} --payload '{"task": "postprocess"}' response.json | |
| # notify: | |
| # name: Send Discord Notification (Migration) | |
| # runs-on: ubuntu-latest | |
| # needs: build-and-run-migration | |
| # if: always() | |
| # steps: | |
| # - name: Prepare Notification Info | |
| # id: vars | |
| # run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| # | |
| # - name: Discord Notify (Success) | |
| # if: needs.build-and-run-migration.result == 'success' | |
| # uses: tsickert/[email protected] | |
| # with: | |
| # webhook-url: ${{ secrets.DISCORD_WEBHOOK }} | |
| # embed-title: "✅ Migration Test 배포 성공!" | |
| # embed-color: 65280 | |
| # embed-description: | | |
| # 마이그레이션 테스트 환경이 성공적으로 구축되었습니다. | |
| # **커밋**: [${{ steps.vars.outputs.sha_short }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) | |
| # **실행자**: ${{ github.actor }} | |
| # embed-url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| # | |
| # - name: Discord Notify (Failure) | |
| # if: needs.build-and-run-migration.result != 'success' | |
| # uses: tsickert/[email protected] | |
| # with: | |
| # webhook-url: ${{ secrets.DISCORD_WEBHOOK }} | |
| # embed-title: "❌ Migration Test 배포 실패!" | |
| # embed-color: 16711680 | |
| # embed-description: | | |
| # 마이그레이션 테스트 환경 구축중 오류가 발생했습니다. | |
| # **커밋**: [${{ steps.vars.outputs.sha_short }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) | |
| # **실행자**: ${{ github.actor }} | |
| # embed-url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" |