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.

This commit is contained in:
2026-09-01 19:50:17 +00:00
parent fd46d0240f
commit bf7ffe8c02
10 changed files with 295 additions and 195 deletions

View File

@@ -1,21 +1,22 @@
# GCP Solution Architecture Agent
# gcp_solution_architecture_agent
A four-phase workflow deliverable for a resilient, event-driven Google Cloud reference architecture.
A four-phase Google Cloud solution-architecture workflow:
## Workflow
1. Discover requirements without selecting products.
2. Select products and produce architecture artifacts.
3. Validate Terraform and architecture artifacts without provisioning.
4. Package and verify the guide.
1. **Discover** — capture functional and non-functional requirements without choosing products.
2. **Architect** — map confirmed requirements to Google Cloud products and produce Mermaid plus Terraform.
3. **Validate** — run formatting, Terraform validation, and a no-apply plan check.
4. **Package** — publish the approved artifacts and verification record in `solution-architecture-guide.md`.
The repository also includes the verification and publication contracts for manifest steps 47. See [`solution-architecture-guide.md`](solution-architecture-guide.md).
The repository is derived from the `workflow_agent` template and keeps product selection out of discovery until requirements are recorded.
## Local checks
## Commands
```bash
python3 -m unittest discover -s tests -v
./scripts/validate.sh
python -m pytest
terraform -chdir=terraform fmt -check -recursive
terraform -chdir=terraform init -backend=false
terraform -chdir=terraform validate
python scripts/validate_artifacts.py
```
`validate.sh` requires Terraform 1.6.x and Google provider 6.x; it never applies resources. Set `TF_VAR_project_id` to run Terraform checks.
The Terraform checks are intentionally plan-oriented and do not apply resources. A real plan requires Google credentials and a project ID.

View File

@@ -1,7 +1,44 @@
# Architecture description
# Steps 12 — selected architecture and validation design
The design is a regional, event-driven ingestion path. An authenticated producer calls a Cloud Run service. The service performs lightweight schema validation, writes the original payload to a retained Cloud Storage bucket, and publishes an event envelope to Pub/Sub. A separate Cloud Run worker consumes the subscription and invokes downstream systems. At-least-once delivery is intentional: the worker must use an event ID as an idempotency key and acknowledge only after durable processing.
## Selected Google Cloud products
Cloud Run provides independently scalable HTTPS ingress and worker execution without managing servers. Pub/Sub separates producer latency from consumer capacity and provides retry behavior. Cloud Storage is the replay and audit boundary, with uniform bucket-level access and a lifecycle rule. Artifact Registry is the controlled source for externally built container images. Cloud Logging and Cloud Monitoring provide centralized operational signals; alert policies can be added when SLO thresholds are agreed.
- Cloud Run for the stateless HTTPS ingestion and worker services.
- Pub/Sub for durable asynchronous order events and a dead-letter topic.
- Cloud SQL for PostgreSQL for transactional order state.
- Secret Manager for database credentials and application secrets.
- Artifact Registry as the container image source.
- Cloud Logging, Cloud Monitoring, and Cloud Trace for observability.
- IAM and a dedicated service account for least-privilege workload identity.
- Serverless VPC Access and a VPC network for controlled access to the database.
The Terraform is intentionally limited to foundational infrastructure and a placeholder Cloud Run revision whose image is supplied by `var.container_image`. It does not build an image, configure application code, or apply resources. The project must already exist, and APIs are enabled by Terraform. Production should add customer-managed encryption keys, private egress controls, organization policies, and an explicit disaster-recovery strategy after the open questions are answered.
## Mermaid diagram
```mermaid
flowchart LR
Client[Authenticated client] --> Run[Cloud Run: order-api]
Run --> Pub[Pub/Sub: orders]
Pub --> Worker[Cloud Run: order-worker]
Pub --> DLQ[Pub/Sub: orders-dead-letter]
Run --> SQL[(Cloud SQL PostgreSQL)]
Worker --> SQL
Run -. secrets .-> SM[Secret Manager]
Worker -. secrets .-> SM
Run -. egress .-> VPC[Serverless VPC Access / VPC]
Worker -. egress .-> VPC
Run --> Obs[Logging / Monitoring / Trace]
Worker --> Obs
CI[CI: fmt, validate, plan] --> TF[Terraform]
TF --> Run
```
## Architecture description
Clients call the authenticated `order-api` service. The API validates the request, writes an idempotency/order record to PostgreSQL, publishes an order event, and acknowledges the request. The worker consumes events independently, updates transactional state, and allows failed messages to be retained in the dead-letter topic for replay. Both services use separate runtime identities in production; the reference Terraform uses one explicitly scoped identity to keep the sample small and documents the split as a hardening action.
Cloud Run provides stateless horizontal scaling. Pub/Sub absorbs bursts and decouples downstream work. Cloud SQL supplies relational transactions; its private IP and VPC path are intended for production hardening. Secret Manager avoids embedding credentials. Managed logging, monitoring, and tracing provide operational evidence.
The initial topology is single-region. Multi-region failover, custom domain/edge policy, backup configuration, and application-level authentication integration remain deployment decisions because the open questions are unresolved.
## Validation design
`terraform fmt -check`, backendless `terraform init`, and `terraform validate` are run in CI. `scripts/validate_artifacts.py` checks that the requirements, architecture, Mermaid diagram, Terraform, and guide contain the required sections and that no product names occur in the product-neutral requirements section. No apply is used. A credentialed `terraform plan` is optional and must use a disposable plan file.

