Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permissions:
env:
PROJECT_ID: casecomp-495718
REGION: asia-south1
SERVICE: cardscrapebot
SERVICE: casecomp-api
IMAGE: gcr.io/casecomp-495718/casecomp-api

jobs:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"test:live": "API_URL=https://api.casecomp.xyz node test/api-test.js",
"scan": "node scan.js",
"psa": "node scripts/psa-report.js",
"deploy": "gcloud builds submit --config=cloudbuild.yml --project casecomp-495718 && gcloud run deploy cardscrapebot --image gcr.io/casecomp-495718/casecomp-api --region asia-south1 --project casecomp-495718 --port 3000 --allow-unauthenticated",
"deploy": "gcloud builds submit --config=cloudbuild.yml --project casecomp-495718 && gcloud run deploy casecomp-api --image gcr.io/casecomp-495718/casecomp-api --region asia-south1 --project casecomp-495718 --port 3000 --allow-unauthenticated",
"playwright-install": "npx playwright install chromium"
},
"dependencies": {
Expand Down
74 changes: 66 additions & 8 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ data "google_project" "current" {
# ── Cloud Run ─────────────────────────────────────────────────

resource "google_cloud_run_v2_service" "api" {
name = "cardscrapebot"
name = "casecomp-api"
location = var.region

template {
Expand Down Expand Up @@ -149,6 +149,27 @@ resource "google_cloud_run_v2_service_iam_member" "public" {
member = "allUsers"
}

# ── Static Site (GCS) ────────────────────────────────────────

resource "google_storage_bucket" "site" {
name = "casecomp-site"
location = var.region
force_destroy = false

uniform_bucket_level_access = true

website {
main_page_suffix = "index.html"
not_found_page = "index.html"
}
}

resource "google_storage_bucket_iam_member" "site_public" {
bucket = google_storage_bucket.site.name
role = "roles/storage.objectViewer"
member = "allUsers"
}

# ── Load Balancer ─────────────────────────────────────────────

resource "google_compute_global_address" "api_ip" {
Expand All @@ -158,7 +179,7 @@ resource "google_compute_global_address" "api_ip" {
}

resource "google_compute_region_network_endpoint_group" "api_neg" {
name = "cardscrapebot-neg"
name = "casecomp-api-neg"
region = var.region
network_endpoint_type = "SERVERLESS"

Expand All @@ -175,23 +196,60 @@ resource "google_compute_backend_service" "api_backend" {
}
}

resource "google_compute_backend_bucket" "site_backend" {
name = "casecomp-site-backend"
bucket_name = google_storage_bucket.site.name
enable_cdn = true
}

resource "google_compute_url_map" "api_urlmap" {
name = "cardscrapebot-urlmap"
default_service = google_compute_backend_service.api_backend.id
default_service = google_compute_backend_bucket.site_backend.id

host_rule {
hosts = [var.api_domain]
path_matcher = "api"
}

host_rule {
hosts = [var.site_domain, "www.${var.site_domain}"]
path_matcher = "site"
}

path_matcher {
name = "api"
default_service = google_compute_backend_service.api_backend.id
}

path_matcher {
name = "site"
default_service = google_compute_backend_bucket.site_backend.id
}
}

resource "google_compute_managed_ssl_certificate" "api_cert" {
name = "cardscrapebot-cert-v2"

managed {
domains = [var.domain]
domains = [var.api_domain]
}
}

resource "google_compute_managed_ssl_certificate" "site_cert" {
name = "casecomp-site-cert"

managed {
domains = [var.site_domain, "www.${var.site_domain}"]
}
}

resource "google_compute_target_https_proxy" "api_proxy" {
name = "cardscrapebot-https-proxy"
url_map = google_compute_url_map.api_urlmap.id
ssl_certificates = [google_compute_managed_ssl_certificate.api_cert.id]
ssl_certificates = [
google_compute_managed_ssl_certificate.api_cert.id,
google_compute_managed_ssl_certificate.site_cert.id,
]
}

resource "google_compute_global_forwarding_rule" "api_https" {
Expand Down Expand Up @@ -221,7 +279,7 @@ resource "google_monitoring_notification_channel" "email" {

resource "google_logging_metric" "api_errors" {
name = "cardscrapebot-errors"
filter = "resource.type=\"cloud_run_revision\" resource.labels.service_name=\"cardscrapebot\" textPayload=~\"\\[ERROR\\]\""
filter = "resource.type=\"cloud_run_revision\" resource.labels.service_name=\"casecomp-api\" textPayload=~\"\\[ERROR\\]\""

metric_descriptor {
metric_kind = "DELTA"
Expand Down Expand Up @@ -274,7 +332,7 @@ resource "google_monitoring_uptime_check_config" "api_uptime" {
type = "uptime_url"
labels = {
project_id = var.project_id
host = var.domain
host = var.api_domain
}
}

Expand Down Expand Up @@ -323,5 +381,5 @@ output "lb_ip" {
}

output "api_url" {
value = "https://${var.domain}"
value = "https://${var.api_domain}"
}
6 changes: 5 additions & 1 deletion terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ variable "region" {
default = "asia-south1"
}

variable "domain" {
variable "api_domain" {
default = "api.casecomp.xyz"
}

variable "site_domain" {
default = "casecomp.xyz"
}

variable "container_image" {
default = "gcr.io/casecomp-495718/casecomp-api"
}
Expand Down
82 changes: 74 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@
protobufjs "^7.5.5"
yargs "^17.7.2"

"@img/colour@^1.0.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz"
integrity sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==

"@img/sharp-darwin-arm64@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz"
integrity sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==
optionalDependencies:
"@img/sharp-libvips-darwin-arm64" "1.2.4"

"@img/sharp-libvips-darwin-arm64@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz"
integrity sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==

"@ioredis/commands@1.5.1":
version "1.5.1"
resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz"
Expand Down Expand Up @@ -386,6 +403,11 @@ depd@^2.0.0, depd@~2.0.0:
resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==

detect-libc@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz"
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==

dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz"
Expand Down Expand Up @@ -545,11 +567,11 @@ etag@^1.8.1:
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==

express-rate-limit@^8.3.2:
version "8.3.2"
resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.2.tgz"
integrity sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg==
version "8.5.1"
resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz"
integrity sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==
dependencies:
ip-address "10.1.0"
ip-address "^10.2.0"

express@^5.2.1, "express@>= 4.11", "express@>=4.0.0 || >=5.0.0-beta":
version "5.2.1"
Expand Down Expand Up @@ -788,6 +810,11 @@ hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"

helmet@^8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz"
integrity sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==

htmlparser2@^10.1.0:
version "10.1.0"
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz"
Expand Down Expand Up @@ -873,10 +900,10 @@ ioredis@^5.10.1:
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"

ip-address@10.1.0:
version "10.1.0"
resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz"
integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==
ip-address@^10.2.0:
version "10.2.0"
resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz"
integrity sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==

ipaddr.js@1.9.1:
version "1.9.1"
Expand Down Expand Up @@ -1260,6 +1287,11 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0:
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

semver@^7.7.3:
version "7.8.0"
resolved "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz"
integrity sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==

send@^1.1.0, send@^1.2.0:
version "1.2.1"
resolved "https://registry.npmjs.org/send/-/send-1.2.1.tgz"
Expand Down Expand Up @@ -1292,6 +1324,40 @@ setprototypeof@~1.2.0:
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==

sharp@^0.34.5:
version "0.34.5"
resolved "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz"
integrity sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==
dependencies:
"@img/colour" "^1.0.0"
detect-libc "^2.1.2"
semver "^7.7.3"
optionalDependencies:
"@img/sharp-darwin-arm64" "0.34.5"
"@img/sharp-darwin-x64" "0.34.5"
"@img/sharp-libvips-darwin-arm64" "1.2.4"
"@img/sharp-libvips-darwin-x64" "1.2.4"
"@img/sharp-libvips-linux-arm" "1.2.4"
"@img/sharp-libvips-linux-arm64" "1.2.4"
"@img/sharp-libvips-linux-ppc64" "1.2.4"
"@img/sharp-libvips-linux-riscv64" "1.2.4"
"@img/sharp-libvips-linux-s390x" "1.2.4"
"@img/sharp-libvips-linux-x64" "1.2.4"
"@img/sharp-libvips-linuxmusl-arm64" "1.2.4"
"@img/sharp-libvips-linuxmusl-x64" "1.2.4"
"@img/sharp-linux-arm" "0.34.5"
"@img/sharp-linux-arm64" "0.34.5"
"@img/sharp-linux-ppc64" "0.34.5"
"@img/sharp-linux-riscv64" "0.34.5"
"@img/sharp-linux-s390x" "0.34.5"
"@img/sharp-linux-x64" "0.34.5"
"@img/sharp-linuxmusl-arm64" "0.34.5"
"@img/sharp-linuxmusl-x64" "0.34.5"
"@img/sharp-wasm32" "0.34.5"
"@img/sharp-win32-arm64" "0.34.5"
"@img/sharp-win32-ia32" "0.34.5"
"@img/sharp-win32-x64" "0.34.5"

shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
Expand Down