-
Notifications
You must be signed in to change notification settings - Fork 1
Deployment and Operations
전환 안내. 아래의 엄격한 prod 버전 검증, metadata 선보존, tag·Release 복구 절차는 backend issue #306의 workflow가
main에 반영된 뒤 적용됩니다. 반영 전에는main의 실제 workflow를 기준으로 판단합니다.
dev와 prod Lambda 배포는 수동 workflow_dispatch입니다. dev는 Lambda Version과 Alias만 갱신하며 버전 릴리즈를 게시하지 않습니다. prod는 배포 전 preflight를 거치고 Alias 검증 후 Summary와 metadata artifact를 보존한 다음 Git 태그와 GitHub Release를 게시합니다.
flowchart TB
subgraph Dev["dev 배포"]
DevTrigger["workflow_dispatch"] --> DevMigration["Flyway info + migrate"]
DevMigration --> DevDeploy["Test → Build → S3 → Lambda Version"]
DevDeploy --> DevAlias["Alias 이동·검증"] --> DevDone["배포 완료<br/>버전 릴리즈 없음"]
end
subgraph Prod["prod 배포"]
ProdTrigger["main workflow_dispatch<br/>MAJOR.MINOR.PATCH 입력"] --> Preflight["preflight<br/>main·버전 형식·중복 태그 검증"]
Preflight --> ProdMigration["Flyway info + migrate<br/>이전 코드 호환 migration"]
ProdMigration --> ProdDeploy["Test → Build → S3 → Lambda Version"]
ProdDeploy --> ProdAlias["Alias 이동·검증"] --> Summary["Actions Summary 작성"]
Summary --> Metadata["deployment metadata<br/>artifact 업로드"]
Metadata --> Tag["be-v{버전}<br/>annotated tag push"] --> Release["GitHub Release<br/>추적 본문 포함"]
end
사용하는 Workflow입니다.
| Workflow | 용도 |
|---|---|
CI (Gradle) |
dev, main push·PR에서 ./gradlew check
|
Flyway Migration for DB schema |
dev·prod DB 마이그레이션 단독 실행 |
Deploy to Dev Lambda |
dev 마이그레이션 후 Lambda 배포 |
Deploy to Prod Lambda |
prod 마이그레이션 후 Lambda 배포 |
Repository Variables입니다.
- dev는
DEV_AWS_REGION,DEV_LAMBDA_FUNCTION_NAME,DEV_LAMBDA_ALIAS,DEV_LAMBDA_ARTIFACT_BUCKET을 사용합니다. - prod는
PROD_AWS_REGION,PROD_LAMBDA_FUNCTION_NAME,PROD_LAMBDA_ALIAS,PROD_LAMBDA_ARTIFACT_BUCKET을 사용합니다.
Secrets입니다.
- AWS 배포는
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY를 사용합니다. - Flyway dev는
DEV_FLYWAY_DB_URL,DEV_FLYWAY_DB_USER,DEV_FLYWAY_DB_PASSWORD를 사용합니다. - Flyway prod는
PROD_FLYWAY_DB_URL,PROD_FLYWAY_DB_USER,PROD_FLYWAY_DB_PASSWORD를 사용합니다.
값을 Wiki나 Actions 로그에 출력하지 않습니다.
- 대상 변경이
dev에 포함됐는지 확인합니다. - Actions에서
Deploy to Dev Lambda를 선택합니다. - 실행할 ref를 확인하고 Workflow를 시작합니다.
-
Migrate dev DB schema가 성공했는지 확인합니다. - 테스트, ZIP 생성, S3 업로드, Lambda Version 게시를 확인합니다.
- Summary의 Published Version과 Alias Version이 같은지 확인합니다.
- dev Health, Swagger, 변경 endpoint를 smoke test합니다.
dev 배포 Workflow는 Lambda 코드와 Alias만 갱신합니다. 런타임 환경 변수, IAM, Layer, Extension은 관리하지 않습니다. dev 배포 전에도 대상 Lambda의 SPRING_PROFILES_ACTIVE, DB, SQS, HMAC, S3 설정을 별도로 확인합니다.
prod Workflow는 main에서만 실행합니다. Actions 실행 ref가 다르면 preflight에서 실패하며 Migration을 시작하지 않습니다. Workflow 안의 마이그레이션은 prod GitHub Environment의 승인 규칙을 따릅니다.
실행할 때 각 숫자가 0 또는 선행 0 없는 양의 정수인 최종 MAJOR.MINOR.PATCH를 입력합니다. 01.2.3 같은 선행 0, 축약 버전, prerelease와 build suffix는 허용하지 않습니다. preflight는 버전 형식과 기존 be-v{버전} 태그 중복을 Migration 전에 검사합니다.
Workflow dispatch 시점의 main commit SHA를 배포 단위로 고정합니다. Migration, Lambda build, S3 Object, Git 태그와 GitHub Release가 모두 같은 commit SHA를 사용합니다.
-
dev에서 만든release/v{버전}의 QA와fix/*반영을 끝내고 해당 버전을 확정합니다. - release 브랜치를
main에 병합한 뒤 확정한 버전과 같은 값을 prod Workflow에 입력합니다. - 운영 배포가 끝나면
main을dev에 역병합해 release QA 수정이 다음 릴리즈에서 사라지지 않게 합니다.
-
hotfix/*는main에서 생성하고 prod Workflow 실행 전에 반드시main에 병합합니다. - 마지막으로 성공한
be-v*릴리즈의 PATCH를 증가한 버전을 확인하고 승인합니다. 예를 들어 마지막 성공 버전이be-v1.2.3이면1.2.4를 사용합니다. - 운영 배포가 끝나면
main을dev와 진행 중인 모든release/*브랜치에 역병합합니다.
prod Flyway migration은 배포 직전까지 트래픽을 처리하는 이전 Lambda 코드와 backward compatible해야 합니다. Migration 성공 뒤 테스트·빌드·Lambda 게시가 실패하면 이전 Alias가 계속 트래픽을 처리하므로 새 schema에서 이전 코드가 정상 동작해야 합니다.
확인 순서입니다.
- 정식 release 또는 hotfix의 사전 조건을 충족했고 대상 변경이
main에 포함됐는지 확인합니다. - Actions에서
Deploy to Prod Lambda의 ref를main으로 선택하고 승인한 버전을 입력해 수동 실행합니다. - preflight에서
main, 엄격한 버전 형식,be-v{버전}태그 중복 검증이 성공했는지 확인합니다. - Flyway
info에서 예상한 버전만 Pending이고 이전 Lambda 코드와 호환되는지 확인합니다. - Migration, Test, Build, Publish가 모두 성공했는지 확인합니다.
- Alias가 새 Version을 가리키는지 확인합니다.
- Alias 검증 뒤 Actions Summary와 deployment metadata artifact가 생성됐는지 확인합니다.
- 같은 commit SHA에
be-v{버전}annotated tag와 GitHub Release가 생성됐는지 확인합니다. Release 본문의 제품 버전, commit SHA, Lambda published version과 alias version도 대조합니다. -
/health,/actuator/health, 핵심 인증 API를 확인합니다. - Sentry와 CloudWatch에서 새 오류가 증가하지 않는지 확인합니다.
prod Lambda에는 다음 런타임 설정이 외부 인프라에서 명시돼야 합니다.
-
SPRING_PROFILES_ACTIVE=prod. - prod DB와 OIDC·JWT 설정.
- prod SQS Queue URL과 HMAC Secret.
- prod S3 Bucket, Prefix, Region.
application.yml의 S3 기본값은 develop-shadow용입니다. prod에서 SCRAPING_RESULT_BUCKET과 SCRAPING_RESULT_PREFIX를 생략하면 잘못된 환경의 결과를 보게 될 수 있습니다.
lambdaZip은 다음 파일을 만듭니다.
build/distributions/haksa-lambda.zip
Workflow는 commit SHA를 포함한 S3 Key로 ZIP을 올리고 새 Lambda Version을 게시합니다. Alias 검증이 성공하면 태그와 Release를 게시하기 전에 Actions Summary와 deployment metadata artifact에 release version, release tag, commit SHA, function, alias, S3 key, published version, alias version을 기록합니다. GitHub Release 본문에도 제품 버전, commit SHA, Lambda published version과 alias version을 기록하고 자동 생성 릴리즈 노트를 함께 유지합니다.
Alias 검증 전에 실패하면 배포 실패이며 태그와 GitHub Release가 생기지 않습니다. Alias 검증 뒤 태그 또는 Release 게시가 실패하면 Lambda 배포는 성공했지만 릴리즈 기록 게시가 실패한 부분 성공입니다.
태그 push는 성공했지만 GitHub Release 생성만 실패했다면 다음 값이 모두 일치할 때 같은 태그에 Release만 복구합니다. 이미 게시한 태그는 삭제하거나 다른 commit으로 이동하지 않습니다.
- 실패한 Actions run의
headSha. - annotated tag를 역참조한 commit SHA.
- metadata artifact의
commit_sha,published_version,alias_version. - 현재 Lambda Alias가 가리키는 Version.
다음 명령은 실패한 run과 artifact를 조회해 Release만 복구하는 예시입니다.
RUN_ID="<실패한 Actions run ID>"
artifact_dir="$(mktemp -d)"
gh run download "$RUN_ID" \
--name prod-lambda-deployment-metadata \
--dir "$artifact_dir"
metadata_file="$artifact_dir/prod-lambda-deployment.txt"
metadata_value() {
awk -F= -v key="$1" '$1 == key { sub(/^[^=]*=/, ""); print; exit }' "$metadata_file"
}
release_version="$(metadata_value release_version)"
release_tag="$(metadata_value release_tag)"
commit_sha="$(metadata_value commit_sha)"
function_name="$(metadata_value function_name)"
alias_name="$(metadata_value alias)"
published_version="$(metadata_value published_version)"
alias_version="$(metadata_value alias_version)"
run_sha="$(gh run view "$RUN_ID" --json headSha --jq '.headSha')"
git fetch origin "refs/tags/$release_tag:refs/tags/$release_tag"
tag_sha="$(git rev-parse "$release_tag^{commit}")"
live_alias_version="$(aws lambda get-alias \
--function-name "$function_name" \
--name "$alias_name" \
--query 'FunctionVersion' \
--output text)"
test "$run_sha" = "$commit_sha"
test "$tag_sha" = "$commit_sha"
test "$published_version" = "$alias_version"
test "$live_alias_version" = "$alias_version"
release_notes=$(printf -- '- Product version: `%s`\n- Commit SHA: `%s`\n- Lambda published version: `%s`\n- Lambda alias version: `%s`\n' \
"$release_version" \
"$commit_sha" \
"$published_version" \
"$alias_version")
gh release create "$release_tag" \
--verify-tag \
--target "$commit_sha" \
--title "$release_tag" \
--generate-notes \
--notes "$release_notes"값이 다르거나 이미 Release가 있으면 중단하고 후속 배포 또는 수동 변경 여부를 먼저 확인합니다. 부분 성공을 복구하려고 prod Workflow를 다시 실행하거나 태그를 다시 만들지 않습니다.
애플리케이션 롤백은 직전 정상 Lambda Version으로 Alias를 되돌리는 방식입니다. 이전 Version은 Actions Summary와 deployment metadata artifact에서 확인합니다.
aws lambda update-alias \
--function-name "$LAMBDA_FUNCTION_NAME" \
--name "$LAMBDA_ALIAS" \
--function-version "$PREVIOUS_VERSION"
aws lambda get-alias \
--function-name "$LAMBDA_FUNCTION_NAME" \
--name "$LAMBDA_ALIAS" \
--query 'FunctionVersion' \
--output textDB 마이그레이션은 Lambda Alias와 함께 자동 롤백되지 않습니다. 적용된 Migration 파일도 되돌려 수정하지 않습니다. 스키마 보정은 데이터 보존과 이전 애플리케이션 호환성을 확인한 다음 version의 forward migration으로 수행합니다.
같은 Lambda Handler는 HTTP API 외에 EventBridge Scheduler event도 처리합니다. source=eventbridge.scheduler이고 task가 있으면 다음 작업을 실행합니다.
-
SCRAPE_JOB_RECONCILE_STALE은 오래된 포털 작업을 callback timeout으로 종료합니다. -
REFRESH_TOKEN_CLEANUP은 만료된 Refresh Token을 정리합니다.
Scheduler 리소스 정의는 이 저장소에 없습니다. 유지보수 작업이 실행되는지는 배포된 EventBridge Scheduler target과 Lambda invoke 권한을 확인해야 합니다.
curl -sS https://api.cchaksa.com/health
curl -sS https://api.cchaksa.com/actuator/health
curl -sS https://api.cchaksa.com/v3/api-docs포털 장애는 jobId를 시작점으로 찾습니다. 다음 값을 함께 연결합니다.
-
jobId. -
outboxId. -
queueMessageId. -
workerRequestId. -
operationType.
| 도구 | 우선 확인할 내용 |
|---|---|
| GitHub Actions | Migration, Test, Build, Alias 변경 |
| CloudWatch Logs | Lambda platform 로그와 stdout·stderr. prod file 로그 수집 여부는 외부 설정 확인 |
| Sentry | 예외 Stack Trace와 MDC tag |
| Grafana Cloud | 활성화된 OTLP Metric과 외부 전달 로그. 현재 앱의 OTLP Trace exporter는 제외됨 |
| PostgreSQL | 작업·Outbox 상태와 학사 데이터 반영 결과 |
Grafana metric이나 Sentry event가 없다는 사실만으로 요청이 없었다고 단정하지 않습니다. 수집 설정과 Lambda 로그를 먼저 확인합니다.
prod Logback은 기본적으로 /var/log/app 파일과 Sentry에 기록하며 Console appender가 없습니다. Lambda에서 file 로그를 수집하려면 쓰기 가능한 LOG_PATH와 Telemetry Extension 또는 별도 전달 설정이 필요합니다. 해당 인프라 정의는 이 저장소에 없으므로 실제 Lambda 설정을 확인해야 합니다.