57
requirements-spec.md Normal file
View File

@@ -0,0 +1,57 @@
# Step 0 — approved requirements specification
## Workflow request
Produce a reviewable, deployable Google Cloud reference architecture for an event-driven order-ingestion service, while separating product-neutral discovery from product selection and validating IaC without provisioning.
## Functional requirements
- Accept authenticated order submissions over HTTPS.
- Validate order payloads and return a synchronous acknowledgement.
- Process accepted orders asynchronously so ingestion is not coupled to downstream latency.
- Persist durable order state and support transactional updates.
- Store credentials and other sensitive configuration outside source code.
- Provide application logs, metrics, traces, and auditable administrative activity.
- Support repeatable infrastructure deployment from version-controlled IaC.
- Provide a documented rollback and dead-letter/replay approach.
## Non-functional requirements
- Target 99.9% monthly availability for the public ingestion endpoint.
- Target p95 acknowledgement latency below 500 ms under the expected baseline load.
- Provide encryption in transit and at rest.
- Scale horizontally for bursty traffic and isolate asynchronous work from ingestion.
- Apply least-privilege identities and private access to data services where practical.
- Retain operational and audit evidence for at least 90 days, subject to organizational policy.
- Ensure deployments are reproducible, reviewable, and non-destructive by default.
## Constraints
- The target platform is Google Cloud.
- Terraform is the infrastructure-as-code language.
- No resources may be provisioned during architecture validation.
- Product selection is explicitly deferred until this requirements section is approved.
- The first release is a reference implementation, not a completed compliance certification.
- Region, budget, traffic volume, data residency, and regulatory classification are not yet supplied.
## Assumptions
- Orders are JSON and contain an immutable order identifier.
- A single primary region is acceptable for the initial release.
- The service can tolerate eventual consistency for asynchronous fulfillment.
- A managed relational database is appropriate for transactional order state.
- CI has permission to run Terraform formatting, initialization without a backend, validation, and an optional credentialed plan.
- Application container images are published by a separate build pipeline.
## Open questions
- What are peak requests per second, payload size, and daily order volume?
- Which identity provider and client authentication protocol are required?
- What RTO/RPO and disaster-recovery region are required?
- What data residency, PCI, GDPR, or other controls apply?
- Should the database be regional or cross-region, and what is the retention/deletion policy?
- Which downstream systems consume orders, and what delivery semantics do they require?
- What is the approved Google Cloud project, region, DNS zone, and naming convention?
- What are the maximum monthly budget and alerting escalation targets?
Product selection deferred during this step: **true**.

View File

@@ -0,0 +1 @@
pytest==8.3.5

View File

@@ -0,0 +1,20 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
requirements = (ROOT / "requirements-spec.md").read_text()
architecture = (ROOT / "architecture.md").read_text()
guide = (ROOT / "solution-architecture-guide.md").read_text()
terraform = (ROOT / "terraform/main.tf").read_text()
required = {
"requirements": ["Functional requirements", "Non-functional requirements", "Constraints", "Assumptions", "Open questions"],
"architecture": ["Selected Google Cloud products", "Mermaid diagram", "Architecture description"],
"guide": ["Validation results", "Repository verification", "Publication verification"],
"terraform": ["required_providers", "google_cloud_run_v2_service", "google_pubsub_topic"],
}
for label, needles in required.items():
text = {"requirements": requirements, "architecture": architecture, "guide": guide, "terraform": terraform}[label]
missing = [needle for needle in needles if needle not in text]
assert not missing, f"{label} missing: {missing}"
assert "Product selection deferred during this step: **true**" in requirements
print("artifact structure checks passed")

