Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a3bf2b7
fix: 올바르지 않은 버킷에 대한 람다 실행 권한 부여 내용 수정
Hexeong Apr 28, 2026
29003a9
fix: 기존 AWS 실제 resource에 맞지 않는 stage rds 부분에 대한 정의 제거
Hexeong Apr 28, 2026
42a5484
feat: tfstate 버킷 관리 및 Github Action용 s3/iam 정의
Hexeong Apr 28, 2026
1e3ab68
feat: tfstate 파일들에 대한 관리를 S3 백엔드로 변경
Hexeong Apr 28, 2026
308b21d
refactor: prod/stage 환경 terraform 코드 최신화
Hexeong Apr 28, 2026
bac30ef
feat: Github Action 정의
Hexeong Apr 28, 2026
3544783
fix: terraform plan 결과에 대한 수정
Hexeong Apr 28, 2026
d62a9ea
fix: 코드래빗 반영
Hexeong Apr 28, 2026
a10ea70
fix: prod환경에 대한 ssm 터널링 문제(플러그인 설치 방식 오류) 해결
Hexeong Apr 28, 2026
b9e3fd9
fix: 코드 리뷰 반영 및 prod 환경에 대한 terraform 워크플로우 수정
Hexeong Apr 28, 2026
66eb913
fix: prod 환경에 대한 terraform 워크플로우 수정
Hexeong Apr 28, 2026
dccf84f
fix: prod 환경에 대한 terraform 워크플로우 수정
Hexeong Apr 28, 2026
5ec981d
fix: prod 환경에 대한 terraform 워크플로우 수정
Hexeong Apr 28, 2026
1e636ab
fix: prod 환경에 대한 terraform 워크플로우 수정 & 코드래빗 반영
Hexeong Apr 28, 2026
7f078d0
fix: 코드래빗 반영
Hexeong Apr 28, 2026
d45a117
fix: pr에서 aws 리소스에 접근할 수 있는 권한을 read 용도로 축소 및 apply와의 역할 분리
Hexeong May 3, 2026
0c7b91b
fix: 시크릿파일들에 대한 변경에 대해 워크플로우 필터가 정상 작동하도록 수정
Hexeong May 4, 2026
09cc257
fix: global 환경에서의 s3 버킷 통합 수정 이력에 대한 terraform 코드 최신화
Hexeong May 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
language: ko-KR

reviews:
auto_review:
enabled: false

path_instructions:
- path: "**/*.tf"
instructions: |
이 PR의 Terraform 코드 변경을 리뷰합니다.
PR 댓글에 올라온 각 환경의 "Terraform Plan" 결과를 반드시 확인하고, 코드 변경과 plan 결과가 일치하는지 검토하세요.

다음 항목을 중점적으로 검토하세요:
- plan에 예상치 못한 resource destroy 또는 replace가 포함된 경우
- 보안 그룹(Security Group) 인바운드/아웃바운드 규칙 변경
- IAM 권한이 과도하게 부여된 경우 (최소 권한 원칙)
- 민감한 값(비밀번호, 키 등)이 코드에 하드코딩된 경우
- `lifecycle.ignore_changes` 설정이 의도에 맞게 사용되었는지
269 changes: 269 additions & 0 deletions .github/workflows/terraform-apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
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/shared_resources.tfvars'
prod:
- 'environment/prod/**'
- 'modules/app_stack/**'
- 'modules/common/**'
- 'config/secrets/prod.tfvars'
- 'config/secrets/app_stack.tfvars'
stage:
- 'environment/stage/**'
- 'modules/app_stack/**'
- 'modules/common/**'
- 'config/secrets/stage.tfvars'
- 'config/secrets/app_stack.tfvars'
monitoring:
- 'environment/monitoring/**'
- 'modules/monitoring_stack/**'
- 'modules/common/**'
- 'config/secrets/monitoring.tfvars'
- 'config/secrets/monitoring_stack.tfvars'

apply-bootstrap:
needs: detect-changes
if: needs.detect-changes.outputs.bootstrap == 'true'
runs-on: ubuntu-latest
Comment thread
coderabbitai[bot] marked this conversation as resolved.
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 RDS
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)

RDS_HOST=$(aws rds describe-db-instances \
--query 'DBInstances[?contains(DBInstanceIdentifier, `prod`)].Endpoint.Address | [0]' \
--output text)

if [ -z "$EC2_ID" ] || [ "$EC2_ID" = "None" ]; then
echo "::error::prod EC2 인스턴스를 찾을 수 없습니다"
exit 1
fi
if [ -z "$RDS_HOST" ] || [ "$RDS_HOST" = "None" ]; then
echo "::error::prod RDS 엔드포인트를 찾을 수 없습니다"
exit 1
fi

echo "Tunneling via $EC2_ID -> $RDS_HOST:3306"

aws ssm start-session \
--target "$EC2_ID" \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters "{\"host\":[\"$RDS_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/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"
Loading
Loading