feat: DB EC2의 백업 관리용 S3 버킷 생성 (#69) #18
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: Terraform Apply | |
| on: | |
| push: | |
| branches: [main] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| env: | |
| TF_VERSION: "1.10.5" | |
| SSM_TUNNEL_TIMEOUT: "60" | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| bootstrap: ${{ steps.filter.outputs.bootstrap }} | |
| global: ${{ steps.filter.outputs.global }} | |
| prod: ${{ steps.filter.outputs.prod }} | |
| stage: ${{ steps.filter.outputs.stage }} | |
| monitoring: ${{ steps.filter.outputs.monitoring }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| bootstrap: | |
| - 'bootstrap/**' | |
| global: | |
| - 'environment/global/**' | |
| - 'modules/shared_resources/**' | |
| - 'config/secrets' | |
| prod: | |
| - 'environment/prod/**' | |
| - 'modules/app_stack/**' | |
| - 'modules/common/**' | |
| - 'config/secrets' | |
| stage: | |
| - 'environment/stage/**' | |
| - 'modules/app_stack/**' | |
| - 'modules/common/**' | |
| - 'config/secrets' | |
| monitoring: | |
| - 'environment/monitoring/**' | |
| - 'modules/monitoring_stack/**' | |
| - 'modules/common/**' | |
| - 'config/secrets' | |
| apply-bootstrap: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.bootstrap == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| persist-credentials: false | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ap-northeast-2 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Terraform Init | |
| working-directory: bootstrap | |
| run: terraform init | |
| - name: Terraform Apply | |
| working-directory: bootstrap | |
| run: terraform apply -auto-approve | |
| apply-global: | |
| needs: [detect-changes, apply-bootstrap] | |
| if: | | |
| always() && | |
| needs.detect-changes.outputs.global == 'true' && | |
| (needs.apply-bootstrap.result == 'success' || needs.apply-bootstrap.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| persist-credentials: false | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ap-northeast-2 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Terraform Init | |
| working-directory: environment/global | |
| run: terraform init | |
| - name: Terraform Apply | |
| working-directory: environment/global | |
| run: | | |
| terraform apply -auto-approve \ | |
| -var-file="../../config/secrets/shared_resources.tfvars" | |
| apply-prod: | |
| needs: [detect-changes, apply-bootstrap] | |
| if: | | |
| always() && | |
| needs.detect-changes.outputs.prod == 'true' && | |
| (needs.apply-bootstrap.result == 'success' || needs.apply-bootstrap.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| persist-credentials: false | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ap-northeast-2 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Install Session Manager Plugin | |
| run: | | |
| curl -sL "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" \ | |
| -o /tmp/session-manager-plugin.deb | |
| sudo dpkg -i /tmp/session-manager-plugin.deb | |
| echo "/usr/local/sessionmanagerplugin/bin" >> $GITHUB_PATH | |
| /usr/local/sessionmanagerplugin/bin/session-manager-plugin --version | |
| - name: Start SSM Tunnel to DB EC2 | |
| run: | | |
| echo "=== session-manager-plugin 진단 ===" | |
| which session-manager-plugin || echo "NOT IN PATH" | |
| session-manager-plugin --version || echo "VERSION CHECK FAILED" | |
| echo "====================================" | |
| EC2_ID=$(aws ec2 describe-instances \ | |
| --filters "Name=tag:Name,Values=solid-connection-server-prod" "Name=instance-state-name,Values=running" \ | |
| --query 'Reservations[0].Instances[0].InstanceId' \ | |
| --output text) | |
| DB_EC2_HOST=$(aws ec2 describe-instances \ | |
| --filters "Name=tag:Name,Values=solid-connection-db-mysql-prod" "Name=instance-state-name,Values=running" \ | |
| --query 'Reservations[0].Instances[0].PrivateIpAddress' \ | |
| --output text) | |
| if [ -z "$EC2_ID" ] || [ "$EC2_ID" = "None" ]; then | |
| echo "::error::prod EC2 인스턴스를 찾을 수 없습니다" | |
| exit 1 | |
| fi | |
| if [ -z "$DB_EC2_HOST" ] || [ "$DB_EC2_HOST" = "None" ]; then | |
| echo "::error::prod DB EC2 private IP를 찾을 수 없습니다" | |
| exit 1 | |
| fi | |
| echo "Tunneling via $EC2_ID -> $DB_EC2_HOST:3306" | |
| aws ssm start-session \ | |
| --target "$EC2_ID" \ | |
| --document-name AWS-StartPortForwardingSessionToRemoteHost \ | |
| --parameters "{\"host\":[\"$DB_EC2_HOST\"],\"portNumber\":[\"3306\"],\"localPortNumber\":[\"3306\"]}" & | |
| SSM_PID=$! | |
| echo "SSM_PID=$SSM_PID" >> $GITHUB_ENV | |
| for i in $(seq 1 $SSM_TUNNEL_TIMEOUT); do | |
| if ! kill -0 $SSM_PID 2>/dev/null; then | |
| echo "::error::SSM 세션이 터널 준비 전에 종료되었습니다" | |
| exit 1 | |
| fi | |
| if nc -z 127.0.0.1 3306 2>/dev/null; then | |
| echo "SSM tunnel ready (${i}s)" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| if ! nc -z 127.0.0.1 3306 2>/dev/null; then | |
| echo "::error::${SSM_TUNNEL_TIMEOUT}초 내에 터널이 준비되지 않았습니다" | |
| kill $SSM_PID 2>/dev/null || true | |
| exit 1 | |
| fi | |
| if ! kill -0 $SSM_PID 2>/dev/null; then | |
| echo "::error::포트는 열렸으나 SSM 세션이 이미 종료되었습니다" | |
| exit 1 | |
| fi | |
| - name: Terraform Init | |
| working-directory: environment/prod | |
| run: terraform init | |
| - name: Terraform Apply | |
| working-directory: environment/prod | |
| run: | | |
| terraform apply -auto-approve \ | |
| -var-file="../../config/secrets/prod.tfvars" \ | |
| -var-file="../../config/secrets/prod_db.tfvars" \ | |
| -var-file="../../config/secrets/app_stack.tfvars" | |
| - name: Stop SSM Tunnel | |
| if: always() | |
| run: kill $SSM_PID 2>/dev/null || true | |
| apply-stage: | |
| needs: [detect-changes, apply-bootstrap] | |
| if: | | |
| always() && | |
| needs.detect-changes.outputs.stage == 'true' && | |
| (needs.apply-bootstrap.result == 'success' || needs.apply-bootstrap.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| persist-credentials: false | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ap-northeast-2 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Terraform Init | |
| working-directory: environment/stage | |
| run: terraform init | |
| - name: Terraform Apply | |
| working-directory: environment/stage | |
| run: | | |
| terraform apply -auto-approve \ | |
| -var-file="../../config/secrets/stage.tfvars" \ | |
| -var-file="../../config/secrets/app_stack.tfvars" | |
| apply-monitoring: | |
| needs: [detect-changes, apply-bootstrap] | |
| if: | | |
| always() && | |
| needs.detect-changes.outputs.monitoring == 'true' && | |
| (needs.apply-bootstrap.result == 'success' || needs.apply-bootstrap.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.GH_PAT }} | |
| persist-credentials: false | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ap-northeast-2 | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| terraform_wrapper: false | |
| - name: Terraform Init | |
| working-directory: environment/monitoring | |
| run: terraform init | |
| - name: Terraform Apply | |
| working-directory: environment/monitoring | |
| run: | | |
| terraform apply -auto-approve \ | |
| -var-file="../../config/secrets/monitoring.tfvars" \ | |
| -var-file="../../config/secrets/monitoring_stack.tfvars" |