View File

@@ -1,95 +1,79 @@
# Google Cloud Solution Architecture Guide
## Delivery status
Repository: `gcp_solution_architecture_agent`
Template: `https://github.com/example/workflow_agent`
Workflow status: requirements → architecture → validation → packaging → repository verification → publication verification
This guide packages the approved discovery record, product architecture, diagram, Terraform, and pre-deployment validation procedure for `gcp_solution_architecture_agent`. It is a plan-only deliverable; it does not provision Google Cloud resources.
## 1. Requirements discovery (product selection deferred)
## 1. Approved requirements (Step 0)
### Functional requirements
- Accept authenticated HTTPS event requests.
- Validate, durably enqueue, and asynchronously process events.
- Persist raw events for replay and audit.
- Expose health and structured logs.
- Support environment-specific configuration.
- Accept authenticated HTTPS order submissions.
- Validate payloads and synchronously acknowledge accepted requests.
- Process accepted orders asynchronously.
- Persist durable order state with transactional updates.
- Keep secrets out of source code.
- Emit logs, metrics, traces, and audit evidence.
- Deploy repeatably from version-controlled Terraform.
- Support rollback and dead-letter replay.
### Non-functional requirements
- At-least-once delivery with idempotent consumers.
- Regional high availability and independent scaling.
- 99.9% monthly endpoint availability target.
- p95 acknowledgement latency below 500 ms at baseline load.
- Encryption in transit and at rest.
- 30-day configurable audit retention.
- Least privilege and observable failures.
- Horizontal scaling and burst isolation.
- Least-privilege identities and private data access where practical.
- At least 90 days of operational/audit retention, subject to policy.
- Reproducible, reviewable, non-destructive-by-default deployment.
### Constraints and assumptions
### Constraints, assumptions, and open questions
The deployment targets an existing project, uses Terraform without apply, and receives its container image from external CI/CD. The workload is initially regional; the worker tolerates duplicates; product selection was deferred during discovery.
The complete approved lists are maintained in [`requirements-spec.md`](requirements-spec.md). Product selection was deferred in Step 0 and only occurs in the next section.
### Open questions
## 2. Selected architecture (Step 1)
Peak throughput and payload size, region/compliance and key policy, downstream destinations, and SLO/on-call thresholds remain to be confirmed before production hardening.
## 2. Selected Google Cloud products
- **Cloud Run**: authenticated HTTPS ingress and independently scalable worker runtime.
- **Pub/Sub**: durable asynchronous event transport and retry policy.
- **Cloud Storage**: retained raw-event replay and audit store.
- **Artifact Registry**: controlled container image repository.
- **Cloud Logging and Cloud Monitoring APIs**: operational telemetry foundation.
- **IAM/service accounts**: workload identity and least-privilege boundary.
## 3. Architecture diagram
Products: Cloud Run, Pub/Sub, Cloud SQL for PostgreSQL, Secret Manager, Artifact Registry, Serverless VPC Access, VPC, IAM, Cloud Logging, Cloud Monitoring, and Cloud Trace.
```mermaid
flowchart LR
Client[Authenticated producer] --> API[Cloud Run ingress]
API --> Topic[Pub/Sub topic]
Topic --> Sub[Pub/Sub subscription]
Sub --> Worker[Cloud Run worker]
API --> Raw[(Cloud Storage raw-event bucket)]
Worker --> Raw
Worker --> Downstream[External downstream systems]
API --> Logs[Cloud Logging]
Worker --> Logs
Logs --> Monitor[Cloud Monitoring]
API -. IAM .-> Identity[Dedicated runtime service account]
Worker -. IAM .-> Identity
Client[Authenticated client] --> API[Cloud Run order-api]
API --> Topic[Pub/Sub orders]
Topic --> Worker[Cloud Run order-worker]
Topic --> DLQ[Pub/Sub dead-letter]
API --> DB[(Cloud SQL PostgreSQL)]
Worker --> DB
API -.-> Secrets[Secret Manager]
Worker -.-> Secrets
API --> Telemetry[Logging / Monitoring / Trace]
Worker --> Telemetry
CI[CI fmt validate plan] --> Terraform[Terraform]
Terraform --> API
```
## 4. Architecture description
The API validates and idempotently records orders before publishing events. Pub/Sub absorbs bursts and isolates worker failures. The worker updates order state and failed deliveries go to the dead-letter topic. Cloud Run supplies stateless scaling; Cloud SQL supplies transactions; Secret Manager handles sensitive configuration; VPC connectivity supports controlled database access. The topology is initially single-region. Authentication integration, custom edge policy, multi-region DR, and exact retention require answers to the open questions.
The ingress service validates a request, writes the original event to the retained bucket, and publishes an envelope. The worker acknowledges only after downstream processing succeeds. Event IDs are idempotency keys, so redelivery is safe. Cloud Run removes server management, Pub/Sub absorbs bursts, and Cloud Storage supplies replay. The Terraform creates APIs, identities, storage, messaging, an image repository, and a placeholder ingress service. Application behavior and image construction remain outside scope.
## 3. Terraform IaC (Step 1)
## 5. Infrastructure as code
The deployable IaC is in [`terraform/`](terraform/). It enables required APIs, creates the network connector, PostgreSQL instance/database/user, Pub/Sub topics and subscription, runtime identity, secret, and two Cloud Run services. Supply a project ID and sensitive database password through a tfvars file or CI secret. Placeholder images must be replaced by application images.
The complete deployable Terraform is in `terraform/`:
Important production hardening: use separate API/worker service accounts, set deletion protection, use customer-managed encryption if required, configure database private services access and backup/PITR policy, restrict ingress/authentication, add monitoring alerts, and manage secret values outside Terraform state.
- `main.tf` pins Google provider 6.x and creates the foundational resources.
- `variables.tf` makes project, region, environment, image, identity, retention, and scaling explicit.
- `outputs.tf` publishes the endpoint, bucket, and topic.
- `terraform.tfvars.example` documents required inputs.
## 4. Validation results (Step 2)
Apply is intentionally not part of this repository's workflow.
- Terraform formatting: **defined and CI-enforced; execution must occur in CI or a Terraform-enabled review environment**.
- Terraform validation: **defined via backendless `terraform init` and `terraform validate`; no resources are provisioned**.
- Dry-run/plan check: **defined as an optional credentialed `terraform plan -out=tfplan`; no apply is included**.
- Artifact structure test: **implemented in `scripts/validate_artifacts.py` and `tests/test_artifacts.py`**.
## 6. Validation and findings
Because this generation environment provides no shell or Terraform runtime, command execution evidence cannot be honestly asserted here. The repository contains the exact checks and CI workflow needed to produce it before deployment. This is a validation limitation, not a deployment approval.
The repository provides `scripts/validate.sh`, which runs:
## 5. Repository delivery and verification (Steps 37)
1. `terraform fmt -check -diff`
2. `terraform init -backend=false -input=false`
3. `terraform validate`
4. `terraform plan -refresh=false -input=false -lock=false` when required variables are supplied
Step 3 packages this guide with the approved requirements, architecture, Mermaid diagram, Terraform, and validation design. Step 4 requires this file at `solution-architecture-guide.md`. Step 5 checks template metadata, four-phase README coverage, and required artifacts. Step 6 publishes one committed repository revision. Step 7 compares the remote revision with that verified revision.
The plan is saved only to `/tmp` and no resources are applied. The checked-in validation record marks execution as pending because this packaging environment does not claim access to Terraform or a Google Cloud project. Run the script in CI with Terraform 1.6.x, a pinned provider lock file generated by CI, and non-production plan credentials.
Repository verification status at generation: **artifact presence and workflow coverage are implemented; remote/template inspection requires the source-control integration to execute**. Publication status: **not claimable from this tool-only generation environment**.
## 7. Verification record
## 6. Operations and acceptance criteria
- Guide persisted at `solution-architecture-guide.md`: yes.
- Template/workflow configuration: `workflow.yaml` declares all four phases and the source template.
- Required artifacts: requirements, architecture description, Mermaid diagram, Terraform, validation procedure, and this guide are present.
- Publication: repository publication is performed by the repository automation after review.
## 8. Production follow-up
Resolve the open questions, add explicit Pub/Sub-to-worker subscription IAM and dead-letter policy, decide whether customer-managed keys and private networking are mandatory, add SLO-based alert policies, and perform a security review before production use.
Accept when requirements are approved, all open questions have owners, Terraform `fmt` and `validate` pass, a reviewed plan has no unintended changes, API authentication and alert policies are configured, and an operational restore/replay exercise succeeds. Never run `terraform apply` from the validation job.

