From 7ba5f6e911ef1f0915af6705c6256a6cf7c83e67 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:16:35 +0900 Subject: [PATCH 01/11] =?UTF-8?q?chore:=20GCP,=20Cloudflare=20Terraform=20?= =?UTF-8?q?provider=20=EC=B4=88=EA=B8=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/main.tf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 terraform/main.tf diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 00000000..9fa928de --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,23 @@ +terraform { + required_version = ">= 1.6.0" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 5.0" + } + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 4.0" + } + } +} + +provider "google" { + project = var.gcp_project_id + region = var.gcp_region +} + +provider "cloudflare" { + api_token = var.cloudflare_api_token +} \ No newline at end of file From 55dc60aae4d4bff4ce79ec6dff9e79ca2e3b9abe Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:18:16 +0900 Subject: [PATCH 02/11] =?UTF-8?q?chore:=20Terraform=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=20=EC=A0=95=EC=9D=98=20=EC=B6=94=EA=B0=80=20(GCP,=20Cloudflare?= =?UTF-8?q?,=20SSH)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 +++++++- terraform/variables.tf | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 terraform/variables.tf diff --git a/.gitignore b/.gitignore index 21ca485b..61319394 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,10 @@ src/main/resources/application-dev.yml .env -application-dev.yml \ No newline at end of file +application-dev.yml + +### Terraform ### +terraform/.terraform/ +terraform/terraform.tfstate +terraform/terraform.tfstate.backup +terraform/terraform.tfvars \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 00000000..5bb9f155 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,26 @@ +variable "gcp_project_id" { + description = "GCP 프로젝트 ID" + type = string +} + +variable "gcp_region" { + description = "GCP 기본 리전 (prod)" + type = string + default = "asia-northeast3" +} + +variable "cloudflare_api_token" { + description = "Cloudflare API 토큰" + type = string + sensitive = true +} + +variable "cloudflare_zone_id" { + description = "cockple.shop Cloudflare Zone ID" + type = string +} + +variable "ssh_public_key" { + description = "인스턴스 접속용 SSH 공개키" + type = string +} \ No newline at end of file From e28b11ebb80aec77d91a0fd6eb1b43cd5961bcf8 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:20:03 +0900 Subject: [PATCH 03/11] =?UTF-8?q?chore:=20cloudflare=20IP=EB=A7=8C=20?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=84=A4=ED=8A=B8=EC=9B=8C=ED=81=AC=20=EC=85=8B?= =?UTF-8?q?=ED=8C=85(=EB=AC=B4=EB=A3=8C=20=EC=9D=B8=EC=8A=A4=ED=84=B4?= =?UTF-8?q?=EC=8A=A4=EB=8A=94=20=EB=A6=AC=EC=A0=84=EC=9D=B4=20=ED=95=9C?= =?UTF-8?q?=EC=A0=95=EB=90=98=EC=96=B4=20=EC=9E=88=EC=96=B4=20us-central1?= =?UTF-8?q?=EB=A1=9C=20=EC=85=8B=ED=8C=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/network.tf | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 terraform/network.tf diff --git a/terraform/network.tf b/terraform/network.tf new file mode 100644 index 00000000..d65214f4 --- /dev/null +++ b/terraform/network.tf @@ -0,0 +1,62 @@ +resource "google_compute_network" "cockple_vpc" { + name = "cockple-vpc" + auto_create_subnetworks = false +} + +resource "google_compute_subnetwork" "prod" { + name = "cockple-subnet-prod" + ip_cidr_range = "10.0.1.0/24" + region = "asia-northeast3" + network = google_compute_network.cockple_vpc.id +} + +resource "google_compute_subnetwork" "staging" { + name = "cockple-subnet-staging" + ip_cidr_range = "10.0.2.0/24" + region = "us-central1" + network = google_compute_network.cockple_vpc.id +} + +# Cloudflare IP 대역에서만 80 포트 허용 (origin IP 보호) +resource "google_compute_firewall" "allow_http_cloudflare" { + name = "cockple-allow-http-cloudflare" + network = google_compute_network.cockple_vpc.name + + allow { + protocol = "tcp" + ports = ["80"] + } + + source_ranges = [ + "173.245.48.0/20", + "103.21.244.0/22", + "103.22.200.0/22", + "103.31.4.0/22", + "141.101.64.0/18", + "108.162.192.0/18", + "190.93.240.0/20", + "188.114.96.0/20", + "197.234.240.0/22", + "198.41.128.0/17", + "162.158.0.0/15", + "104.16.0.0/13", + "104.24.0.0/14", + "172.64.0.0/13", + "131.0.72.0/22", + ] + + target_tags = ["cockple-prod", "cockple-staging"] +} + +resource "google_compute_firewall" "allow_ssh" { + name = "cockple-allow-ssh" + network = google_compute_network.cockple_vpc.name + + allow { + protocol = "tcp" + ports = ["22"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["cockple-prod", "cockple-staging"] +} \ No newline at end of file From 4c978a66691474c9d42a598346a922ca346b0790 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:20:56 +0900 Subject: [PATCH 04/11] =?UTF-8?q?chore:=20=EC=9D=B8=EC=8A=A4=ED=84=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=84=A4=EC=A0=95=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/compute.tf | 81 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 terraform/compute.tf diff --git a/terraform/compute.tf b/terraform/compute.tf new file mode 100644 index 00000000..386dc2ee --- /dev/null +++ b/terraform/compute.tf @@ -0,0 +1,81 @@ +resource "google_compute_address" "prod" { + name = "cockple-prod-ip" + region = "asia-northeast3" +} + +resource "google_compute_address" "staging" { + name = "cockple-staging-ip" + region = "us-central1" +} + +resource "google_compute_instance" "prod" { + name = "cockple-prod" + machine_type = "e2-medium" # 4GB RAM + zone = "asia-northeast3-b" + tags = ["cockple-prod"] + + boot_disk { + initialize_params { + image = "ubuntu-os-cloud/ubuntu-2204-lts" + size = 20 + } + } + + network_interface { + subnetwork = google_compute_subnetwork.prod.id + access_config { + nat_ip = google_compute_address.prod.address + } + } + + metadata = { + ssh-keys = "ubuntu:${var.ssh_public_key}" + } + + metadata_startup_script = <<-EOF + #!/bin/bash + apt-get update -y + apt-get install -y docker.io + curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose + systemctl enable docker + systemctl start docker + usermod -aG docker ubuntu + EOF +} + +resource "google_compute_instance" "staging" { + name = "cockple-staging" + machine_type = "e2-micro" # 1GB RAM, 무료 티어 + zone = "us-central1-a" + tags = ["cockple-staging"] + + boot_disk { + initialize_params { + image = "ubuntu-os-cloud/ubuntu-2204-lts" + size = 30 # 무료 티어 최대 + } + } + + network_interface { + subnetwork = google_compute_subnetwork.staging.id + access_config { + nat_ip = google_compute_address.staging.address + } + } + + metadata = { + ssh-keys = "ubuntu:${var.ssh_public_key}" + } + + metadata_startup_script = <<-EOF + #!/bin/bash + apt-get update -y + apt-get install -y docker.io + curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose + systemctl enable docker + systemctl start docker + usermod -aG docker ubuntu + EOF +} From c291499afaa3215868dca38caa0d9bff4a8780cf Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:24:07 +0900 Subject: [PATCH 05/11] =?UTF-8?q?chore:=20Cloudflare=20DNS=20A=20=EB=A0=88?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=84=A4=EC=A0=95=20(prod,=20staging,=20S?= =?UTF-8?q?SH)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/dns.tf | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 terraform/dns.tf diff --git a/terraform/dns.tf b/terraform/dns.tf new file mode 100644 index 00000000..95d6a4f7 --- /dev/null +++ b/terraform/dns.tf @@ -0,0 +1,31 @@ +resource "cloudflare_record" "prod" { + zone_id = var.cloudflare_zone_id + name = "@" + content = google_compute_address.prod.address + type = "A" + proxied = true +} + +resource "cloudflare_record" "prod_ssh" { + zone_id = var.cloudflare_zone_id + name = "ssh" + content = google_compute_address.prod.address + type = "A" + proxied = false +} + +resource "cloudflare_record" "staging" { + zone_id = var.cloudflare_zone_id + name = "staging" + content = google_compute_address.staging.address + type = "A" + proxied = true +} + +resource "cloudflare_record" "staging_ssh" { + zone_id = var.cloudflare_zone_id + name = "ssh-staging" + content = google_compute_address.staging.address + type = "A" + proxied = false +} From e4956d84c7bc60cfea0e7fdde45b8b3e6e6d915b Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:25:15 +0900 Subject: [PATCH 06/11] =?UTF-8?q?chore:=20IP=20=EC=B6=9C=EB=A0=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=85=8B=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/outputs.tf | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 terraform/outputs.tf diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 00000000..f3fe8f51 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,9 @@ +output "prod_ip" { + description = "Prod 서버 공인 IP" + value = google_compute_address.prod.address +} + +output "staging_ip" { + description = "Staging 서버 공인 IP" + value = google_compute_address.staging.address +} \ No newline at end of file From 00fc99b508ac66b4bfcbe11f098dc2f49ae9f994 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 22:25:43 +0900 Subject: [PATCH 07/11] =?UTF-8?q?chore:=20provider=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=20=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/.terraform.lock.hcl | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 terraform/.terraform.lock.hcl diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 00000000..f5fc3276 --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/cloudflare/cloudflare" { + version = "4.52.5" + constraints = "~> 4.0" + hashes = [ + "h1:18bXaaOSq8MWKuMxo/4y7EB7/i7G90y5QsKHZRmkoDo=", + "zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b", + "zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a", + "zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7", + "zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238", + "zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b", + "zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072", + "zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661", + "zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c", + "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f", + "zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54", + "zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852", + "zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0", + "zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5", + "zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036", + "zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803", + ] +} + +provider "registry.terraform.io/hashicorp/google" { + version = "5.45.2" + constraints = "~> 5.0" + hashes = [ + "h1:k8taQAdfHrv2F/AiGV5BZBZfI+1uaq8g6O8dWzjx42c=", + "zh:0d09c8f20b556305192cdbe0efa6d333ceebba963a8ba91f9f1714b5a20c4b7a", + "zh:117143fc91be407874568df416b938a6896f94cb873f26bba279cedab646a804", + "zh:16ccf77d18dd2c5ef9c0625f9cf546ebdf3213c0a452f432204c69feed55081e", + "zh:3e555cf22a570a4bd247964671f421ed7517970cd9765ceb46f335edc2c6f392", + "zh:688bd5b05a75124da7ae6e885b2b92bd29f4261808b2b78bd5f51f525c1052ca", + "zh:6db3ef37a05010d82900bfffb3261c59a0c247e0692049cb3eb8c2ef16c9d7bf", + "zh:70316fde75f6a15d72749f66d994ccbdde5f5ed4311b6d06b99850f698c9bbf9", + "zh:84b8e583771a4f2bd514e519d98ed7fd28dce5efe0634e973170e1cfb5556fb4", + "zh:9d4b8ef0a9b6677935c604d94495042e68ff5489932cfd1ec41052e094a279d3", + "zh:a2089dd9bd825c107b148dd12d6b286f71aa37dfd4ca9c35157f2dcba7bc19d8", + "zh:f03d795c0fd9721e59839255ee7ba7414173017dc530b4ce566daf3802a0d6dd", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} From e3aa77dcb869f3b225b46388fe7490f32954c01f Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 23:41:27 +0900 Subject: [PATCH 08/11] =?UTF-8?q?chore:=20Cloud=20SQL=EB=A1=9C=20MySQL=20?= =?UTF-8?q?=EB=9D=84=EC=9A=B0=EB=8F=84=EB=A1=9D=20Terraform=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/cloudsql.tf | 53 ++++++++++++++++++++++++++++++++++++++++++ terraform/network.tf | 22 ++++++++++++++++++ terraform/outputs.tf | 5 ++++ terraform/variables.tf | 12 ++++++++++ 4 files changed, 92 insertions(+) create mode 100644 terraform/cloudsql.tf diff --git a/terraform/cloudsql.tf b/terraform/cloudsql.tf new file mode 100644 index 00000000..b33fa11b --- /dev/null +++ b/terraform/cloudsql.tf @@ -0,0 +1,53 @@ +resource "google_project_service" "sqladmin" { + service = "sqladmin.googleapis.com" + disable_on_destroy = false +} + +resource "google_sql_database_instance" "cockple" { + name = "cockple-mysql" + database_version = "MYSQL_8_0" + region = "asia-northeast3" + + deletion_protection = true + + settings { + tier = "db-g1-small" + + ip_configuration { + ipv4_enabled = false # 공인 IP 비활성화, VPC 내부 통신만 + private_network = google_compute_network.cockple_vpc.id + } + + backup_configuration { + enabled = true + start_time = "03:00" # 새벽 3시 자동 백업 + } + } + + depends_on = [ + google_project_service.sqladmin, + google_service_networking_connection.private_vpc_connection, + ] +} + +resource "google_sql_database" "prod" { + name = "cockple" + instance = google_sql_database_instance.cockple.name +} + +resource "google_sql_database" "staging" { + name = "cockple_staging" + instance = google_sql_database_instance.cockple.name +} + +resource "google_sql_user" "prod" { + name = "cockple" + instance = google_sql_database_instance.cockple.name + password = var.db_password +} + +resource "google_sql_user" "staging" { + name = "cockple_staging" + instance = google_sql_database_instance.cockple.name + password = var.db_staging_password +} \ No newline at end of file diff --git a/terraform/network.tf b/terraform/network.tf index d65214f4..5620ebeb 100644 --- a/terraform/network.tf +++ b/terraform/network.tf @@ -1,8 +1,30 @@ +resource "google_project_service" "servicenetworking" { + service = "servicenetworking.googleapis.com" + disable_on_destroy = false +} + resource "google_compute_network" "cockple_vpc" { name = "cockple-vpc" auto_create_subnetworks = false } +# Cloud SQL private IP를 위한 VPC peering +resource "google_compute_global_address" "private_ip_range" { + name = "cockple-private-ip-range" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.cockple_vpc.id +} + +resource "google_service_networking_connection" "private_vpc_connection" { + network = google_compute_network.cockple_vpc.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [google_compute_global_address.private_ip_range.name] + + depends_on = [google_project_service.servicenetworking] +} + resource "google_compute_subnetwork" "prod" { name = "cockple-subnet-prod" ip_cidr_range = "10.0.1.0/24" diff --git a/terraform/outputs.tf b/terraform/outputs.tf index f3fe8f51..cc2cb055 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -6,4 +6,9 @@ output "prod_ip" { output "staging_ip" { description = "Staging 서버 공인 IP" value = google_compute_address.staging.address +} + +output "db_private_ip" { + description = "Cloud SQL 사설 IP (SSH 터널로 접속)" + value = google_sql_database_instance.cockple.private_ip_address } \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf index 5bb9f155..ab594fd7 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -23,4 +23,16 @@ variable "cloudflare_zone_id" { variable "ssh_public_key" { description = "인스턴스 접속용 SSH 공개키" type = string +} + +variable "db_password" { + description = "Cloud SQL prod 유저 비밀번호" + type = string + sensitive = true +} + +variable "db_staging_password" { + description = "Cloud SQL staging 유저 비밀번호" + type = string + sensitive = true } \ No newline at end of file From c40f507e6deb49b37fbbfe97bfb3670fe13efed2 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 23:43:00 +0900 Subject: [PATCH 09/11] =?UTF-8?q?chore:=20GCS=20Terraform=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/compute.tf | 10 ++++++++++ terraform/outputs.tf | 10 ++++++++++ terraform/storage.tf | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 terraform/storage.tf diff --git a/terraform/compute.tf b/terraform/compute.tf index 386dc2ee..7f03db35 100644 --- a/terraform/compute.tf +++ b/terraform/compute.tf @@ -32,6 +32,11 @@ resource "google_compute_instance" "prod" { ssh-keys = "ubuntu:${var.ssh_public_key}" } + service_account { + email = google_service_account.cockple_app.email + scopes = ["cloud-platform"] # GCS 등 GCP 서비스 접근 + } + metadata_startup_script = <<-EOF #!/bin/bash apt-get update -y @@ -68,6 +73,11 @@ resource "google_compute_instance" "staging" { ssh-keys = "ubuntu:${var.ssh_public_key}" } + service_account { + email = google_service_account.cockple_app.email + scopes = ["cloud-platform"] + } + metadata_startup_script = <<-EOF #!/bin/bash apt-get update -y diff --git a/terraform/outputs.tf b/terraform/outputs.tf index cc2cb055..a14dc02a 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -11,4 +11,14 @@ output "staging_ip" { output "db_private_ip" { description = "Cloud SQL 사설 IP (SSH 터널로 접속)" value = google_sql_database_instance.cockple.private_ip_address +} + +output "gcs_bucket_name" { + description = "GCS 버킷 이름" + value = google_storage_bucket.cockple_assets.name +} + +output "app_service_account_email" { + description = "앱 서비스 계정 이메일 (GCS 인증에 사용)" + value = google_service_account.cockple_app.email } \ No newline at end of file diff --git a/terraform/storage.tf b/terraform/storage.tf new file mode 100644 index 00000000..63e9e4a4 --- /dev/null +++ b/terraform/storage.tf @@ -0,0 +1,32 @@ +resource "google_project_service" "storage" { + service = "storage.googleapis.com" + disable_on_destroy = false +} + +# 앱 인스턴스용 서비스 계정 (GCS 접근) +resource "google_service_account" "cockple_app" { + account_id = "cockple-app" + display_name = "Cockple App Service Account" +} + +resource "google_storage_bucket" "cockple_assets" { + name = "cockple-assets-${var.gcp_project_id}" + location = "ASIA-NORTHEAST3" + + uniform_bucket_level_access = true + + cors { + origin = ["https://cockple.shop", "https://staging.cockple.shop"] + method = ["GET", "PUT", "POST", "DELETE"] + response_header = ["Content-Type"] + max_age_seconds = 3600 + } + + depends_on = [google_project_service.storage] +} + +resource "google_storage_bucket_iam_member" "app_storage_admin" { + bucket = google_storage_bucket.cockple_assets.name + role = "roles/storage.objectAdmin" + member = "serviceAccount:${google_service_account.cockple_app.email}" +} \ No newline at end of file From 7bdd1936469261c84c1de2f68b9e1c937bd8e5a2 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Tue, 24 Feb 2026 23:56:59 +0900 Subject: [PATCH 10/11] =?UTF-8?q?chore:=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EA=B3=84=EC=A0=95=20=EC=B6=94=EA=B0=80=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C=20?= =?UTF-8?q?=EC=9E=A0=20=EC=8B=9C=20=EB=A9=88=EC=B6=94=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/compute.tf | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/terraform/compute.tf b/terraform/compute.tf index 7f03db35..7cace9f5 100644 --- a/terraform/compute.tf +++ b/terraform/compute.tf @@ -9,10 +9,11 @@ resource "google_compute_address" "staging" { } resource "google_compute_instance" "prod" { - name = "cockple-prod" - machine_type = "e2-medium" # 4GB RAM - zone = "asia-northeast3-b" - tags = ["cockple-prod"] + name = "cockple-prod" + machine_type = "e2-medium" # 4GB RAM + zone = "asia-northeast3-b" + tags = ["cockple-prod"] + allow_stopping_for_update = true boot_disk { initialize_params { @@ -50,10 +51,11 @@ resource "google_compute_instance" "prod" { } resource "google_compute_instance" "staging" { - name = "cockple-staging" - machine_type = "e2-micro" # 1GB RAM, 무료 티어 - zone = "us-central1-a" - tags = ["cockple-staging"] + name = "cockple-staging" + machine_type = "e2-micro" # 1GB RAM, 무료 티어 + zone = "us-central1-a" + tags = ["cockple-staging"] + allow_stopping_for_update = true boot_disk { initialize_params { From 806b21048784f4b766a7d6d84252967a2283be08 Mon Sep 17 00:00:00 2001 From: Dimo-2562 Date: Wed, 25 Feb 2026 00:14:22 +0900 Subject: [PATCH 11/11] =?UTF-8?q?chore:=20Cloud=20SQL=20=EB=8C=80=EC=8B=A0?= =?UTF-8?q?=20Docker=20MySQL=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EA=B8=B0=EB=A1=9C=20=EA=B2=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/cloudsql.tf | 53 ------------------------------------------ terraform/network.tf | 22 ------------------ terraform/outputs.tf | 5 ---- terraform/variables.tf | 12 ---------- 4 files changed, 92 deletions(-) delete mode 100644 terraform/cloudsql.tf diff --git a/terraform/cloudsql.tf b/terraform/cloudsql.tf deleted file mode 100644 index b33fa11b..00000000 --- a/terraform/cloudsql.tf +++ /dev/null @@ -1,53 +0,0 @@ -resource "google_project_service" "sqladmin" { - service = "sqladmin.googleapis.com" - disable_on_destroy = false -} - -resource "google_sql_database_instance" "cockple" { - name = "cockple-mysql" - database_version = "MYSQL_8_0" - region = "asia-northeast3" - - deletion_protection = true - - settings { - tier = "db-g1-small" - - ip_configuration { - ipv4_enabled = false # 공인 IP 비활성화, VPC 내부 통신만 - private_network = google_compute_network.cockple_vpc.id - } - - backup_configuration { - enabled = true - start_time = "03:00" # 새벽 3시 자동 백업 - } - } - - depends_on = [ - google_project_service.sqladmin, - google_service_networking_connection.private_vpc_connection, - ] -} - -resource "google_sql_database" "prod" { - name = "cockple" - instance = google_sql_database_instance.cockple.name -} - -resource "google_sql_database" "staging" { - name = "cockple_staging" - instance = google_sql_database_instance.cockple.name -} - -resource "google_sql_user" "prod" { - name = "cockple" - instance = google_sql_database_instance.cockple.name - password = var.db_password -} - -resource "google_sql_user" "staging" { - name = "cockple_staging" - instance = google_sql_database_instance.cockple.name - password = var.db_staging_password -} \ No newline at end of file diff --git a/terraform/network.tf b/terraform/network.tf index 5620ebeb..d65214f4 100644 --- a/terraform/network.tf +++ b/terraform/network.tf @@ -1,30 +1,8 @@ -resource "google_project_service" "servicenetworking" { - service = "servicenetworking.googleapis.com" - disable_on_destroy = false -} - resource "google_compute_network" "cockple_vpc" { name = "cockple-vpc" auto_create_subnetworks = false } -# Cloud SQL private IP를 위한 VPC peering -resource "google_compute_global_address" "private_ip_range" { - name = "cockple-private-ip-range" - purpose = "VPC_PEERING" - address_type = "INTERNAL" - prefix_length = 16 - network = google_compute_network.cockple_vpc.id -} - -resource "google_service_networking_connection" "private_vpc_connection" { - network = google_compute_network.cockple_vpc.id - service = "servicenetworking.googleapis.com" - reserved_peering_ranges = [google_compute_global_address.private_ip_range.name] - - depends_on = [google_project_service.servicenetworking] -} - resource "google_compute_subnetwork" "prod" { name = "cockple-subnet-prod" ip_cidr_range = "10.0.1.0/24" diff --git a/terraform/outputs.tf b/terraform/outputs.tf index a14dc02a..aeb7a1a9 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -8,11 +8,6 @@ output "staging_ip" { value = google_compute_address.staging.address } -output "db_private_ip" { - description = "Cloud SQL 사설 IP (SSH 터널로 접속)" - value = google_sql_database_instance.cockple.private_ip_address -} - output "gcs_bucket_name" { description = "GCS 버킷 이름" value = google_storage_bucket.cockple_assets.name diff --git a/terraform/variables.tf b/terraform/variables.tf index ab594fd7..2f96e69b 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -24,15 +24,3 @@ variable "ssh_public_key" { description = "인스턴스 접속용 SSH 공개키" type = string } - -variable "db_password" { - description = "Cloud SQL prod 유저 비밀번호" - type = string - sensitive = true -} - -variable "db_staging_password" { - description = "Cloud SQL staging 유저 비밀번호" - type = string - sensitive = true -} \ No newline at end of file