From 7e4d91605e4c9257878fdf29b503d02635c2e7a0 Mon Sep 17 00:00:00 2001 From: Chris Christiansen Date: Wed, 27 May 2026 16:13:08 +0000 Subject: [PATCH] feat(terraform): add vauco-bootstrap module Gjenbrukbar modul for alle OSVauco-kundeprosjekter. Oppretter: GCP-prosjekt, APIs, IAM, Cloud Run, billing-budsjett. Brukes av medioteq.tf og alle fremtidige kunder. --- .../terraform/modules/vauco-bootstrap/main.tf | 107 ++++++++++++++++++ .../modules/vauco-bootstrap/outputs.tf | 19 ++++ .../modules/vauco-bootstrap/variables.tf | 36 ++++++ 3 files changed, 162 insertions(+) create mode 100644 infrastructure/terraform/modules/vauco-bootstrap/main.tf create mode 100644 infrastructure/terraform/modules/vauco-bootstrap/outputs.tf create mode 100644 infrastructure/terraform/modules/vauco-bootstrap/variables.tf diff --git a/infrastructure/terraform/modules/vauco-bootstrap/main.tf b/infrastructure/terraform/modules/vauco-bootstrap/main.tf new file mode 100644 index 0000000..2116676 --- /dev/null +++ b/infrastructure/terraform/modules/vauco-bootstrap/main.tf @@ -0,0 +1,107 @@ +# ============================================================================== +# vauco-bootstrap — gjenbrukbar modul for alle OSVauco-kundeprosjekter +# Oppretter: GCP-prosjekt, APIs, IAM, Cloud Run, billing-budsjett +# ============================================================================== + +locals { + labels = { + managed-by = "terraform" + customer = var.customer_id + environment = "prod" + } +} + +# ------------------------------------------------------------------------------ +# GCP-prosjekt +# ------------------------------------------------------------------------------ +resource "google_project" "customer" { + name = var.customer_id + project_id = var.project_id + billing_account = var.billing_account_id + + labels = local.labels +} + +# ------------------------------------------------------------------------------ +# Aktiver nødvendige APIs +# ------------------------------------------------------------------------------ +resource "google_project_service" "apis" { + for_each = toset([ + "run.googleapis.com", + "artifactregistry.googleapis.com", + "secretmanager.googleapis.com", + "cloudresourcemanager.googleapis.com", + "iam.googleapis.com", + "dialogflow.googleapis.com", + ]) + + project = google_project.customer.project_id + service = each.value + disable_on_destroy = false +} + +# ------------------------------------------------------------------------------ +# Service account for Cloud Run +# ------------------------------------------------------------------------------ +resource "google_service_account" "cloud_run_sa" { + project = google_project.customer.project_id + account_id = "${var.customer_id}-run-sa" + display_name = "Cloud Run SA – ${var.customer_id}" + + depends_on = [google_project_service.apis] +} + +# ------------------------------------------------------------------------------ +# Cloud Run service +# ------------------------------------------------------------------------------ +resource "google_cloud_run_v2_service" "app" { + name = "${var.customer_id}-app" + location = var.region + project = google_project.customer.project_id + + template { + service_account = google_service_account.cloud_run_sa.email + + containers { + image = var.container_image + + resources { + limits = { + cpu = "1" + memory = "512Mi" + } + } + } + } + + labels = local.labels + depends_on = [google_project_service.apis] +} + +# ------------------------------------------------------------------------------ +# Billing-budsjett med e-postvarsel +# ------------------------------------------------------------------------------ +resource "google_billing_budget" "customer" { + billing_account = var.billing_account_id + display_name = "Budget – ${var.customer_id}" + + budget_filter { + projects = ["projects/${google_project.customer.number}"] + } + + amount { + specified_amount { + currency_code = "NOK" + units = "500" + } + } + + threshold_rules { + threshold_percent = 0.8 + } + + all_updates_rule { + monitoring_notification_channels = [] + disable_default_iam_recipients = false + } +} diff --git a/infrastructure/terraform/modules/vauco-bootstrap/outputs.tf b/infrastructure/terraform/modules/vauco-bootstrap/outputs.tf new file mode 100644 index 0000000..8a4101f --- /dev/null +++ b/infrastructure/terraform/modules/vauco-bootstrap/outputs.tf @@ -0,0 +1,19 @@ +output "project_id" { + description = "GCP project ID" + value = google_project.customer.project_id +} + +output "project_number" { + description = "GCP project number" + value = google_project.customer.number +} + +output "cloud_run_url" { + description = "Cloud Run service URL" + value = google_cloud_run_v2_service.app.uri +} + +output "service_account_email" { + description = "Service account for Cloud Run" + value = google_service_account.cloud_run_sa.email +} diff --git a/infrastructure/terraform/modules/vauco-bootstrap/variables.tf b/infrastructure/terraform/modules/vauco-bootstrap/variables.tf new file mode 100644 index 0000000..27b0092 --- /dev/null +++ b/infrastructure/terraform/modules/vauco-bootstrap/variables.tf @@ -0,0 +1,36 @@ +variable "project_id" { + description = "GCP project ID for kunde-prosjektet" + type = string +} + +variable "customer_id" { + description = "Kort kundenavn (brukes i labels og ressursnavn)" + type = string +} + +variable "billing_account_id" { + description = "GCP billing account ID" + type = string +} + +variable "region" { + description = "Primær GCP-region" + type = string + default = "europe-north1" +} + +variable "alert_email" { + description = "E-post for billing-varsler" + type = string +} + +variable "billing_viewer_emails" { + description = "Liste over e-poster med billing viewer-tilgang" + type = list(string) + default = [] +} + +variable "container_image" { + description = "Full URI til container-image i Artifact Registry" + type = string +}