1+ terraform {
2+ required_providers {
3+ google = {
4+ source = " hashicorp/google"
5+ version = " >= 5.0"
6+ }
7+ }
8+ backend "gcs" {
9+ # [주의] 본인의 버킷 이름으로 유지하세요!
10+ bucket = " stiky-terraform-state-wonjun"
11+ prefix = " prod"
12+ }
13+ }
14+
15+ provider "google" {
16+ project = var. project_id
17+ region = var. region
18+ }
19+
20+ # 0. VPC 네트워크 설정 (Private IP 사용을 위한 필수 설정)
21+ # 구글 서비스용 내부 IP 대역 예약
22+ resource "google_compute_global_address" "private_ip_address" {
23+ name = " private-ip-address"
24+ purpose = " VPC_PEERING"
25+ address_type = " INTERNAL"
26+ prefix_length = 16
27+ network = " default"
28+ }
29+
30+ # VPC와 구글 서비스 간 피어링 연결
31+ resource "google_service_networking_connection" "private_vpc_connection" {
32+ network = " default"
33+ service = " servicenetworking.googleapis.com"
34+ reserved_peering_ranges = [google_compute_global_address . private_ip_address . name ]
35+ }
36+
37+ # 1. Artifact Registry (이미지 저장소)
38+ resource "google_artifact_registry_repository" "repo" {
39+ location = var. region
40+ repository_id = " stiky-repo"
41+ format = " DOCKER"
42+ }
43+
44+ # 2. Cloud SQL (MySQL)
45+ resource "google_sql_database_instance" "master" {
46+ name = " stiky-mysql-prod-${ random_id . suffix . hex } "
47+ database_version = " MYSQL_8_0"
48+ region = var. region
49+ deletion_protection = true
50+
51+ settings {
52+ tier = " db-f1-micro"
53+ ip_configuration {
54+ ipv4_enabled = false
55+ private_network = " projects/${ var . project_id } /global/networks/default"
56+ }
57+ }
58+
59+ # [중요] 네트워크 연결이 끝난 뒤에 DB를 만들어야 에러가 안 남
60+ depends_on = [google_service_networking_connection . private_vpc_connection ]
61+ }
62+
63+ resource "random_id" "suffix" {
64+ byte_length = 4
65+ }
66+
67+ resource "google_sql_database" "database" {
68+ name = " stiky"
69+ instance = google_sql_database_instance. master . name
70+ }
71+
72+ resource "google_sql_user" "users" {
73+ name = " wonjun"
74+ instance = google_sql_database_instance. master . name
75+ password = " temp-password"
76+ }
77+
78+ # 3. Redis (Memorystore)
79+ resource "google_redis_instance" "cache" {
80+ name = " stiky-redis-prod"
81+ memory_size_gb = 1
82+ region = var. region
83+
84+ # Redis도 Private IP를 쓰므로 네트워크 연결에 의존성을 둠
85+ depends_on = [google_service_networking_connection . private_vpc_connection ]
86+ }
87+
88+ # 4. Cloud Run (애플리케이션)
89+ resource "google_cloud_run_v2_service" "default" {
90+ name = " stiky-api"
91+ location = var. region
92+ ingress = " INGRESS_TRAFFIC_ALL"
93+
94+ template {
95+ vpc_access {
96+ network_interfaces {
97+ network = " default"
98+ subnetwork = " default"
99+ }
100+ egress = " ALL_TRAFFIC"
101+ }
102+
103+ containers {
104+ image = " ${ var . region } -docker.pkg.dev/${ var . project_id } /${ google_artifact_registry_repository . repo . name } /stiky-api:latest"
105+
106+ ports { container_port = 8080 }
107+
108+ env {
109+ name = " SPRING_PROFILES_ACTIVE"
110+ value = " prod"
111+ }
112+ env {
113+ name = " DB_HOST"
114+ value = google_sql_database_instance. master . private_ip_address
115+ }
116+ env {
117+ name = " DB_NAME"
118+ value = google_sql_database. database . name
119+ }
120+ env {
121+ name = " DB_USER"
122+ value = google_sql_user. users . name
123+ }
124+ env {
125+ name = " REDIS_HOST"
126+ value = google_redis_instance. cache . host
127+ }
128+
129+ env {
130+ name = " DB_PASS"
131+ value_source {
132+ secret_key_ref {
133+ secret = " DB_PASS"
134+ version = " latest"
135+ }
136+ }
137+ }
138+ env {
139+ name = " JWT_SECRET"
140+ value_source {
141+ secret_key_ref {
142+ secret = " JWT_SECRET"
143+ version = " latest"
144+ }
145+ }
146+ }
147+ env {
148+ name = " GOOGLE_CLIENT_ID"
149+ value_source {
150+ secret_key_ref {
151+ secret = " GOOGLE_CLIENT_ID"
152+ version = " latest"
153+ }
154+ }
155+ }
156+ env {
157+ name = " GOOGLE_CLIENT_SECRET"
158+ value_source {
159+ secret_key_ref {
160+ secret = " GOOGLE_CLIENT_SECRET"
161+ version = " latest"
162+ }
163+ }
164+ }
165+ }
166+ }
167+
168+ lifecycle {
169+ ignore_changes = [
170+ client ,
171+ client_version ,
172+ template [0 ]. containers [0 ]. image
173+ ]
174+ }
175+ }
176+
177+ # 5. 도메인 매핑
178+ resource "google_cloud_run_domain_mapping" "default" {
179+ location = var. region
180+ name = " www.stiky.site"
181+ metadata { namespace = var. project_id }
182+ spec { route_name = google_cloud_run_v2_service. default . name }
183+ }
0 commit comments