Add Terraform configuration

This commit is contained in:
Marija Stopa 2026-01-08 15:15:00 +01:00
parent b0e0d9970e
commit 8c5af42548
4 changed files with 234 additions and 0 deletions

15
terraform/.gitignore vendored Normal file
View file

@ -0,0 +1,15 @@
# Terraform
*.tfstate
*.tfstate.*
*.tfvars
.terraform/
.terraform.lock.hcl
crash.log
override.tf
*.tfplan
# Secrets
*.pem
*.key
.env
.env.local

143
terraform/main.tf Normal file
View file

@ -0,0 +1,143 @@
terraform {
required_version = ">= 1.6.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
# backend "gcs" {
# bucket = "terraform-state-bucket"
# prefix = "terraform/state"
# }
}
provider "google" {
project = var.project_id
region = var.region
}
locals {
service_name = "petclinic-${var.environment}"
labels = {
environment = var.environment
application = "petclinic"
managed-by = "terraform"
}
}
# Artifact Registry Repository
resource "google_artifact_registry_repository" "petclinic" {
location = var.region
repository_id = "petclinic"
description = "Docker repository for PetClinic application"
format = "DOCKER"
labels = local.labels
}
# Service Account for Cloud Run
resource "google_service_account" "petclinic" {
account_id = "petclinic-${var.environment}"
display_name = "PetClinic Service Account (${var.environment})"
description = "Service account for PetClinic Cloud Run service"
}
# Grant Cloud Run service account
resource "google_project_iam_member" "petclinic_log_writer" {
project = var.project_id
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.petclinic.email}"
}
resource "google_project_iam_member" "petclinic_metric_writer" {
project = var.project_id
role = "roles/monitoring.metricWriter"
member = "serviceAccount:${google_service_account.petclinic.email}"
}
# Cloud Run Service
resource "google_cloud_run_v2_service" "petclinic" {
name = local.service_name
location = var.region
labels = local.labels
template {
service_account = google_service_account.petclinic.email
scaling {
min_instance_count = var.min_instances
max_instance_count = var.max_instances
}
containers {
image = "${var.region}-docker.pkg.dev/${var.project_id}/petclinic/spring-petclinic:${var.image_tag}"
resources {
limits = {
cpu = var.cpu_limit
memory = var.memory_limit
}
cpu_idle = true
startup_cpu_boost = true
}
env {
name = "SPRING_PROFILES_ACTIVE"
value = var.environment
}
env {
name = "JAVA_OPTS"
value = "-XX:MaxRAMPercentage=75.0 -XX:+UseContainerSupport"
}
# Health check probes
startup_probe {
http_get {
path = "/actuator/health/liveness"
port = 8080
}
initial_delay_seconds = 0
timeout_seconds = 1
period_seconds = 3
failure_threshold = 10
}
liveness_probe {
http_get {
path = "/actuator/health/liveness"
port = 8080
}
initial_delay_seconds = 0
timeout_seconds = 1
period_seconds = 10
failure_threshold = 3
}
}
}
traffic {
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
percent = 100
}
depends_on = [
google_project_iam_member.petclinic_log_writer,
google_project_iam_member.petclinic_metric_writer,
]
}
# IAM Policy for Public Access
resource "google_cloud_run_v2_service_iam_member" "public_access" {
count = var.allow_public_access ? 1 : 0
project = var.project_id
location = var.region
name = google_cloud_run_v2_service.petclinic.name
role = "roles/run.invoker"
member = "allUsers"
}

19
terraform/outputs.tf Normal file
View file

@ -0,0 +1,19 @@
output "service_url" {
description = "URL of the deployed Cloud Run service"
value = google_cloud_run_v2_service.petclinic.uri
}
output "service_name" {
description = "Name of the Cloud Run service"
value = google_cloud_run_v2_service.petclinic.name
}
output "artifact_registry_url" {
description = "URL of the Artifact Registry repository"
value = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.petclinic.repository_id}"
}
output "environment" {
description = "Deployment environment"
value = var.environment
}

57
terraform/variables.tf Normal file
View file

@ -0,0 +1,57 @@
variable "project_id" {
description = "GCP Project ID"
type = string
}
variable "region" {
description = "GCP Region"
type = string
default = "us-central1"
}
variable "environment" {
description = "Environment name (dev, prod)"
type = string
validation {
condition = contains(["dev", "prod"], var.environment)
error_message = "Environment must be dev or prod."
}
}
variable "image_tag" {
description = "Docker image tag to deploy"
type = string
default = "latest"
}
# Cloud Run Configuration
variable "min_instances" {
description = "Minimum number of Cloud Run instances"
type = number
default = 0
}
variable "max_instances" {
description = "Maximum number of Cloud Run instances"
type = number
default = 10
}
variable "cpu_limit" {
description = "CPU limit for Cloud Run container"
type = string
default = "1"
}
variable "memory_limit" {
description = "Memory limit for Cloud Run container"
type = string
default = "512Mi"
}
variable "allow_public_access" {
description = "Allow public access to the service"
type = bool
default = true
}