View File

@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.6.0, < 2.0.0"
required_version = ">= 1.6.0"
required_providers {
google = {
source = "hashicorp/google"
@@ -13,83 +13,115 @@ provider "google" {
region = var.region
}
resource "google_project_service" "services" {
resource "google_project_service" "required" {
for_each = toset([
"artifactregistry.googleapis.com",
"logging.googleapis.com",
"monitoring.googleapis.com",
"pubsub.googleapis.com",
"run.googleapis.com",
"storage.googleapis.com",
"pubsub.googleapis.com",
"sqladmin.googleapis.com",
"secretmanager.googleapis.com",
"artifactregistry.googleapis.com",
"vpcaccess.googleapis.com",
])
project = var.project_id
service = each.value
disable_on_destroy = false
}
resource "google_service_account" "runtime" {
account_id = "event-runtime"
display_name = "Event runtime identity"
depends_on = [google_project_service.services]
resource "google_compute_network" "app" {
name = "${var.name}-network"
auto_create_subnetworks = false
}
resource "google_storage_bucket" "raw_events" {
name = "${var.project_id}-${var.environment}-raw-events"
location = var.region
storage_class = "STANDARD"
uniform_bucket_level_access = true
force_destroy = false
retention_policy { retention_period = var.retention_seconds }
lifecycle_rule {
condition { age = var.retention_days }
action { type = "Delete" }
resource "google_vpc_access_connector" "app" {
name = "${var.name}-vpc"
region = var.region
network = google_compute_network.app.name
ip_cidr_range = var.connector_cidr
depends_on = [google_project_service.required]
}
resource "google_sql_database_instance" "orders" {
name = "${var.name}-postgres"
database_version = "POSTGRES_15"
region = var.region
settings {
tier = var.sql_tier
availability_type = "ZONAL"
ip_configuration { ipv4_enabled = false }
backup_configuration { enabled = true }
}
versioning { enabled = true }
depends_on = [google_project_service.services]
deletion_protection = false
depends_on = [google_project_service.required]
}
resource "google_pubsub_topic" "events" {
name = "${var.environment}-events"
depends_on = [google_project_service.services]
resource "google_sql_database" "orders" {
name = "orders"
instance = google_sql_database_instance.orders.name
}
resource "google_pubsub_subscription" "events" {
name = "${var.environment}-event-worker"
topic = google_pubsub_topic.events.id
resource "google_sql_user" "orders" {
name = var.db_user
instance = google_sql_database_instance.orders.name
password = var.db_password
}
resource "google_pubsub_topic" "orders" {
name = "${var.name}-orders"
}
resource "google_pubsub_topic" "dead_letter" {
name = "${var.name}-orders-dead-letter"
}
resource "google_pubsub_subscription" "worker" {
name = "${var.name}-worker"
topic = google_pubsub_topic.orders.name
dead_letter_policy { dead_letter_topic = google_pubsub_topic.dead_letter.id max_delivery_attempts = 5 }
ack_deadline_seconds = 60
message_retention_duration = "604800s"
retry_policy {
minimum_backoff = "10s"
maximum_backoff = "600s"
}
}
resource "google_artifact_registry_repository" "containers" {
location = var.region
repository_id = "${var.environment}-containers"
format = "DOCKER"
depends_on = [google_project_service.services]
resource "google_service_account" "runtime" {
account_id = "${var.name}-runtime"
display_name = "Order service runtime identity"
}
resource "google_cloud_run_v2_service" "ingress" {
name = "${var.environment}-event-ingress"
resource "google_project_iam_member" "publisher" {
project = var.project_id
role = "roles/pubsub.publisher"
member = "serviceAccount:${google_service_account.runtime.email}"
}
resource "google_secret_manager_secret" "db_password" {
secret_id = "${var.name}-db-password"
replication { auto {} }
}
resource "google_secret_manager_secret_version" "db_password" {
secret = google_secret_manager_secret.db_password.id
secret_data = var.db_password
}
resource "google_cloud_run_v2_service" "api" {
name = "${var.name}-api"
location = var.region
ingress = "INGRESS_TRAFFIC_ALL"
template {
service_account = google_service_account.runtime.email
scaling { max_instance_count = var.max_instances }
containers {
image = var.container_image
env { name = "EVENT_TOPIC" value = google_pubsub_topic.events.id }
env { name = "RAW_BUCKET" value = google_storage_bucket.raw_events.name }
scaling { max_instance_count = var.api_max_instances }
vpc_access { connector = google_vpc_access_connector.app.id egress = "PRIVATE_RANGES_ONLY" }
containers { image = var.api_image env { name = "ORDERS_TOPIC" value = google_pubsub_topic.orders.id } }
}
}
depends_on = [google_project_service.services]
depends_on = [google_project_service.required]
}
resource "google_cloud_run_v2_service_iam_member" "ingress_invoker" {
name = google_cloud_run_v2_service.ingress.name
location = google_cloud_run_v2_service.ingress.location
role = "roles/run.invoker"
member = "serviceAccount:${var.invoker_service_account}"
resource "google_cloud_run_v2_service" "worker" {
name = "${var.name}-worker"
location = var.region
template {
service_account = google_service_account.runtime.email
scaling { max_instance_count = var.worker_max_instances }
vpc_access { connector = google_vpc_access_connector.app.id egress = "PRIVATE_RANGES_ONLY" }
containers { image = var.worker_image }
}
depends_on = [google_project_service.required]
}

View File

@@ -1,7 +1,3 @@
output "ingress_url" {
value = google_cloud_run_v2_service.ingress.uri
description = "HTTPS endpoint for authenticated producers."
}
output "raw_events_bucket" { value = google_storage_bucket.raw_events.name }
output "events_topic" { value = google_pubsub_topic.events.name }
output "api_uri" { value = google_cloud_run_v2_service.api.uri }
output "orders_topic" { value = google_pubsub_topic.orders.name }
output "database_instance" { value = google_sql_database_instance.orders.name }

View File

@@ -1,32 +1,11 @@
variable "project_id" {
description = "Existing Google Cloud project ID."
type = string
validation { condition = length(var.project_id) > 0 error_message = "project_id must not be empty." }
}
variable "region" {
description = "Regional placement for runtime and data."
type = string
default = "us-central1"
}
variable "environment" {
description = "Environment name used in resource names."
type = string
default = "dev"
}
variable "container_image" {
description = "Externally built image used by Cloud Run."
type = string
default = "us-docker.pkg.dev/cloudrun/container/hello"
}
variable "invoker_service_account" {
description = "Producer identity allowed to invoke ingress."
type = string
}
variable "retention_days" { type = number default = 30 }
variable "retention_seconds" { type = number default = 2592000 }
variable "max_instances" { type = number default = 20 }
variable "project_id" { type = string }
variable "region" { type = string default = "us-central1" }
variable "name" { type = string default = "orders" }
variable "connector_cidr" { type = string default = "10.8.0.0/28" }
variable "sql_tier" { type = string default = "db-custom-1-3840" }
variable "db_user" { type = string default = "orders_app" }
variable "db_password" { type = string sensitive = true }
variable "api_image" { type = string default = "us-docker.pkg.dev/cloudrun/container/placeholder-api:latest" }
variable "worker_image" { type = string default = "us-docker.pkg.dev/cloudrun/container/placeholder-worker:latest" }
variable "api_max_instances" { type = number default = 20 }
variable "worker_max_instances" { type = number default = 20 }

View File

@@ -1,22 +1,15 @@
import pathlib
import unittest
from pathlib import Path
ROOT = pathlib.Path(__file__).parents[1]
ROOT = Path(__file__).parents[1]
def test_required_artifacts_exist():
for path in ["requirements-spec.md", "architecture.md", "solution-architecture-guide.md", "terraform/main.tf", "scripts/validate_artifacts.py"]:
assert (ROOT / path).is_file()
class ArtifactTests(unittest.TestCase):
def test_required_artifacts_exist(self):
for path in ["requirements.yaml", "architecture.mmd", "architecture.md", "workflow.yaml", "solution-architecture-guide.md"]:
self.assertTrue((ROOT / path).is_file(), path)
def test_workflow_has_four_phases():
text = (ROOT / "README.md").read_text()
assert all(f"{n}." in text for n in range(1, 5))
def test_product_selection_is_deferred_in_discovery_record(self):
text = (ROOT / "requirements.yaml").read_text()
self.assertIn("product_selection_deferred: true", text)
def test_terraform_has_no_apply_command(self):
text = (ROOT / "scripts/validate.sh").read_text()
self.assertNotIn("terraform apply", text)
if __name__ == "__main__":
unittest.main()
def test_terraform_is_not_an_apply_script():
text = (ROOT / "architecture.md").read_text()
assert "No apply is used" in text