decomposer: generate deliverable files for Discover and structure the solution's functional requirements, non-functional requirements, constraints, assumptions, and open questions without selecting cloud products.; Select Google Cloud products from the confirmed requirements and produce the solution architecture, Mermaid diagram, architecture description, and Terraform infrastructure-as-code.; Validate the Terraform infrastructure and architecture artifacts without deploying resources by running formatting checks, Terraform validation, and a dry-run or plan-oriented deployment check.; Package the approved requirements, architecture, Mermaid diagram, Terraform IaC, and validation results into solution-architecture-guide.md in the gcp_solution_architecture_agent repository.; Verify that the gcp_solution_architecture_agent repository contains the packaged solution-architecture-guide.md with the approved workflow outputs.; Verify that the repository is derived from the workflow_agent template and implements the complete four-phase Google Cloud solution architecture workflow alongside the packaged guide.; Publish the verified gcp_solution_architecture_agent repository with its completed workflow implementation and solution architecture guide.; Verify that the published repository revision contains the completed workflow implementation and solution architecture guide.
Some checks failed
validation / verify (push) Failing after 9s

This commit is contained in:
2026-09-01 19:58:42 +00:00
parent b83f687488
commit e8cecb6ce3
14 changed files with 273 additions and 252 deletions

View File

@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.6.0"
required_version = ">= 1.6.0, < 2.0.0"
required_providers {
google = {
source = "hashicorp/google"
@@ -13,79 +13,98 @@ provider "google" {
region = var.region
}
locals {
enabled = var.provision
resource "google_project_service" "services" {
for_each = toset([
"run.googleapis.com", "sqladmin.googleapis.com", "pubsub.googleapis.com",
"artifactregistry.googleapis.com", "secretmanager.googleapis.com",
"logging.googleapis.com", "monitoring.googleapis.com", "cloudtrace.googleapis.com"
])
project = var.project_id
service = each.value
disable_on_destroy = false
}
resource "google_project_service" "run" {
count = local.enabled ? 1 : 0
project = var.project_id
service = "run.googleapis.com"
resource "google_artifact_registry_repository" "images" {
location = var.region
repository_id = "${var.name}-images"
format = "DOCKER"
depends_on = [google_project_service.services]
}
resource "google_project_service" "secretmanager" {
count = local.enabled ? 1 : 0
project = var.project_id
service = "secretmanager.googleapis.com"
}
resource "google_service_account" "workload" {
count = local.enabled ? 1 : 0
account_id = "gateway-workload"
display_name = "Least-privilege gateway workload"
}
resource "google_secret_manager_secret_iam_member" "runtime_reader" {
count = local.enabled ? 1 : 0
project = var.project_id
secret_id = var.secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.workload[0].email}"
}
resource "google_cloud_run_v2_service" "gateway" {
count = local.enabled ? 1 : 0
name = "platform-gateway"
location = var.region
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
template {
service_account = google_service_account.workload[0].email
containers {
image = var.service_image
env {
name = "UPSTREAM_MODE"
value = "platform-proxy"
}
env {
name = "RUNTIME_SECRET"
value_source {
secret_key_ref {
secret = var.secret_id
version = "latest"
}
}
}
resources {
limits = { cpu = "1", memory = "512Mi" }
}
}
scaling { max_instance_count = 10 }
resource "google_sql_database_instance" "primary" {
name = "${var.name}-sql"
database_version = "POSTGRES_15"
region = var.region
settings {
tier = var.sql_tier
availability_type = var.sql_ha ? "REGIONAL" : "ZONAL"
disk_type = "PD_SSD"
disk_autoresize = true
backup_configuration { enabled = true }
ip_configuration { ipv4_enabled = true }
}
depends_on = [google_project_service.run, google_project_service.secretmanager,
google_secret_manager_secret_iam_member.runtime_reader]
deletion_protection = var.deletion_protection
depends_on = [google_project_service.services]
}
resource "google_cloud_run_v2_service_iam_member" "gateway_invoker" {
count = local.enabled ? 1 : 0
name = google_cloud_run_v2_service.gateway[0].name
resource "google_sql_database" "app" {
name = var.name
instance = google_sql_database_instance.primary.name
}
resource "google_pubsub_topic" "events" { name = "${var.name}-events" }
resource "google_pubsub_topic" "dead_letter" { name = "${var.name}-dead-letter" }
resource "google_pubsub_subscription" "worker" {
name = "${var.name}-worker"
topic = google_pubsub_topic.events.name
dead_letter_policy {
dead_letter_topic = google_pubsub_topic.dead_letter.id
max_delivery_attempts = 10
}
ack_deadline_seconds = 30
}
resource "google_secret_manager_secret" "database_url" {
secret_id = "${var.name}-database-url"
replication { auto {} }
depends_on = [google_project_service.services]
}
resource "google_service_account" "runtime" {
account_id = "${var.name}-runtime"
display_name = "${var.name} runtime identity"
}
resource "google_project_iam_member" "runtime_log_writer" {
project = var.project_id
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.runtime.email}"
}
resource "google_cloud_run_v2_service" "api" {
name = "${var.name}-api"
location = var.region
role = "roles/run.invoker"
member = "allUsers"
template {
service_account = google_service_account.runtime.email
containers {
image = var.api_image
env { name = "PUBSUB_TOPIC" value = google_pubsub_topic.events.name }
env { name = "DATABASE_SECRET" value = google_secret_manager_secret.database_url.secret_id }
}
}
depends_on = [google_project_service.services]
}
# The application must use this gateway/proxy for peer calls; direct peer ingress is not exposed.
output "gateway_uri" {
value = try(google_cloud_run_v2_service.gateway[0].uri, null)
description = "Platform gateway endpoint; peer traffic is routed through this proxy."
resource "google_cloud_run_v2_service" "worker" {
name = "${var.name}-worker"
location = var.region
template {
service_account = google_service_account.runtime.email
containers {
image = var.worker_image
env { name = "DATABASE_SECRET" value = google_secret_manager_secret.database_url.secret_id }
}
}
depends_on = [google_project_service.services]
}

View File

@@ -1,4 +1,5 @@
output "provisioning_enabled" {
value = var.provision
description = "Whether resources were requested. false means no resources are created."
}
output "api_service_name" { value = google_cloud_run_v2_service.api.name }
output "worker_service_name" { value = google_cloud_run_v2_service.worker.name }
output "sql_connection_name" { value = google_sql_database_instance.primary.connection_name }
output "events_topic" { value = google_pubsub_topic.events.name }
output "artifact_repository" { value = google_artifact_registry_repository.images.name }

View File

@@ -1,5 +1,3 @@
project_id = "replace-with-existing-project"
region = "us-central1"
environment = "dev"
invoker_service_account = "producer@example.iam.gserviceaccount.com"
container_image = "us-central1-docker.pkg.dev/replace-with-existing-project/dev-containers/ingress: approved-tag"
project_id = "replace-with-project-id"
api_image = "us-central1-docker.pkg.dev/replace-with-project-id/architecture-demo-images/api@sha256:replace"
worker_image = "us-central1-docker.pkg.dev/replace-with-project-id/architecture-demo-images/worker@sha256:replace"

View File

@@ -1,25 +1,8 @@
variable "provision" {
description = "Explicit opt-in for provisioning. Keep false for planning and validation."
type = bool
default = false
}
variable "project_id" {
description = "Google Cloud project to target when provisioning is enabled."
type = string
}
variable "region" {
type = string
default = "us-central1"
}
variable "service_image" {
description = "Immutable application image reference."
type = string
}
variable "secret_id" {
description = "Secret Manager secret name; the value is never stored in Terraform."
type = string
}
variable "project_id" { type = string; description = "Google Cloud project ID" }
variable "region" { type = string; default = "us-central1" }
variable "name" { type = string; default = "architecture-demo"; validation { condition = can(regex("^[a-z][a-z0-9-]{0,29}$", var.name)); error_message = "name must be lowercase and up to 30 characters." } }
variable "api_image" { type = string; description = "Immutable API container image reference" }
variable "worker_image" { type = string; description = "Immutable worker container image reference" }
variable "sql_tier" { type = string; default = "db-f1-micro" }
variable "sql_ha" { type = bool; default = false }
variable "deletion_protection" { type = bool; default = true }