😸
Maintenance Routing
네, 심야 유지보수를 위한 sorry 페이지 설정 방법을 설명드리겠습니다.
- 먼저 sorry 페이지용 Cloud Storage 버킷을 생성합니다:
modules/maintenance/storage.tf
resource "google_storage_bucket" "maintenance_page" {
name = "maintenance-page-bucket"
location = "ASIA-NORTHEAST1"
force_destroy = true
uniform_bucket_level_access = true
website {
main_page_suffix = "index.html"
not_found_page = "404.html"
}
}
# sorry 페이지용 IAM 설정
resource "google_storage_bucket_iam_member" "public_read" {
bucket = google_storage_bucket.maintenance_page.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
- Cloud Scheduler를 사용하여 유지보수 모드 전환을 자동화합니다:
modules/maintenance/scheduler.tf
resource "google_cloud_scheduler_job" "maintenance_start" {
name = "maintenance-mode-start"
schedule = "0 4 * * *" # 매일 04:00
time_zone = "Asia/Tokyo"
http_target {
http_method = "POST"
uri = "https://cloudfunctions.googleapis.com/v1/projects/${var.project_id}/locations/${var.region}/functions/switchMaintenanceMode"
oidc_token {
service_account_email = google_service_account.maintenance_sa.email
}
body = base64encode(jsonencode({
"maintenance_mode": "on"
}))
}
}
resource "google_cloud_scheduler_job" "maintenance_end" {
name = "maintenance-mode-end"
schedule = "0 6 * * *" # 매일 06:00
time_zone = "Asia/Tokyo"
http_target {
http_method = "POST"
uri = "https://cloudfunctions.googleapis.com/v1/projects/${var.project_id}/locations/${var.region}/functions/switchMaintenanceMode"
oidc_token {
service_account_email = google_service_account.maintenance_sa.email
}
body = base64encode(jsonencode({
"maintenance_mode": "off"
}))
}
}
- Cloud Load Balancer 설정을 수정하여 유지보수 모드를 지원합니다:
modules/loadbalancer/main.tf
resource "google_compute_url_map" "main" {
name = "main-url-map"
default_service = google_compute_backend_bucket.main_backend.id
host_rule {
hosts = ["${var.domain}"]
path_matcher = "main-paths"
}
path_matcher {
name = "main-paths"
default_service = google_compute_backend_bucket.main_backend.id
path_rule {
paths = ["/api/*"]
service = google_compute_backend_service.cloudrun_backend.id
}
}
# 유지보수 모드용 조건부 라우팅
header_action {
request_headers_to_remove = ["maintenance-mode"]
response_headers_to_add {
header_name = "X-Maintenance-Mode"
header_value = "{maintenance_mode}"
replace = true
}
}
}
# Cloud Armor 보안 정책 수정
resource "google_compute_security_policy" "policy" {
name = "maintenance-security-policy"
# 기존 IP 제한 규칙
rule {
action = "allow"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = var.allowed_ip_ranges
}
}
}
# 유지보수 모드 시 모든 트래픽을 sorry 페이지로 리다이렉트
rule {
action = "redirect"
priority = "900"
match {
expr {
expression = "has(headers.maintenance-mode) && headers.maintenance-mode.contains('on')"
}
}
redirect_options {
type = "EXTERNAL_302"
target = "https://${var.domain}/maintenance.html"
}
}
}
- 유지보수 모드 전환을 위한 Cloud Function:
modules/maintenance/function/main.py
from google.cloud import storage
import functions_framework
@functions_framework.http
def switch_maintenance_mode(request):
mode = request.get_json().get('maintenance_mode')
# Load Balancer의 헤더 규칙 업데이트
# (여기서는 예시로 Cloud Storage의 메타데이터를 사용)
storage_client = storage.Client()
bucket = storage_client.bucket('maintenance-page-bucket')
blob = bucket.blob('maintenance.txt')
if mode == 'on':
blob.upload_from_string('maintenance')
else:
blob.delete()
return {'status': 'success', 'mode': mode}
- IAP 설정 유지:
modules/iap/main.tf
resource "google_iap_web_backend_service_iam_binding" "binding" {
project = var.project_id
web_backend_service = google_compute_backend_service.cloudrun_backend.name
role = "roles/iap.httpsResourceAccessor"
members = var.allowed_members
}
주요 특징:
- 유지보수 시간에 자동으로 sorry 페이지로 전환
- Cloud Armor를 통한 IP 제한 유지
- IAP 인증 유지
- Cloud Scheduler를 통한 자동 전환
- 기존 인프라 구성 유지
설정 순서:
- sorry 페이지를 Cloud Storage에 업로드
- Cloud Scheduler로 유지보수 시간 설정
- Load Balancer와 Cloud Armor 규칙 수정
- Cloud Function 배포
이렇게 설정하면:
- 평상시: 일반 서비스 제공
- 유지보수 시간(04:00-06:00): 모든 요청이 sorry 페이지로 리다이렉트
- IP 제한과 IAP 인증은 계속 유지됨
Discussion