From 1c9624ad5cddb5294f99bd7399b27eb23964e94d Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Tue, 11 Nov 2025 16:42:00 +1100 Subject: [PATCH 01/16] docs: add more docs on foundations, resources, support and more --- .../config/vocabularies/Suga/accept.txt | 22 +- docs/deploy/aws.mdx | 41 ++ docs/deploy/azure.mdx | 14 + docs/deploy/environment-management.mdx | 35 ++ docs/deploy/gcp.mdx | 40 ++ docs/deploy/overview.mdx | 30 ++ docs/deploy/terraform-configuration.mdx | 22 + docs/develop/access-control.mdx | 117 +++++ docs/develop/buckets.mdx | 164 +++++++ docs/develop/databases.mdx | 280 ++++++++++++ docs/develop/entrypoints.mdx | 99 +++++ docs/develop/overview.mdx | 198 +++++++++ docs/develop/services.mdx | 225 ++++++++++ docs/develop/suga-client.mdx | 250 +++++++++++ docs/docs.json | 77 +++- docs/faq.mdx | 218 +++++++++ docs/foundations/deployment.mdx | 412 ++++++++++++++++++ .../foundations/infrastructure-generation.mdx | 198 +++++++++ docs/foundations/local-development.mdx | 349 +++++++++++++++ docs/foundations/overview.mdx | 298 +++++++++++++ docs/{ => foundations}/platforms.mdx | 6 +- docs/foundations/plugins.mdx | 279 ++++++++++++ docs/{ => foundations}/projects.mdx | 4 +- docs/guides/build-platform.mdx | 12 +- docs/guides/plugin-development.mdx | 27 +- docs/guides/static-website-hosting.mdx | 335 ++++++++++++++ .../service-to-bucket-access-control.png | Bin 0 -> 94278 bytes docs/images/develop/app-diagram-example.png | Bin 0 -> 193275 bytes docs/quickstart.mdx | 4 +- docs/sdks/go/client.mdx | 56 +++ docs/sdks/go/databases.mdx | 229 ++++++++++ docs/sdks/node/client.mdx | 39 ++ docs/sdks/node/databases.mdx | 195 +++++++++ docs/sdks/python/client.mdx | 39 ++ docs/sdks/python/databases.mdx | 189 ++++++++ docs/support.mdx | 89 ++++ docs/why-suga.mdx | 170 ++++++++ 37 files changed, 4726 insertions(+), 36 deletions(-) create mode 100644 docs/deploy/aws.mdx create mode 100644 docs/deploy/azure.mdx create mode 100644 docs/deploy/environment-management.mdx create mode 100644 docs/deploy/gcp.mdx create mode 100644 docs/deploy/overview.mdx create mode 100644 docs/deploy/terraform-configuration.mdx create mode 100644 docs/develop/access-control.mdx create mode 100644 docs/develop/buckets.mdx create mode 100644 docs/develop/databases.mdx create mode 100644 docs/develop/entrypoints.mdx create mode 100644 docs/develop/overview.mdx create mode 100644 docs/develop/services.mdx create mode 100644 docs/develop/suga-client.mdx create mode 100644 docs/faq.mdx create mode 100644 docs/foundations/deployment.mdx create mode 100644 docs/foundations/infrastructure-generation.mdx create mode 100644 docs/foundations/local-development.mdx create mode 100644 docs/foundations/overview.mdx rename docs/{ => foundations}/platforms.mdx (96%) create mode 100644 docs/foundations/plugins.mdx rename docs/{ => foundations}/projects.mdx (97%) create mode 100644 docs/guides/static-website-hosting.mdx create mode 100644 docs/images/develop/access-control/service-to-bucket-access-control.png create mode 100644 docs/images/develop/app-diagram-example.png create mode 100644 docs/sdks/go/client.mdx create mode 100644 docs/sdks/go/databases.mdx create mode 100644 docs/sdks/node/client.mdx create mode 100644 docs/sdks/node/databases.mdx create mode 100644 docs/sdks/python/client.mdx create mode 100644 docs/sdks/python/databases.mdx create mode 100644 docs/support.mdx create mode 100644 docs/why-suga.mdx diff --git a/docs/.vale/styles/config/vocabularies/Suga/accept.txt b/docs/.vale/styles/config/vocabularies/Suga/accept.txt index 14480b7f..6d0c318c 100644 --- a/docs/.vale/styles/config/vocabularies/Suga/accept.txt +++ b/docs/.vale/styles/config/vocabularies/Suga/accept.txt @@ -284,4 +284,24 @@ nav prev next toc -uv \ No newline at end of file +uv +Monorepo +monorepo +Minio +Prisma +SQLAlchemy +datasource +sqlalchemy +ORMs +api +debugpy +dlv +pgx +sqlx +pgxpool +playsInline +Reusability +Pulumi +SREs +DevOps +cicd \ No newline at end of file diff --git a/docs/deploy/aws.mdx b/docs/deploy/aws.mdx new file mode 100644 index 00000000..991fc83e --- /dev/null +++ b/docs/deploy/aws.mdx @@ -0,0 +1,41 @@ +--- +title: "AWS Deployment" +description: "Deploy Suga applications to Amazon Web Services" +--- + +Deploy Suga applications to AWS using Lambda, Fargate, S3, and CloudFront. + +## Prerequisites + +- AWS account +- AWS CLI configured +- Terraform installed + +## Quick Start + +```bash +# Build your application +suga build + +# Navigate to generated stack +cd terraform/stacks/my-app +``` + +Create provider configuration: + +```hcl title="provider.tf" +provider "aws" { + region = "us-west-2" +} +``` + +Deploy: + +```bash +terraform init +terraform apply +``` + + + See the full deployment workflow + diff --git a/docs/deploy/azure.mdx b/docs/deploy/azure.mdx new file mode 100644 index 00000000..adf81b08 --- /dev/null +++ b/docs/deploy/azure.mdx @@ -0,0 +1,14 @@ +--- +title: "Azure Deployment" +description: "Deploy Suga applications to Microsoft Azure" +--- + +Azure support is coming soon. + + + Azure platform development is in progress. Check back soon for updates. + + +## Interested in Azure Support? + +Contact [support@addsuga.com](mailto:support@addsuga.com) to express interest or get notified when Azure support is available. diff --git a/docs/deploy/environment-management.mdx b/docs/deploy/environment-management.mdx new file mode 100644 index 00000000..0caff067 --- /dev/null +++ b/docs/deploy/environment-management.mdx @@ -0,0 +1,35 @@ +--- +title: "Environment Management" +description: "Managing multiple deployment environments (dev, staging, production)" +--- + +Manage multiple environments using Terraform workspaces and variable files. + +## Using Workspaces + +```bash +# Create workspaces +terraform workspace new dev +terraform workspace new staging +terraform workspace new prod + +# Deploy to dev +terraform workspace select dev +terraform apply -var-file=environments/dev.tfvars + +# Deploy to prod +terraform workspace select prod +terraform apply -var-file=environments/prod.tfvars +``` + +## Environment-Specific Configuration + +```hcl title="environments/dev.tfvars" +services_api_memory = 512 +services_api_timeout = 10 +``` + +```hcl title="environments/prod.tfvars" +services_api_memory = 2048 +services_api_timeout = 30 +``` diff --git a/docs/deploy/gcp.mdx b/docs/deploy/gcp.mdx new file mode 100644 index 00000000..c294a3f3 --- /dev/null +++ b/docs/deploy/gcp.mdx @@ -0,0 +1,40 @@ +--- +title: "GCP Deployment" +description: "Deploy Suga applications to Google Cloud Platform" +--- + +Deploy Suga applications to GCP using Cloud Run, Cloud Storage, and Cloud CDN. + +## Prerequisites + +- Google Cloud account +- gcloud CLI configured +- Terraform installed + +## Quick Start + +```bash +# Build your application +suga build + +# Navigate to generated stack +cd terraform/stacks/my-app +``` + +Configure required variables: + +```hcl title="terraform.tfvars" +project_id = "my-gcp-project" +region = "us-central1" +``` + +Deploy: + +```bash +terraform init +terraform apply +``` + + + See the full deployment workflow + diff --git a/docs/deploy/overview.mdx b/docs/deploy/overview.mdx new file mode 100644 index 00000000..6d855c14 --- /dev/null +++ b/docs/deploy/overview.mdx @@ -0,0 +1,30 @@ +--- +title: "Deployment Overview" +description: "Overview of deploying Suga applications to cloud providers" +--- + +Deploying with Suga means running standard Terraform commands on infrastructure generated by `suga build`. + + + See the comprehensive deployment guide in Foundations + + +## Quick Links + + + + Deploy to Amazon Web Services + + + + Deploy to Google Cloud Platform + + + + Deploy to Microsoft Azure + + + + Configure Terraform backends and state + + diff --git a/docs/deploy/terraform-configuration.mdx b/docs/deploy/terraform-configuration.mdx new file mode 100644 index 00000000..df463da5 --- /dev/null +++ b/docs/deploy/terraform-configuration.mdx @@ -0,0 +1,22 @@ +--- +title: "Terraform Configuration" +description: "Configure Terraform backends, state management, and variables" +--- + +## Remote State Backends + + + See the complete backend configuration guide + + +## Workspaces for Multiple Environments + +```bash +terraform workspace new dev +terraform workspace new staging +terraform workspace new prod +``` + + + Learn about managing multiple environments + diff --git a/docs/develop/access-control.mdx b/docs/develop/access-control.mdx new file mode 100644 index 00000000..a7105b98 --- /dev/null +++ b/docs/develop/access-control.mdx @@ -0,0 +1,117 @@ +--- +title: "Access Control" +description: "Managing permissions and security in Suga applications" +--- + +Suga's access control model defines which services can access which resources, automatically generating appropriate IAM policies or service account permissions. + +![temp](/images/develop/access-control/service-to-bucket-access-control.png) + +## How Access Control Works + +Access is granted through the `access` property on resources, which can be modified in your project's `suga.yaml` or through the visual editor with the `suga edit` CLI command. + +```yaml +buckets: + uploads: + access: + api: [read, write] # API service can read and write + worker: [read, delete] # Worker can read and delete + +databases: + main: + access: + api: [query] # API can query database +``` + +When you deploy, Suga generates: +- **IAM policies** (AWS) with least-privilege permissions +- **Service account bindings** (GCP) with appropriate roles +- **Network security rules** allowing service-to-resource communication + +## Permission Types + +### Bucket Permissions + +- `read` - Download/read objects +- `write` - Upload/write objects +- `delete` - Delete objects +- `all` - Shorthand for read, write, delete + +```yaml +buckets: + data: + access: + uploader: [write] + processor: [read, delete] + api: [read] +``` + +### Database Permissions + +- `query` - Full SQL access (SELECT, INSERT, UPDATE, DELETE) + +```yaml +databases: + main: + access: + api: [query] + analytics: [query] +``` + +## Least Privilege + +Suga encourages and follows the principle of least privilege: +- By default, services cannot access other resources +- Services only get permissions they need +- No wildcards or overly broad policies +- Separate identities per service + +When using the standard Suga AWS Platforms (`suga/aws`), here is an example of the kind of IAM policy that will be generated: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Resource": "arn:aws:s3:::my-app-uploads/*" + } + ] +} +``` + + + If you use your own Suga [resource plugins](/foundations/plugins), you're free to construct the IAM, roles, etc. as you see fit. + + +## Best Practices + +1. **Grant minimum permissions** - Only what each service needs +2. **Separate services** - Different services for different roles +3. **Review access patterns** - Regularly audit who accesses what +4. **Use read-only when possible** - Many services only need read access + +## Learn More + + + + Service configuration + + + + Bucket permissions + + + + Database access + + + + AWS IAM details + + diff --git a/docs/develop/buckets.mdx b/docs/develop/buckets.mdx new file mode 100644 index 00000000..7855cecb --- /dev/null +++ b/docs/develop/buckets.mdx @@ -0,0 +1,164 @@ +--- +title: "Buckets" +description: "Object storage for files, images, and assets" +--- + +Buckets provide cloud object storage for your application - think files, images, videos, documents, and other unstructured data. + +## What is a Bucket? + +A bucket is object storage that: +- **Stores files** - Any file type, any size +- **Provides access** - Read, write, delete operations +- **Scales automatically** - No capacity planning needed +- **Works everywhere** - Same interface locally and in production + +```yaml title="Basic bucket definition" +buckets: + uploads: + access: + api: [read, write, delete] + profile-images: + access: + api: [read, write] + frontend: [read] +``` + +## Bucket Configuration + +### Access Control + +Grant services access to buckets: + +```yaml +buckets: + uploads: + access: + api: [read, write, delete] # Full access + worker: [read, delete] # Read and delete only + frontend: [read] # Read-only +``` + +**Permission Types:** +- `read` - Download/read files +- `write` - Upload/write files +- `delete` - Delete files +- `all` - Shorthand for read, write, delete + +### Content Path (Static Files) + +Deploy static files to a bucket: + +```yaml +buckets: + frontend: + content_path: ./build # Deploy React/Vue/Angular build + +entrypoints: + web: + routes: + /: frontend # Serve static files from bucket +``` + +When you deploy, files from `./build` are uploaded to the bucket. + +## Using Buckets in Code + +With Suga's generated SDK: + + + + ```typescript + import { SugaClient } from './suga/client'; + + const suga = new SugaClient(); + + // Write file + await suga.uploads.write('path/to/file.txt', Buffer.from('data')); + + // Read file + const data = await suga.uploads.read('path/to/file.txt'); + + // Delete file + await suga.uploads.delete('path/to/file.txt'); + ``` + + + + ```python + from suga.client import SugaClient + + suga = SugaClient() + + # Write file + suga.uploads.write('path/to/file.txt', b'data') + + # Read file + data = suga.uploads.read('path/to/file.txt') + + # Delete file + suga.uploads.delete('path/to/file.txt') + ``` + + + + ```go + import "myapp/suga" + + client, _ := suga.NewClient() + + // Write file + client.Uploads.Write("path/to/file.txt", []byte("data")) + + // Read file + data, _ := client.Uploads.Read("path/to/file.txt") + + // Delete file + client.Uploads.Delete("path/to/file.txt") + ``` + + + + + Learn how to access resources from your service code + + +## Local Development + +During `suga dev`, buckets are emulated using the filesystem: + +``` +.suga/ +└── buckets/ + └── uploads/ + └── file.txt +``` + +You can: +- View files in `.suga/buckets/{bucket-name}/` +- Seed buckets by placing files there +- Test bucket operations without cloud access + + + Learn how to develop applications locally with Suga + + +## Learn More + + + + Complete API reference + + + + Permission management + + + + Deploy static websites + + + + Test buckets locally + + diff --git a/docs/develop/databases.mdx b/docs/develop/databases.mdx new file mode 100644 index 00000000..2a72ef51 --- /dev/null +++ b/docs/develop/databases.mdx @@ -0,0 +1,280 @@ +--- +title: "Databases" +description: "PostgreSQL databases for structured data" +--- + +Databases provide persistent SQL storage for your application's structured data. + +## What is a Database? + +A database in Suga is a PostgreSQL database that: +- **Stores structured data** - Tables, relations, indexes +- **Provides SQL access** - Full PostgreSQL compatibility +- **Scales automatically** - Managed database service +- **Integrates with services** - Automatic connection configuration + +```yaml title="Basic database" +databases: + main: + access: + api: [query] + worker: [query] +``` + +## Database Configuration + +### Access Control and Connection Strings + +When you grant a service access to a database, Suga automatically injects the database connection string into that service's environment variables: + +```yaml title="Database with environment variable injection" +databases: + main: + subtype: neon + access: + api: [query] + worker: [query] + env_var_key: DATABASE_URL # Connection string injected as DATABASE_URL +``` + +Services with access automatically receive: +- **Full connection string** - Including host, port, database name, and credentials +- **Environment variable** - Specified by `env_var_key` +- **Ready to use** - Works immediately with standard PostgreSQL libraries + +**Permission:** +- `query` - Full read/write SQL access + +### Multiple Databases + +When using multiple databases, each must have a unique `env_var_key` to avoid conflicts: + +```yaml title="Multiple databases with unique env vars" +databases: + users: + subtype: neon + access: + api: [query] + env_var_key: USERS_DATABASE_URL + + products: + subtype: neon + access: + api: [query] + env_var_key: PRODUCTS_DATABASE_URL + + orders: + subtype: neon + access: + api: [query] + env_var_key: ORDERS_DATABASE_URL +``` + +Now the `api` service receives three separate connection strings: +- `USERS_DATABASE_URL` +- `PRODUCTS_DATABASE_URL` +- `ORDERS_DATABASE_URL` + + + Each database **must** have a unique `env_var_key` if the same service accesses multiple databases. Using the same key for different databases will cause conflicts. + + +## Using Databases in Code + +Access databases using standard PostgreSQL libraries with the automatically injected connection string: + + + + ```typescript + import { Pool } from 'pg'; + + // Connection string automatically injected by Suga + const pool = new Pool({ + connectionString: process.env.DATABASE_URL + }); + + // Query database + const result = await pool.query( + 'SELECT * FROM users WHERE active = $1', + [true] + ); + const users = result.rows; + + // Insert data + await pool.query( + 'INSERT INTO users (name, email) VALUES ($1, $2)', + ['Alice', 'alice@example.com'] + ); + + // Update data + await pool.query( + 'UPDATE users SET name = $1 WHERE id = $2', + ['Bob', 1] + ); + ``` + + Install the PostgreSQL client: + ```bash + npm install pg + ``` + + + + ```python + import psycopg2 + import os + + # Connection string automatically injected by Suga + conn = psycopg2.connect(os.environ['DATABASE_URL']) + cursor = conn.cursor() + + # Query database + cursor.execute('SELECT * FROM users WHERE active = %s', [True]) + users = cursor.fetchall() + + # Insert data + cursor.execute( + 'INSERT INTO users (name, email) VALUES (%s, %s)', + ['Alice', 'alice@example.com'] + ) + conn.commit() + + # Update data + cursor.execute( + 'UPDATE users SET name = %s WHERE id = %s', + ['Bob', 1] + ) + conn.commit() + ``` + + Install the PostgreSQL client: + ```bash + pip install psycopg2-binary + ``` + + + + ```go + import ( + "context" + "os" + "github.com/jackc/pgx/v5/pgxpool" + ) + + // Connection string automatically injected by Suga + pool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) + if err != nil { + panic(err) + } + defer pool.Close() + + // Query database + rows, err := pool.Query(context.Background(), + "SELECT * FROM users WHERE active = $1", true) + + // Insert data + _, err = pool.Exec(context.Background(), + "INSERT INTO users (name, email) VALUES ($1, $2)", + "Alice", "alice@example.com") + + // Update data + _, err = pool.Exec(context.Background(), + "UPDATE users SET name = $1 WHERE id = $2", + "Bob", 1) + ``` + + Install the PostgreSQL client: + ```bash + go get github.com/jackc/pgx/v5/pgxpool + ``` + + + +### Connection String Format + +The injected `DATABASE_URL` contains everything needed to connect: + +``` +postgresql://username:password@host:port/database?sslmode=require +``` + +This works with any PostgreSQL-compatible library or ORM (Prisma, TypeORM, SQLAlchemy, etc.): + + + + ```javascript title="prisma/schema.prisma" + datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + } + ``` + + + + ```typescript + import { DataSource } from 'typeorm'; + + const dataSource = new DataSource({ + type: 'postgres', + url: process.env.DATABASE_URL, + entities: [User], + }); + ``` + + + + ```python + from sqlalchemy import create_engine + import os + + engine = create_engine(os.environ['DATABASE_URL']) + ``` + + + +## Database Migrations + +Run migrations as part of your deployment: + + + Learn how to manage database schema changes + + +## Local Development + +During `suga dev`, PostgreSQL databases run automatically with no manual setup required: + +- Suga starts a local PostgreSQL instance for each database +- Connection strings are injected into services via `env_var_key` +- Data persists in `.suga/databases/` between sessions +- Use the same PostgreSQL libraries and ORMs as production + +```bash +suga dev +``` + +Your services receive `DATABASE_URL` (or your custom `env_var_key`) automatically, making the same code work in both local development and production. + + + Learn more about local development with databases + + +## Learn More + + + + Complete API reference + + + + Schema management + + + + Local PostgreSQL during suga dev + + + + Permission management + + diff --git a/docs/develop/entrypoints.mdx b/docs/develop/entrypoints.mdx new file mode 100644 index 00000000..600f07a1 --- /dev/null +++ b/docs/develop/entrypoints.mdx @@ -0,0 +1,99 @@ +--- +title: "Entrypoints" +description: "HTTP routing and CDN configuration for exposing your application" +--- + +Entrypoints provide HTTP access to your application through CDN and routing configuration. They act as the front door to your services and static assets. + +## What is an Entrypoint? + +An entrypoint is a CDN + router that: +- **Routes HTTP requests** - To services or buckets based on URL paths +- **Provides HTTPS** - Automatic SSL/TLS termination +- **Caches responses** - CDN caching for performance +- **Handles scaling** - Automatically scales with traffic + +```yaml title="Basic entrypoint" +entrypoints: + web: + routes: + /api/: api # Route /api/* to api service + /: frontend # Route /* to frontend service +``` + +## Route Configuration + +Routes map URL paths to destinations: + +```yaml +entrypoints: + web: + routes: + /api/: api-service # Service destination + /static/: assets # Bucket destination + /: frontend # Service destination +``` + +**Path Matching:** +- `/api/` - Matches `/api/*` (with trailing content) +- `/` - Matches all remaining paths + +Routes are evaluated in order - most specific first. + +## Custom Domains + + + Most entrypoints support custom domains, however, this functionality is [platform](/foundations/platforms.mdx) specific. + + For example, the `suga/aws` platform will generate Terraform Variables during `suga build`, which allow you to specify a custom domain per entrypoint. + + +## Common Patterns + +**API + Frontend:** +```yaml +entrypoints: + web: + routes: + /api/: api + /: frontend +``` + +**Microservices Gateway:** +```yaml +entrypoints: + gateway: + routes: + /users/: users-service + /products/: products-service + /orders/: orders-service +``` + +**Static Site with API:** +```yaml +entrypoints: + web: + routes: + /api/: api + /: static-assets # Bucket with static files +``` + +## Learn More + + + + Static website hosting + + + + CloudFront configuration + + + + Route to static files in buckets + + + + Configure routing destinations + + diff --git a/docs/develop/overview.mdx b/docs/develop/overview.mdx new file mode 100644 index 00000000..40d03da4 --- /dev/null +++ b/docs/develop/overview.mdx @@ -0,0 +1,198 @@ +--- +title: "Development Overview" +description: "Understanding Suga's resource types and how to define your application architecture" +--- + +Suga applications are built from several core resource types that work together to create complete cloud applications. This page introduces these resources and explains how they interact. + +## Suga Resources + +Every Suga application can use these resource types: + + + + Application containers that run your code + + + + HTTP routing and CDN configuration + + + + Object storage for files and assets + + + + PostgreSQL databases for structured data + + + +## Resource Relationships + +Resources connect to form your application architecture: + +![Project Editor Diagram Example](/images/develop/app-diagram-example.png) + +## Defining Resources + +Resources are defined in `suga.yaml`: + +```yaml title="suga.yaml" +target: suga/aws@1 +name: my-app +description: My cloud application + +services: + # Define services here + +buckets: + # Define buckets here + +databases: + # Define databases here + +entrypoints: + # Define entrypoints here +``` + +### Using the Visual Editor + +The easiest way to define resources is with the visual editor, by running the `edit` command in your project directory: + +```bash +suga edit +``` + +The visual editor provides: +- **Drag-and-drop** resource creation, using the available resource from your chosen platform +- **Visual connections** to establish relationships and access +- **Property editors** for configurations of resources +- **Real-time validation** of your architecture and configuration +- **Automatic YAML sync** with bidirectional live update to your project's suga.yaml file +- **AI Assistant** that can collaborate with you on your design + +### Editing YAML Directly + +You can also edit `suga.yaml` directly: + +```yaml title="suga.yaml" +services: + api: + container: + docker: + dockerfile: Dockerfile + context: . + dev: + script: npm run dev +``` + +## Resource Naming + +Resource names must follow these rules: + +- **Lowercase letters and numbers** - `api`, `api2`, `frontend` +- **Underscores allowed** - `api_service`, `user_uploads` +- **Start with letter** - `api` (not `2api`) +- **No special characters** - Avoid `-`, `.`, `/`, etc. + + + Resource names typically become part of cloud resource identifiers. Choose names that are descriptive and unlikely to change. + + +## Resource Configuration + +Each resource type has unique configuration options; however, there are some common configuration options. + +### Subtypes + +Cloud provider like AWS provide many container and compute runtime options including EC2, ECS and Fargate, Lambda, EKS, and more. The list gets longer as you look to other cloud providers. + +The same is true for other resources like Buckets, which might use S3 on AWS, Cloud Storage on GCP, Blob Storage on Azure or another option like self-hosted Minio on Kubernetes. + +Suga helps you build applications that work well on any of these services without significant modifications to your application code. Reducing vendor lock-in and the cost of change. This allows you to migrate between services during development or as you better understand the performance, cost and other needs of your applications. + +The resource subtype in the `suga.yaml` file is how you tell Suga which specific service you want to use: + +```yaml title="Choose specific cloud service" +services: + api: + subtype: lambda # AWS Lambda (serverless) + worker: + subtype: fargate # AWS Fargate (containers) + +buckets: + uploads: + subtype: s3 # AWS S3 + +entrypoints: + web: + subtype: cloudfront # AWS CloudFront +``` + +The available subtypes depend on your target [platform](/foundations/platforms): +- `suga/aws@1` - Lambda, Fargate, S3, CloudFront +- `suga/gcp@1` - Cloud Run, Cloud Storage, Cloud CDN +- `you/custom@1` - Any other cloud or resources you like, including cross-cloud deployments + +### Access Control + +Resources can grant access to services: + +```yaml title="Grant service access to resources" +buckets: + uploads: + access: + api: [read, write, delete] # API service can read/write/delete + frontend: [read] # Frontend can only read + +databases: + main: + access: + api: [query] # API can query the database +``` + +This generates appropriate IAM policies or service account permissions. + + + Learn more about access control patterns + + + + +## Accessing Resources from Code + +Once you've defined resources in your `suga.yaml`, Suga provides generated client libraries for cloud-agnostic resource access. The same code works locally with `suga dev` and in production across any cloud provider. + + + Learn about generated client libraries for buckets and resource access patterns + + +## Learn More + +Dive deeper into each resource type: + + + + Application containers and compute + + + + HTTP routing and CDN + + + + Object storage and file management + + + + PostgreSQL databases + + + + Security and permissions + + + + How Suga deploys applications + + diff --git a/docs/develop/services.mdx b/docs/develop/services.mdx new file mode 100644 index 00000000..f8ae66dd --- /dev/null +++ b/docs/develop/services.mdx @@ -0,0 +1,225 @@ +--- +title: "Services" +description: "Application containers that run your code" +--- + +Services are the compute layer of your Suga application - containers that run your application code and handle business logic. + +## What is a Service? + +A service is an application container that: +- **Runs your code** - Node.js, Python, Go, or any containerized application +- **Handles requests** - HTTP requests, background jobs, scheduled tasks +- **Accesses resources** - Buckets, databases, other services +- **Scales automatically** - Based on traffic (Lambda, Cloud Run) or configuration (Fargate) + +```yaml title="Basic service definition" +services: + api: + dev: + script: npm run dev + container: + docker: + dockerfile: Dockerfile + context: . + env: + EXT_URL: "https://example.com/api" +``` + +## Service Configuration + +### Development Script + +The `dev.script` tells Suga how to run your service locally: + +```yaml +services: + api: + dev: + script: npm run dev # Node.js + worker: + dev: + script: python main.py # Python + processor: + dev: + script: go run main.go # Go +``` + +During `suga dev`, this script runs and can automatically restart on code changes. + +### Container Configuration + +For production deployment, services need container configuration: + +**Using Dockerfile:** +```yaml +services: + api: + container: + docker: + dockerfile: Dockerfile + context: . +``` + +**Using Pre-built Image:** +```yaml +services: + api: + container: + image: + id: "my-registry/api:latest" +``` + +### Environment Variables + +Configure services with environment variables: + +```yaml +services: + api: + env: + DATABASE_URL: postgresql://... + REDIS_URL: redis://... + LOG_LEVEL: info + FEATURE_XYZ: "true" +``` + +#### PORT environment variable + +In order to establish HTTP routes/requests Suga will automatically inject a `PORT` env var into each of your services, indicating which port it should start on. + +```typescript index.ts +const port = process.env.PORT || 8000; +app.listen(port, () => { + console.log(`Server running on port ${port}`); +}); +``` + +### Working Directory + +The `working_directory` property sets the base directory for the service. All other paths in the service configuration are resolved relative to this directory: + +```yaml title="Service with working directory" +services: + api: + working_directory: ./api + dev: + script: npm run dev # Runs from ./api directory + container: + docker: + dockerfile: Dockerfile # Resolves to ./api/Dockerfile + context: . # Resolves to ./api +``` + +**If not specified**, the project root (where `suga.yaml` is located) is used as the working directory. + +#### Monorepo Example + +Working directories are particularly useful in monorepo structures: + +```yaml title="Monorepo with multiple services" +services: + api: + working_directory: ./services/api + dev: + script: npm run dev + container: + docker: + dockerfile: Dockerfile + context: . + env: + SERVICE_NAME: api + + frontend: + working_directory: ./services/frontend + dev: + script: npm run dev + container: + docker: + dockerfile: Dockerfile + context: . + env: + SERVICE_NAME: frontend + + worker: + working_directory: ./services/worker + dev: + script: python main.py + container: + docker: + dockerfile: Dockerfile + context: . +``` + +Project structure: +``` +my-app/ +├── suga.yaml +└── services/ + ├── api/ + │ ├── Dockerfile + │ ├── package.json + │ └── src/ + ├── frontend/ + │ ├── Dockerfile + │ ├── package.json + │ └── src/ + └── worker/ + ├── Dockerfile + ├── requirements.txt + └── main.py +``` + +## Service Access Control + +Services can access other resources: + +```yaml +services: + api: + # Access granted through bucket configuration + +buckets: + uploads: + access: + api: [read, write, delete] + +databases: + main: + access: + api: [query] +``` + +This automatically generates IAM policies or service account permissions. + + + Learn more about access control patterns + + +## Accessing Resources from Services + +Services interact with resources like buckets using generated Suga client libraries. For databases, services receive connection strings via environment variables. + + + Learn how to access resources from your service code + + +## Learn More + + + + Grant resource access + + + + Test services locally + + + + Generated client libraries for resources + + + + Configure database access + + diff --git a/docs/develop/suga-client.mdx b/docs/develop/suga-client.mdx new file mode 100644 index 00000000..12ba74a6 --- /dev/null +++ b/docs/develop/suga-client.mdx @@ -0,0 +1,250 @@ +--- +title: "Suga Client Libraries" +description: "Generated client libraries for cloud-agnostic resource access" +--- + +Once you've defined resources in your `suga.yaml`, you need a way to interact with them from your application code. Suga provides **generated client libraries** that give you a cloud-agnostic interface to your resources. + +## Why Use Generated Clients? + +The Suga client generation approach offers several key advantages: + +- **Cloud Portability** - Same code works on AWS, GCP, or any platform +- **Local Development** - Enable `suga dev` with emulated cloud services +- **Type Safety** - IDE autocomplete and compile-time error checking +- **Simplified API** - Consistent interface across all cloud providers +- **Tailored Surface** - Only includes resources and permissions you've defined + +## What Resources Support Client Generation? + +Currently, Suga generates clients for: + +- **Buckets** - Object storage operations (read, write, delete) + +For other resources: +- **Databases** - Use standard PostgreSQL libraries with injected connection strings (see [Database Access](/develop/databases)) +- **Services** - Communicate through entrypoints or shared resources + +### Generated Client Libraries + +Generate type-safe client libraries using the `suga generate` command: + + + + ```bash + suga generate --node --node-out ./suga + ``` + + ```typescript + import { SugaClient } from './suga/client'; + import { Pool } from 'pg'; + + const suga = new SugaClient(); + + // Access bucket + await suga.uploads.write('file.txt', Buffer.from('Hello!')); + const data = await suga.uploads.read('file.txt'); + + // Access database (using injected connection string) + const pool = new Pool({ connectionString: process.env.DATABASE_URL }); + const result = await pool.query('SELECT * FROM users WHERE active = $1', [true]); + ``` + + + + ```bash + suga generate --python --python-out ./suga_gen + ``` + + ```python + from suga.client import SugaClient + import psycopg2 + import os + + suga = SugaClient() + + # Access bucket + suga.uploads.write('file.txt', b'Hello!') + data = suga.uploads.read('file.txt') + + # Access database (using injected connection string) + conn = psycopg2.connect(os.environ['DATABASE_URL']) + cursor = conn.cursor() + cursor.execute('SELECT * FROM users WHERE active = %s', [True]) + users = cursor.fetchall() + ``` + + + + ```bash + suga generate --go --go-out ./suga --go-package-name suga + ``` + + ```go + import ( + "myapp/suga" + "os" + "github.com/jackc/pgx/v5/pgxpool" + ) + + client, _ := suga.NewClient() + + // Access bucket + client.Uploads.Write("file.txt", []byte("Hello!")) + data, _ := client.Uploads.Read("file.txt") + + // Access database (using injected connection string) + pool, _ := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) + rows, _ := pool.Query(context.Background(), "SELECT * FROM users WHERE active = $1", true) + ``` + + + +The generated client automatically includes only the resources and permissions defined in your `suga.yaml`, providing a tailored API surface for your application. + +### Cloud-Agnostic Portability + +The Suga client maximizes portability by abstracting away cloud provider differences. When you use the client to interact with resources, **the same code works regardless of where your application is deployed**: + +```typescript title="Write once, run anywhere" +// This code works identically on: +// - Local development (file system emulation) +// - AWS deployment (S3) +// - GCP deployment (Cloud Storage) +// - Any custom platform + +await suga.uploads.write('user-profile.jpg', imageData); +``` + +**Without Suga**, you'd need different code for each cloud provider: + +```typescript title="Cloud-specific code (without Suga)" +// AWS +import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; +const s3 = new S3Client({ region: 'us-east-1' }); +await s3.send(new PutObjectCommand({ Bucket: 'my-bucket', Key: 'file.txt', Body: data })); + +// GCP +import { Storage } from '@google-cloud/storage'; +const storage = new Storage(); +await storage.bucket('my-bucket').file('file.txt').save(data); +``` + +By reducing reliance on cloud-specific SDKs, Suga enables: +- **True multi-cloud deployment** - Switch providers without changing application code +- **Simplified codebase** - No conditional logic for different cloud providers +- **Easier testing** - Mock resources uniformly across environments +- **Future-proofing** - Platform changes don't require application code updates + +### Local Development with `suga dev` + +The generated client unlocks powerful local development capabilities. When you run `suga dev`, Suga automatically substitutes real cloud services with local emulations: + +```bash +suga dev +``` + +``` +suga dev + + ⚡ Suga Pre-release (adb9021) + - App: my_app + - Addr: :50051 + +Databases + +✓ Starting [database] postgresql://localhost:5433/database + +Services + +✓ Starting [worker] +✓ Starting [api] + +Entrypoints + +✓ Starting [ingress] http://localhost:3002 + +Use Ctrl-C to exit +``` + +**Your application code doesn't change** - the same client calls work locally: + +```typescript +// Works both locally and in production +await suga.uploads.write('file.txt', data); +// Local: writes to .suga/buckets/uploads/ +// AWS: writes to S3 +// GCP: writes to Cloud Storage +``` + +This seamless transition between local and cloud environments means: +- **No cloud account needed** for development +- **Zero cloud costs** during development +- **Fast iteration** - test changes instantly without deployment +- **Offline development** - work anywhere, no internet required +- **Consistent behavior** - same resource interactions locally and in production + +### How It Works + +The Suga client uses runtime adapters provided by your target platform's plugins: + +1. **In Production:** + ``` + Application → Suga Client → Platform Runtime Adapter → Cloud Provider SDK → Cloud Service + ``` + Example: `suga.uploads.write()` → S3 Adapter → AWS SDK → S3 + +2. **During `suga dev`:** + ``` + Application → Suga Client → Local Emulation Adapter → File System + ``` + Example: `suga.uploads.write()` → Local Adapter → `.suga/buckets/uploads/` + +The application code remains identical - only the underlying adapter changes based on the environment. + +### Type Safety and Auto-Completion + +Generated clients provide full type safety and IDE auto-completion: + +```typescript +const suga = new SugaClient(); + +// IDE knows about all your resources +suga.uploads. // ← Auto-complete shows: write, read, delete +suga.unknownBucket. // ← Compile error: doesn't exist in suga.yaml +``` + +This catches errors at development time rather than runtime, and makes exploring the API easier. + +### When to Use the Generated Client + +**Use the generated Suga client when:** +- You want cloud-agnostic code +- You need local development with `suga dev` +- You're building a multi-cloud application +- You want simplified resource access + +**Use native cloud SDKs directly when:** +- You need cloud-specific features not exposed by Suga +- You have deep integration requirements with a specific provider +- You're gradually migrating an existing application + +You can mix both approaches - use Suga clients for common operations and native SDKs for specialized needs. + + + + Complete API documentation + + + + Learn about local development workflow + + + + CLI reference for suga generate + + + + Configure resource permissions + + \ No newline at end of file diff --git a/docs/docs.json b/docs/docs.json index dbfba55e..2fba9291 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -19,30 +19,62 @@ "groups": [ { "group": "Getting Started", - "pages": ["introduction", "installation", "quickstart"] + "pages": ["introduction", "why-suga", "installation", "quickstart"] }, { - "group": "Core Concepts", - "pages": ["projects", "platforms"] + "group": "Foundations", + "pages": [ + "foundations/overview", + "foundations/projects", + "foundations/platforms", + "foundations/plugins", + "foundations/infrastructure-generation", + "foundations/local-development", + "foundations/deployment" + ] + }, + { + "group": "Develop", + "pages": [ + "develop/overview", + "develop/services", + "develop/entrypoints", + "develop/buckets", + "develop/databases", + "develop/suga-client", + "develop/environment-variables", + "develop/access-control" + ] + }, + { + "group": "Deploy", + "pages": [ + "deploy/overview", + "deploy/aws", + "deploy/gcp", + "deploy/azure", + "deploy/terraform-configuration", + "deploy/environment-management" + ] }, { "group": "Guides", "pages": [ "guides", "guides/add-suga", + "guides/static-website-hosting", "guides/personal-access-tokens", "guides/cicd-authentication", "guides/mcp-integration", "guides/build-platform", "guides/plugin-development", "guides/database-migration", - "guides/terraform-backend-config", - "guides/aws/environment-management" + "guides/terraform-backend-config" ] }, { "group": "Resources", - "pages": ["registry"] + "pages": ["registry", "faq", "support"] } ] }, @@ -88,17 +120,32 @@ { "group": "Python", "icon": "python", - "pages": ["sdks/python", "sdks/python/storage"] + "pages": [ + "sdks/python", + "sdks/python/client", + "sdks/python/storage", + "sdks/python/databases" + ] }, { "group": "Node.js", "icon": "node-js", - "pages": ["sdks/node", "sdks/node/storage"] + "pages": [ + "sdks/node", + "sdks/node/client", + "sdks/node/storage", + "sdks/node/databases" + ] }, { "group": "Go", "icon": "golang", - "pages": ["sdks/go", "sdks/go/storage"] + "pages": [ + "sdks/go", + "sdks/go/client", + "sdks/go/storage", + "sdks/go/databases" + ] } ] } @@ -160,5 +207,15 @@ "posthog": { "apiKey": "phc_XwujEojDf0Qq5EeBqOTo0Xf9ZAi7NZZIrIvvLGr8sZ6" } - } + }, + "redirects": [ + { + "source": "/projects", + "destination": "/foundations/projects" + }, + { + "source": "/platforms", + "destination": "/foundations/platforms" + } + ] } diff --git a/docs/faq.mdx b/docs/faq.mdx new file mode 100644 index 00000000..6aa37559 --- /dev/null +++ b/docs/faq.mdx @@ -0,0 +1,218 @@ +--- +title: "Frequently Asked Questions" +description: "Common questions about Suga" +--- + +## General + +### What is Suga? + +Suga is a cloud development platform that combines visual infrastructure design with platform-driven governance. It generates production-ready Terraform from high-level application specifications, enabling developers to deploy instantly while platform teams maintain complete control. + +### How is Suga different from other tools? + +See our [Why Suga?](/why-suga) page for detailed comparisons with PaaS platforms, raw Terraform/Pulumi, and serverless frameworks. + +### Is Suga open source? + +The Suga CLI, official platforms and plugins are open-source, including the Terraform generation code (engines). + +### What cloud providers does Suga support? + +- **AWS** - Lambda, Fargate, S3, CloudFront (full support) +- **GCP** - Cloud Run, Cloud Storage, Cloud CDN (full support) +- **Azure** - Coming soon + +Custom platforms can target any cloud provider, using standard Terraform Modules. + +## Getting Started + +### Do I need cloud provider experience? + +Basic familiarity helps, but Suga abstracts much of the complexity. You can deploy without being a cloud expert. + +### Can I use Suga with my existing application? + +Yes! See the [Add Suga to Existing Apps](/guides/add-suga) guide. + +### Do I need to learn Terraform? + +No, but understanding Terraform basics can help when customizing deployments. Suga generates all Terraform for you. + +### Can I develop without cloud access? + +Yes! `suga dev` provides local emulation of cloud services with no cloud account or internet connection needed. + +## Technical + +### What languages does Suga support? + +Services can be written in any language that runs in a container (Node.js, Python, Go, Java, Ruby, etc.). + +The optional SDK client generation currently supports: +- Node.js/TypeScript +- Python +- Go + +### Can I use custom cloud configurations? + +Yes, you can: +1. Override platform variables +2. Add custom Terraform resources +3. Create custom platforms +4. Build custom plugins + +### How does Suga handle state? + +Suga uses standard Terraform state management. Use remote backends (S3, GCS, Terraform Cloud) for team collaboration. + +### Can I migrate away from Suga? + +Yes. The generated Terraform is standard and can be maintained independently if you decide to stop using Suga. + +### Does Suga support Kubernetes? + +Not yet, but Kubernetes platform support is planned. + +## Deployment + +### How much does deployment cost? + +Suga itself is free during early access. You pay only your cloud provider's standard rates for resources (Lambda, S3, CloudFront, etc.). + +There is no Suga markup on cloud costs. + +### How long does deployment take? + +First deployment: 5-15 minutes (Terraform provisioning cloud resources) +Code updates: 1-5 minutes (depends on service type and cloud provider) + +### Can I deploy to multiple environments? + +Yes! Use Terraform workspaces or separate state files: + +```bash +terraform workspace new prod +terraform workspace new staging +terraform workspace new dev +``` + +### How do I roll back a deployment? + +Revert your code changes, rebuild with `suga build`, and `terraform apply`. Terraform will update to the previous configuration. + +### What happens if deployment fails? + +Terraform will show the error and leave your infrastructure in a consistent state. Fix the issue and run `terraform apply` again. + +## Development + +### Can I use my own frameworks? + +Yes! Suga works with Express, FastAPI, Django, Go HTTP, and any other framework that runs in a container. + +### How do I debug services locally? + +Use your language's standard debugger with `suga dev`. See the [Local Development](/foundations/local-development) guide. + +### Can services communicate with each other? + +Currently, services communicate through shared databases or buckets. Direct service-to-service communication is coming soon. + +### What if I need a resource type that doesn't exist? + +You can: +1. Add custom Terraform resources to your stack +2. Create a custom plugin for the resource +3. Request the feature for official platforms +4. Extend Suga through [open source contributions](https://github.com/nitrictech/suga) + +## Platform & Plugin Development + +### Who should create platforms? + +Platform teams, DevOps/SRE teams, or anyone wanting to standardize infrastructure across an organization. + +### Can I customize official platforms? + +You can't modify official platforms directly, but you can: +1. Fork and customize them as your own private or public platforms +2. Override configurations through Terraform variables +3. Add custom resources alongside generated ones + +### How do I share platforms with my team? + +Publish platforms to your organization's Suga account. Team members can then target your custom platforms. + +### Do plugins require special permissions? + +Plugins are Terraform modules and run with your cloud provider credentials during `terraform apply`. They have the same permissions as any Terraform code. + +## Pricing & Licensing + +### Is Suga free? + +Suga is currently in early access. Pricing for future releases and enterprise features will be announced. + +You only pay your cloud provider for infrastructure resources. + +### Do I need a Suga account? + +Yes, currently a Suga account is required. Sign up at [addsuga.com](https://addsuga.com). + +In the future, some features may work without an account. + +### Can I use Suga for commercial projects? + +Yes, Suga is designed for production use in commercial applications. + +## Support + +### How do I get help? + +- **Documentation** - [docs.addsuga.com](https://docs.addsuga.com) +- **Email Support** - [support@addsuga.com](mailto:support@addsuga.com) +- **GitHub Issues** - [github.com/nitrictech/suga](https://github.com/nitrictech/suga) + +### How do I report bugs? + +Report bugs via: +- GitHub Issues for public bugs +- Email [support@addsuga.com](mailto:support@addsuga.com) for security issues + +### Can I request features? + +Yes! Submit feature requests through GitHub Issues or email. + +### Do you offer paid support? + +Enterprise support options are available. Contact [sales@addsuga.com](mailto:sales@addsuga.com). + +## Security + +### How secure is Suga? + +- Suga generates standard Terraform with least-privilege IAM policies +- Your code and infrastructure remain in your cloud account +- Suga CLI only communicates with Suga platform services for authentication and platform/plugin retrieval +- No application code is sent to Suga servers + +### Where is my data stored? + +- Application data: In your cloud provider account +- Terraform state: Where you configure it (local, S3, GCS, Terraform Cloud) +- Suga platform: Stores only account info and platform/plugin definitions + +### Does Suga have access to my cloud resources? + +No. Suga generates Terraform that you deploy with your own cloud credentials. Suga has no access to your deployed resources. + +### How do I handle secrets? + +Currently, use your cloud provider's secrets manager and reference via environment variables. + +## Still Have Questions? + + + Reach out to our team at support@addsuga.com + diff --git a/docs/foundations/deployment.mdx b/docs/foundations/deployment.mdx new file mode 100644 index 00000000..663439b5 --- /dev/null +++ b/docs/foundations/deployment.mdx @@ -0,0 +1,412 @@ +--- +title: "Deployment" +description: "Understand how Suga applications are deployed to the cloud" +--- + +Deploying with Suga means running standard Terraform commands on the infrastructure generated by `suga build`. This page explains the deployment lifecycle, how to deploy to different environments, and best practices for production deployments. + +## Deployment Overview + +Suga's deployment model is transparent and uses standard tools: + +1. **Generate Terraform** - `suga build` creates Terraform modules +2. **Configure Provider** - Set up cloud provider credentials and configuration +3. **Initialize Terraform** - Download providers and modules +4. **Preview Changes** - Review what will be created/modified +5. **Apply Changes** - Deploy to your cloud provider +6. **Verify Deployment** - Test deployed resources + +## The Deployment Lifecycle + + + + Generate Terraform from your project: + + ```bash + suga build + ``` + + Output: + ``` + ✓ Terraform generated successfully + output written to terraform/stacks/my-app + + Next steps: + 1. Run cd terraform/stacks/my-app to move to the stack directory + 2. Initialize the stack terraform init -upgrade + 3. Optionally, preview with terraform plan + 4. Deploy with terraform apply + ``` + + + + Change to the generated Terraform directory: + + ```bash + cd terraform/stacks/my-app + ``` + + Contents: + ``` + my-app/ + ├── cdk.tf.json # Main Terraform Entrypoint + └── .terraform/ # Plugin Terraform modules + └── modules/ + ├── api/ + ├── api_image/ + ├── uploads_bucket/ + └── ... + ``` + + + + Set up provider configuration and credentials: + + + + ```bash + # Configure credentials + aws configure + ``` + + Create provider configuration: + + ```hcl title="provider.tf" + provider "aws" { + region = "us-west-2" + } + ``` + + + + ```bash + # Configure credentials + gcloud auth application-default login + ``` + + Set required variables: + + ```hcl title="terraform.tfvars" + project_id = "my-gcp-project" + region = "us-central1" + ``` + + + + + Files like `provider.tf` and `terraform.tfvars` are preserved across builds and won't be overwritten. + + + + + Download providers and modules: + + ```bash + terraform init -upgrade + ``` + + This downloads: + - Cloud provider Terraform providers (AWS, GCP, etc.) + - Plugin modules referenced by your platform + - Backend configuration (if configured) + + + + Review what Terraform will create: + + ```bash + terraform plan + ``` + + Output shows: + - Resources to be created (`+`) + - Resources to be modified (`~`) + - Resources to be deleted (`-`) + + + Always review the plan carefully before applying, especially in production environments. + + + + + Apply the Terraform configuration: + + ```bash + terraform apply + ``` + + Terraform will: + 1. Show the plan again + 2. Ask for confirmation + 3. Create resources in your cloud account + 4. Save state to track resources + + ```bash + Apply complete! Resources: 15 added, 0 changed, 0 destroyed. + + Outputs: + entrypoint_web_url = "https://d123abc.cloudfront.net" + service_api_function_name = "my-app-api" + ``` + + + + Test your deployed application: + + ```bash + # Get the entrypoint URL from outputs + terraform output entrypoint_web_url + + # Test the endpoint + curl https://d123abc.cloudfront.net/api/health + ``` + + + +## Managing Deployments + +### Updating Your Application + +When you make changes to your project: + +1. **Rebuild Terraform:** + ```bash + suga build + ``` + +2. **Preview changes:** + ```bash + cd terraform/stacks/my-app + terraform plan + ``` + +3. **Apply updates:** + ```bash + terraform apply + ``` + +Terraform intelligently updates only what changed: +- Modified services are redeployed +- New resources are created +- Removed resources are deleted +- Unchanged resources remain untouched + +### Deploying Code Updates + +When you update service code without changing infrastructure: + +```bash +# Simply re-run terraform apply +cd terraform/stacks/my-app +terraform apply +``` + +Terraform automatically: +1. Builds new container images from your updated code +2. Pushes images to the container registry (ECR, Artifact Registry, etc.) +3. Updates services to use the new images +4. Handles rolling deployments with zero downtime + +No manual Docker commands needed - the generated Terraform includes container build and push logic. + + + CI/CD pipelines typically automate this by running `terraform apply` on every commit. See the [CI/CD Authentication Guide](/guides/cicd-authentication) for details. + + +### Rolling Back + +If a deployment causes issues, roll back: + +```bash +# Revert code changes +git revert + +# Rebuild Terraform +suga build + +# Apply previous configuration +cd terraform/stacks/my-app +terraform apply +``` + +Or roll back to a previous Terraform state: + +```bash +# List state backups +terraform state list + +# If using versioned state backend, restore previous version +# (AWS S3, GCS, Terraform Cloud all support versioning) +``` + +### Destroying Resources + +When you're done with a deployment: + +```bash +cd terraform/stacks/my-app +terraform destroy +``` + + + `terraform destroy` permanently deletes all cloud resources. Databases, buckets, and all data will be lost. Use with extreme caution, especially in production. + + +## Multi-Environment Deployments + +Deploy the same application to multiple environments (dev, staging, production) using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration per environment. + + + Learn detailed strategies for managing multiple environments with Terraform workspaces and promotion workflows + + +## Cloud Provider Setup + +Each cloud provider requires specific credentials and permissions. Detailed setup instructions including required permissions, authentication methods, and provider configuration are available in the provider-specific guides: + + + + AWS credentials, IAM permissions, and configuration + + + + GCP service accounts, permissions, and configuration + + + + Azure credentials, RBAC, and configuration + + + +## Terraform State Management + +Terraform state tracks deployed resources and must be managed carefully. By default, state is stored locally, which is suitable for personal projects but not recommended for teams. For production deployments, use a remote backend for state locking, versioning, and team collaboration. + + + Complete guide to configuring remote state backends (S3, GCS, Terraform Cloud) + + +## CI/CD Integration + +Automate deployments with CI/CD pipelines to build infrastructure and deploy on every commit. Common patterns include GitHub Actions, GitLab CI, CircleCI, and Jenkins. + + + Learn how to authenticate Suga in CI/CD pipelines with example workflows + + +## Best Practices + +### 1. Always Preview Before Applying + +```bash +terraform plan # Review changes +terraform apply # Only after reviewing +``` + +### 2. Use Remote State for Teams + +Configure a remote backend for team deployments. See the [Terraform Backend Configuration](/guides/terraform-backend-config) guide. + +### 3. Separate Environments + +Use Terraform workspaces or separate state files. See the [Environment Management](/deploy/environment-management) guide. + +### 4. Version Control Everything + +Commit generated Terraform to git: + +```bash +git add terraform/ +git commit -m "Update infrastructure" +``` + +### 5. Test in Non-Production First + +Always deploy to dev/staging before production: + +```bash +# Deploy to dev +terraform workspace select dev +terraform apply + +# Test thoroughly +# Then deploy to prod +terraform workspace select prod +terraform apply +``` + +### 6. Use Terraform Variables for Configuration + +Use variable files for environment-specific configuration. See the [Terraform Configuration](/deploy/terraform-configuration) guide. + +### 7. Monitor Deployments + +Set up monitoring for deployed resources: +- CloudWatch (AWS) +- Cloud Monitoring (GCP) +- Application Performance Monitoring (APM) tools + +### 8. Document Your Deployments + +Maintain deployment documentation: + +```markdown title="DEPLOYMENT.md" +## Production Deployment + +1. Ensure tests pass: `npm test` +2. Build infrastructure: `suga build` +3. Review changes: `terraform plan` +4. Deploy: `terraform apply` +5. Verify: `curl https://api.example.com/health` +6. Monitor: Check CloudWatch dashboard +``` + +## Troubleshooting + +### Common Deployment Issues + +**"No valid credential sources found"** + +Solution: Configure cloud provider credentials properly. + +**"Resource already exists"** + +Solution: Import existing resource into Terraform state: +```bash +terraform import . +``` + +**"State lock timeout"** + +Solution: Another apply is running, or a previous one crashed. Release lock: +```bash +terraform force-unlock +``` + +**"Plan shows unwanted changes"** + +Solution: Check for drift between state and actual resources: +```bash +terraform refresh +terraform plan +``` + +## Learn More + + + + Understand how Terraform is generated + + + + Manage multiple deployment environments + + + + Best practices for Terraform configuration + + + + How to develop applications locally with Suga + + diff --git a/docs/foundations/infrastructure-generation.mdx b/docs/foundations/infrastructure-generation.mdx new file mode 100644 index 00000000..cb5848e8 --- /dev/null +++ b/docs/foundations/infrastructure-generation.mdx @@ -0,0 +1,198 @@ +--- +title: "Infrastructure Generation" +description: "How Suga transforms projects into production-ready Terraform" +--- + +When you run `suga build`, Suga transforms your high-level project specification into production-ready Terraform code. This page explains how this transformation works, what gets generated, and how to customize the output. + +## The Build Process + +The `suga build` command orchestrates a multi-step process: + + + + Suga reads your `suga.yaml` file and validates the configuration: + + ```yaml title="suga.yaml" + target: suga/aws@1 + name: my-app + + services: + api: + dev: + script: npm run dev + + buckets: + uploads: + access: + api: [read, write] + ``` + + + + Suga retrieves the target platform specification from the registry: + + ```bash + # Platform: suga/aws@1 + - Services: lambda, fargate + - Buckets: s3 + - Databases: neon + - Entrypoints: cloudfront + - Infrastructure: vpc, loadbalancer, security-groups + ``` + + + + Each project resource is mapped to a platform blueprint, by the selected subtype: + + ```yaml suga.yaml + services: + api: + subtype: fargate + + buckets: + uploads: + subtype: s3 + ``` + + ``` + Project Platform Blueprint Plugin + ------- ------------------ ------ + service "api" → services.fargate → suga/aws/fargate + bucket "uploads" → buckets.s3 → suga/aws/s3-bucket + ``` + + + + + Suga then uses Terraform CDK to resolve the modules, variables and other configuration and produce a functional Terraform stack. + + ``` + terraform/stacks/my-app/ + ├── cdk.tf.json # Main Terraform Entrypoint + └── .terraform/ # Plugin Terraform modules + └── modules/ + ├── api/ + ├── api_image/ + ├── uploads_bucket/ + └── ... + ``` + + + +## Module Naming + +Suga generates consistent module names for application resources: + +### Terraform Module Names + +Pattern: `{resource_name}[_{submodule_name}]` + +```hcl +module "api" # Service named "api" +module "api_image" # Container image submodule for the "api" service +module "uploads" # Bucket named "uploads" +``` + +## Dependency Management + +Suga automatically manages resource dependencies: + +### Explicit Dependencies + +Defined by platform: + +```yaml title="Platform blueprint" +services: + fargate: + depends_on: + - ${infra.aws_vpc} + - ${infra.aws_lb} +``` + +Results in: + +```hcl title="Generated Terraform" +module "service_api" { + # ... + depends_on = [ + module.aws_vpc, + module.aws_lb + ] +} +``` + +### Implicit Dependencies + +Created by resource references: + +```hcl title="Automatic dependency" +module "service_api" { + vpc_id = module.aws_vpc.vpc_id # Creates implicit dependency +} +``` + +## Multi-Environment Support + +The same generated Terraform can deploy to multiple environments using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration for dev, staging, and production. + + + Learn best practices for managing multiple environments with Terraform workspaces and variables + + +See the [CLI reference](/cli/build) for complete options. + +## Getting Help + +If you encounter issues during build: + +1. Review platform documentation in the [platform browser](https://app.addsuga.com/browse/platforms) +2. Contact [Suga support](/support) + +## Best Practices + +### 1. Version Control Generated Terraform + +Commit generated Terraform to version control: + +```bash +git add terraform/ +git commit -m "Update infrastructure" +``` + +Benefits: +- Track infrastructure changes over time +- Review Terraform diffs in pull requests +- Rollback if needed + +### 2. Validate Before Deploying + +Always validate and preview: + +```bash +suga build +cd terraform/stacks/my-app +terraform init +terraform validate +terraform plan # Review before apply +``` + +## Learn More + + + + Understand the deployment process + + + + Complete CLI reference for suga build + + + + Learn how platforms define infrastructure + + + + Best practices for Terraform configuration + + diff --git a/docs/foundations/local-development.mdx b/docs/foundations/local-development.mdx new file mode 100644 index 00000000..318ce1c3 --- /dev/null +++ b/docs/foundations/local-development.mdx @@ -0,0 +1,349 @@ +--- +title: "Local Development" +description: "Develop and test cloud applications entirely on your local machine" +--- + +Suga's local development environment (`suga dev`) lets you build and test cloud applications entirely on your local machine without cloud access, accounts, or costs. This page explains how local development works, what's emulated, and best practices for productive local workflows. + +## The Development Server + +The `suga dev` command starts a local development server that: + +- **Emulates cloud resources** - Buckets, entrypoints, databases +- **Runs your services** - Using the `dev.script` from your `suga.yaml` +- **Hot reloads code** - Automatically restarts services when files change +- **Provides local URLs** - Access your application at `localhost` ports + +```bash title="Start local development" +suga dev +``` + +```bash title="Example output" +⚡ Suga v0.0.1 + - App: my-app + - Addr: :50051 + +Services + +✓ Starting [api] + +Entrypoints + +✓ Starting [web] http://localhost:3000 + +Use Ctrl-C to exit +``` + +## What Gets Emulated + +### Services + +Your application services run locally using their `dev.script`: + +```yaml title="suga.yaml" +services: + api: + dev: + script: npm run dev + worker: + dev: + script: python main.py +``` + +Each service: +- Runs as a separate process +- Gets automatically restarted on code changes +- Receives environment variables from `suga.yaml` +- Can communicate with emulated resources + +### Buckets (Object Storage) + +Buckets are emulated using the local filesystem: + +``` +project-root/ +└── .suga/ + └── buckets/ + └── uploads/ # Bucket named "uploads" + ├── file1.txt + └── file2.jpg +``` + +**Features:** +- Read/write/delete operations work like cloud storage +- Files persist between `suga dev` sessions +- Pre-seed buckets by placing files in `.suga/buckets/{bucket-name}/` +- View files directly in the file explorer + +**SDK Operations:** + +Use the generated Suga client to interact with buckets: + +```typescript title="Works locally and in production" +// Write file +await suga.uploads.write('file.txt', Buffer.from('Hello!')); + +// Read file +const data = await suga.uploads.read('file.txt'); + +// Delete file +await suga.uploads.delete('file.txt'); +``` + +Local behavior: +- `write()` creates files in `.suga/buckets/uploads/` +- `read()` reads from `.suga/buckets/uploads/` +- `delete()` removes files from `.suga/buckets/uploads/` + + + Learn about generated client libraries for cloud-agnostic resource access + + +### Entrypoints (HTTP Routing) + +Entrypoints provide local HTTP servers with routing: + +```yaml title="suga.yaml" +entrypoints: + web: + routes: + /api/: api + /: frontend +``` + +Results in: + +``` +http://localhost:3000/api/ → Routes to 'api' service +http://localhost:3000/ → Routes to 'frontend' service +``` + +**Features:** +- Path-based routing like production CDN +- Request/response logging +- CORS handling + +### Databases + +PostgreSQL databases are automatically run locally: + +```yaml title="suga.yaml" +databases: + main: + access: + api: [query] + env_var_key: DATABASE_URL +``` + +**Features:** +- Automatic PostgreSQL instance created per database +- Connection strings injected into services via environment variables +- Data persists between `suga dev` sessions +- Full PostgreSQL compatibility for development + +**How it works:** + +During `suga dev`, Suga: +1. Starts a local PostgreSQL instance for each database using Docker +2. Injects connection strings into services with access +3. Makes databases available on local ports + +Services receive the connection string exactly as they would in production: + +```typescript title="Works locally and in production" +import { Pool } from 'pg'; + +const pool = new Pool({ + connectionString: process.env.DATABASE_URL +}); + +await pool.query('CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT)'); +await pool.query('INSERT INTO users (name) VALUES ($1)', ['Alice']); +const result = await pool.query('SELECT * FROM users'); +console.log(result.rows); +``` + +## The `.suga` Directory + +Suga creates a `.suga` directory in your project for local state: + +``` +.suga/ +├── buckets/ # Bucket contents +│ └── uploads/ +├── logs/ # Service logs +│ ├── api.log +│ └── worker.log +└── dev.json # Development server state +``` + + + Add `.suga/` to your `.gitignore` - this directory contains local development state and should not be committed. + + +## Development Workflow + +### Starting Development + +```bash +# Start all services and resources +suga dev +``` + +### Making Code Changes + +1. **Edit your service code** - Changes are detected automatically +2. **Service restarts** - Suga restarts the affected service +3. **Test immediately** - New code is running + +### Debugging Services + +Standard debugging tools work normally: + + + + ```json title="package.json" + { + "scripts": { + "dev": "node --inspect src/index.js" + } + } + ``` + + Then connect Chrome DevTools or VS Code debugger to `localhost:9229`. + + + + ```yaml title="suga.yaml" + services: + api: + dev: + script: python -m debugpy --listen 5678 main.py + ``` + + Then connect VS Code or PyCharm debugger to `localhost:5678`. + + + + ```bash title="Use delve debugger" + dlv debug --headless --listen=:2345 --api-version=2 + ``` + + Then connect GoLand or VS Code debugger to `localhost:2345`. + + + +### Viewing Logs + +Service logs are written to `.suga/logs/`: + +```bash +# Tail service logs +tail -f .suga/logs/api.log + +# Or use your preferred log viewer +cat .suga/logs/api.log | grep ERROR +``` + +### Seeding Local Data + +Pre-populate buckets for testing: + +```bash +# Create test files +mkdir -p .suga/buckets/uploads +echo "Test content" > .suga/buckets/uploads/test.txt + +# Start dev server - files are available immediately +suga dev +``` + +```typescript title="Read pre-seeded data" +const data = await suga.uploads.read('test.txt'); +console.log(data); // "Test content" +``` + +## Environment Variables + +Services receive environment variables defined in `suga.yaml`: + +```yaml title="suga.yaml" +services: + api: + env: + EXTERNAL_API_KEY: dev-key-12345 + DEBUG: "true" + dev: + script: npm run dev + +databases: + main: + access: + api: [query] + env_var_key: DATABASE_URL # Automatically injected during dev and production +``` + +During `suga dev`: +- Service receives environment variables from `env` config +- Database connection strings automatically injected based on `env_var_key` +- Same variables are available in production (after Terraform deployment) +- Use for configuration, API keys, feature flags + + + Use different values for local vs production by adding platform-specific overrides or using Terraform variables. + + +## Service Communication + + + Direct service-to-service communication is coming soon. For now, services can communicate through shared databases, buckets or entrypoint URLs. + + +## Limitations + +Local emulation provides high fidelity but has some limitations: + +### Not Emulated + +- **Cloud-specific features** - Lambda layers, CloudFront behaviors, CDN caching +- **Scaling** - Auto-scaling, load balancing across multiple instances +- **Managed services** - Cloud-specific features like S3 lifecycle policies +- **Networking** - VPCs, security groups, actual cloud networking + +### Performance Differences + +- **Cold starts** - Lambda cold starts don't occur locally +- **Latency** - No network latency between services +- **Resource limits** - Local resources not limited like Lambda (memory, timeout) + +### Workarounds + +For features that can't be emulated: + +1. **Preview in cloud** - Deploy to dev environment for testing +2. **Mock externals** - Use mocks for cloud-specific APIs +3. **Integration tests** - Test cloud features in CI/CD pipelines + + + Learn how to deploy to cloud environments for testing + + +## Learn More + + + + Get started with local development + + + + Complete CLI reference for suga dev + + + + Configure databases and connection strings + + + + Deploy to cloud after local testing + + diff --git a/docs/foundations/overview.mdx b/docs/foundations/overview.mdx new file mode 100644 index 00000000..76b3a50b --- /dev/null +++ b/docs/foundations/overview.mdx @@ -0,0 +1,298 @@ +--- +title: "Foundations Overview" +description: "Understanding Suga's architecture and core concepts" +--- + +Suga is built on a clear separation of concerns that enables both developer productivity and platform governance. Understanding these foundations will help you make the most of the platform. + +## The Suga Architecture + +Suga operates through three key layers that work together to transform your application designs into deployed infrastructure: + +```mermaid +graph TB + A[Projects
What you want] --> D[Platforms
How to build it] + D --> B[Plugins
Cloud resources] + B --> C[Terraform
Deployed infrastructure] + + style A fill:#2BC65F + style D fill:#25B355 + style B fill:#1E9A47 + style C fill:#178A3D +``` + +### 1. Projects: What You Want + +[Projects](/foundations/projects) are your application specifications - declarative YAML files that describe what your application needs: + +- **Services** - Application containers that run your code +- **Buckets** - Cloud storage for files and assets +- **Databases** - PostgreSQL databases for structured data +- **Entrypoints** - HTTP routing and CDN configuration + +Projects are **deployment-agnostic** - they describe requirements without specifying how they're implemented. + +```yaml title="Example: A simple web application" +target: suga/aws@1 +name: my-app + +services: + api: + dev: + script: npm run dev + +buckets: + uploads: + access: + api: [read, write] + +entrypoints: + web: + routes: + /api/: api +``` + +### 2. Platforms: How to Build It + +[Platforms](/foundations/platforms) are blueprints that map your project's abstract resources to specific cloud implementations. They define: + +- Which cloud services to use (Lambda vs Fargate, S3 vs Cloud Storage) +- How to configure those services (memory, CPU, networking) +- Security policies and access controls +- Infrastructure dependencies (VPCs, load balancers) + +Platform teams create and publish platforms to enforce organizational standards while delivering seamless developer experiences. + +### 3. Plugins: Cloud Resources + +[Plugins](/foundations/plugins) are the lowest-level building blocks - reusable Terraform modules that provision specific cloud resources. Each plugin contains: + +- **Terraform module** - Infrastructure-as-code for a specific cloud service +- **Input schema** - Configuration properties the module accepts +- **Runtime adapter** (optional) - Go code that translates SDK calls to cloud APIs + +Platforms compose multiple plugins to create complete deployment targets. + +## The Suga Workflow + +Understanding how these pieces work together: + + + + Create your project using the visual editor or by editing `suga.yaml` directly. + + ```bash + suga edit # Visual editor + # or edit suga.yaml manually + ``` + + + + Test your application with emulated cloud services running locally. + + ```bash + suga dev + ``` + + Local development provides: + - Hot reloading for code changes + - Emulated buckets, entrypoints, and databases + - Fast iteration without cloud costs + + + + Build Terraform infrastructure from your project and target platform. + + ```bash + suga build + ``` + + This process: + 1. Loads your project specification (`suga.yaml`) + 2. Fetches the target platform definition + 3. Maps each resource to appropriate plugins + 4. Generates Terraform modules with proper configuration + 5. Creates IAM policies for service access + 6. Outputs a complete Terraform stack + + + + Deploy the generated Terraform to your cloud provider. + + ```bash + cd terraform/stacks/my-app + terraform init + terraform apply + ``` + + Standard Terraform workflow - you have full control over deployment timing, preview changes with `terraform plan`, and manage state as you normally would. + + + +## Key Concepts + +### Declarative Infrastructure + +Suga uses a declarative approach - you specify **what** you want, not **how** to create it. + +```yaml title="Declarative: What you want" +buckets: + uploads: + access: + api: [read, write] +``` + +Suga handles the **how**: +- Creates S3 bucket (AWS) or Cloud Storage bucket (GCP) +- Configures IAM policies for service access +- Sets up lifecycle rules and encryption +- Generates connection configuration + +### Separation of Concerns + +Suga maintains clear boundaries between different responsibilities: + +| Layer | Responsibility | Owned By | +|-------|---------------|----------| +| **Project** | Application requirements | Developers | +| **Platform** | Implementation strategy | Platform teams | +| **Plugin** | Cloud resource provisioning | Plugin authors | +| **Terraform** | Infrastructure deployment | DevOps/SRE | + +This separation enables: +- Developers to focus on application needs +- Platform teams to enforce standards +- Infrastructure to evolve independently +- Teams to work in parallel + +### Infrastructure as Configuration + +Unlike infrastructure as **code** (where you write Terraform/Pulumi), Suga treats infrastructure as **configuration**: + +- **Configuration** - High-level, declarative, human-readable +- **Code** - Generated automatically, optimized, consistent + +You edit configuration, Suga generates code. + +### Platform-Driven Governance + +Platforms act as governance boundaries: + +```yaml title="Developer specifies requirements" +services: + api: + # I need a service +``` + +```yaml title="Platform enforces standards" +services: + lambda: + properties: + memory: 512 # Organization-mandated memory + timeout: 10 # Organization-mandated timeout + identities: + - plugin: iam-role # Auto-generated IAM with least privilege +``` + +Platform teams control: +- Which cloud services are available +- How they're configured by default +- What developers can customize +- Security and compliance policies + +### Runtime Abstraction (Optional) + +If you use Suga's generated SDKs, the same code works everywhere: + +```typescript title="Cloud-agnostic code" +import { SugaClient } from './suga/client'; + +const suga = new SugaClient(); + +// Works locally with suga dev +// Works on AWS Lambda with S3 +// Works on GCP Cloud Run with Cloud Storage +await suga.uploads.write('file.txt', data); +``` + +Plugins provide runtime adapters that translate abstract operations to cloud-specific APIs. + +## Design Principles + +Suga is built on several core principles: + +### 1. Visual-First Design + +Infrastructure should be visual and intuitive. The visual editor provides: +- Drag-and-drop resource creation +- Visual connections show relationships +- Real-time validation +- AI-assisted architecture design +- Automatic YAML generation + +### 2. Local Development First + +Developers should be able to work entirely locally without cloud access: +- Emulated cloud services +- Fast iteration cycles +- No cloud costs during development +- Consistent behavior between local and production + +### 3. Standard Artifacts + +Suga generates standard, transparent artifacts: +- **Terraform HCL** - Not proprietary formats +- **Standard providers** - AWS, GCP, Azure Terraform providers +- **No magic** - Generated Terraform is readable and customizable + +### 4. Progressive Enhancement + +Start simple, add complexity as needed: +- Begin with default platform configurations +- Customize as requirements grow +- Create custom platforms for specialized needs +- Build custom plugins for unique resources + +### 5. Team Scalability + +Enable teams to work independently while maintaining consistency: +- Platform teams publish reusable blueprints +- Development teams consume platforms +- Plugin authors create building blocks +- Clear interfaces between layers + +## Next Steps + +Now that you understand Suga's foundations, dive deeper into each component: + + + + Learn how to define application requirements + + + + Understand platform blueprints and governance + + + + Explore the building blocks of infrastructure + + + + See how Suga transforms projects into Terraform + + + + Master local development workflow + + + + Understand deployment and operations + + + +Or jump straight to building: + + + Follow the quickstart guide to deploy an application end-to-end + diff --git a/docs/platforms.mdx b/docs/foundations/platforms.mdx similarity index 96% rename from docs/platforms.mdx rename to docs/foundations/platforms.mdx index 724af304..14111685 100644 --- a/docs/platforms.mdx +++ b/docs/foundations/platforms.mdx @@ -1,9 +1,9 @@ --- -title: "Platforms Overview" +title: "Platforms" description: "Understanding Suga's platforms and ecosystem" --- -Platforms in Suga solve a critical challenge: delivering the seamless developer experience of modern deployment platforms while maintaining enterprise control and flexibility. They're blueprints that transform application specifications ([Projects](/projects)) into deployable infrastructure by generating Terraform HCL and providing runtime adapters that translate abstract resource operations into cloud-specific API calls. +Platforms in Suga solve a critical challenge: delivering the seamless developer experience of modern deployment platforms while maintaining enterprise control and flexibility. They're blueprints that transform application specifications ([Projects](/foundations/projects)) into deployable infrastructure by generating Terraform HCL and providing runtime adapters that translate abstract resource operations into cloud-specific API calls. Platform teams can create, customize, and govern these distributed packages to provide developers with instant deployments, automatic scaling, and zero-configuration infrastructure, while maintaining full control over security, compliance, and infrastructure standards. @@ -68,7 +68,7 @@ Platforms operate through two key mechanisms: **Infrastructure Generation** and ### Infrastructure Generation -When you run `suga build`, Suga uses your target platform to transform your [Project](/projects) specification into cloud-specific Terraform HCL (called stacks). This process: +When you run `suga build`, Suga uses your target platform to transform your [Project](/foundations/projects) specification into cloud-specific Terraform HCL (called stacks). This process: 1. **Maps abstract resources** - Takes your high-level resource definitions (services, buckets, databases) and selects appropriate cloud implementations 2. **Generates Terraform modules** - Creates infrastructure-as-code that provisions actual cloud resources with proper networking, security, and permissions diff --git a/docs/foundations/plugins.mdx b/docs/foundations/plugins.mdx new file mode 100644 index 00000000..49abc452 --- /dev/null +++ b/docs/foundations/plugins.mdx @@ -0,0 +1,279 @@ +--- +title: "Plugins" +description: "Understanding Suga's plugin system - the building blocks of cloud infrastructure" +--- + +Plugins are the fundamental building blocks of Suga platforms. Each plugin is a self-contained, reusable unit that knows how to provision and manage a specific type of cloud resource. Platforms compose multiple plugins to create complete deployment targets. + +## What is a Plugin? + +A plugin is a package containing: + +1. **Terraform Module** - Infrastructure-as-code that provisions cloud resources +2. **Manifest** - Schema defining configuration properties and outputs +3. **Runtime Adapter** (optional) - Go code that translates abstract SDK operations into cloud-specific API calls + +``` +plugin-directory/ +├── manifest.yaml # Plugin schema and metadata +├── main.tf # Terraform resources +├── variables.tf # Input variables +├── outputs.tf # Output values +└── runtime/ # Optional runtime adapters + ├── client.go # SDK client implementation + └── operations.go # Cloud-specific operations +``` + +## Plugin Types + +Suga uses plugins for different types of infrastructure: + +### Resource Plugins + +Map to application resources defined in projects: + +- **Service plugins** - Compute resources (Lambda, Fargate, Cloud Run) +- **Bucket plugins** - Object storage (S3, Cloud Storage) +- **Database plugins** - SQL databases (RDS, Cloud SQL, Neon) +- **Entrypoint plugins** - CDN and routing (CloudFront, Cloud CDN) + +### Identity Plugins + +Provide authentication and authorization: + +- **IAM role plugins** - AWS IAM roles +- **Service account plugins** - GCP service accounts +- Auto-generated based on resource access patterns + +### Infrastructure Plugins + +Provide foundational cloud resources: + +- **VPC plugins** - Network configuration +- **Load balancer plugins** - Traffic distribution +- **Security group plugins** - Firewall rules + +## How Platforms Use Plugins + +Platforms reference plugins in their resource blueprints: + +```yaml title="Platform blueprint using plugins" +services: + lambda: + source: + library: suga/aws + plugin: lambda + properties: + memory: ${self.memory} + timeout: ${self.timeout} + variables: + memory: + type: number + default: 512 + timeout: + type: number + default: 10 + identities: + - source: + library: suga/aws + plugin: iam-role +``` + +When you run `suga build`, the platform: + +1. Maps your project resources to plugin blueprints +2. Resolves property values and variables +3. Generates Terraform module calls +4. Configures dependencies and outputs + +## Official Plugin Libraries + +Suga maintains official plugin libraries for major cloud providers: + +### AWS Plugin Library (`suga/aws`) + +| Plugin | Purpose | Provisions | +|--------|---------|-----------| +| `lambda` | Serverless compute | AWS Lambda function + ECR repository | +| `fargate` | Container compute | ECS Fargate service + ECR + ALB target | +| `s3-bucket` | Object storage | S3 bucket with encryption and policies | +| `cloudfront` | CDN and routing | CloudFront distribution + WAF (optional) | +| `iam-role` | Service identity | IAM role with policies | +| `vpc` | Network foundation | VPC with subnets and NAT gateway | +| `loadbalancer` | Traffic distribution | Application Load Balancer | +| `security-group-rule` | Network security | Security group rules | + +### GCP Plugin Library (`suga/gcp`) + +| Plugin | Purpose | Provisions | +|--------|---------|-----------| +| `cloudrun` | Serverless containers | Cloud Run service + Artifact Registry | +| `storage-bucket` | Object storage | Cloud Storage bucket with policies | +| `cdn` | CDN and routing | Cloud Load Balancer + Cloud CDN | +| `service-account` | Service identity | Service account with IAM bindings | + +### Neon Plugin Library (`suga/neon`) + +| Plugin | Purpose | Provisions | +|--------|---------|-----------| +| `database` | PostgreSQL database | Neon database with branch support | + +## Plugin Configuration + +Plugins accept configuration through properties defined in their manifests: + +### Input Properties + +Configure how resources are provisioned: + +```yaml title="Lambda plugin properties" +properties: + memory: 512 # Memory allocation in MB + timeout: 10 # Execution timeout in seconds + ephemeral_storage: 512 # /tmp directory size in MB +``` + +These map directly to Terraform module variables. + +### Property Types + +Plugins support various property types: + +- **Primitives** - `string`, `number`, `bool` +- **Collections** - `list(string)`, `map(string)` +- **Objects** - Complex nested structures +- **References** - `${var.name}`, `${self.property}`, `${infra.component.output}` + +### Variable References + +Properties can reference platform or blueprint variables: + +```yaml title="Using variable references" +properties: + memory: ${self.memory} # Blueprint variable + project_id: ${var.project_id} # Platform variable + vpc_id: ${infra.aws_vpc.vpc_id} # Infrastructure output +``` + +## Plugin Outputs + +Plugins expose outputs that other resources can reference: + +```hcl title="Lambda plugin outputs" +output "function_arn" { + description = "ARN of the Lambda function" + value = aws_lambda_function.main.arn +} + +output "function_name" { + description = "Name of the Lambda function" + value = aws_lambda_function.main.function_name +} +``` + +These outputs are available to: +- Identity plugins (for IAM policy generation) +- Other infrastructure components +- Platform routing configuration + +## Runtime Adapters + +For plugins that provide SDK functionality (services, buckets), runtime adapters translate abstract operations into cloud-specific API calls. + +### Adapter Structure + +```go title="Example runtime adapter" +package runtime + +// Client provides cloud-specific implementations +type Client struct { + s3Client *s3.Client +} + +// Write implements the bucket write operation +func (c *Client) Write(ctx context.Context, key string, data []byte) error { + _, err := c.s3Client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(c.bucketName), + Key: aws.String(key), + Body: bytes.NewReader(data), + }) + return err +} +``` + +### How Adapters Work + +When you use Suga's generated SDK: + +```typescript title="Application code" +await suga.uploads.write('file.txt', data); +``` + +The runtime: +1. Identifies the plugin used for the `uploads` bucket +2. Loads the plugin's runtime adapter +3. Calls the adapter's `Write` method with cloud credentials +4. Adapter translates to cloud-specific API call (S3, Cloud Storage, etc.) + +## Plugin Versioning + +Plugins are versioned and distributed through plugin libraries: + +```yaml title="Platform specifies plugin versions" +libraries: + suga/aws: v0.0.4 + suga/neon: v0.0.2 +``` + +When you build your application: +- Suga fetches the specified plugin versions +- Generates Terraform using those plugin modules +- Ensures consistent deployments across environments + +## Plugin Discovery + +Browse available plugins: + + + Explore official and community plugins in the platform browser + + +## Creating Custom Plugins + +Organizations can create custom plugins for: + +- **Proprietary services** - Internal APIs and systems +- **Specialized configurations** - Custom cloud resource setups +- **Third-party integrations** - SaaS services and external APIs + + + Learn how to create custom plugins for your organization + + +### Plugin Development Workflow + +1. **Create Terraform module** - Define cloud resources +2. **Write manifest** - Specify schema and metadata +3. **Add runtime adapter** (optional) - Implement SDK operations +4. **Test locally** - Use with local projects +5. **Publish** - Share within your organization + +## Learn More + + + + Learn how platforms compose plugins + + + + Create custom plugins for your needs + + + + See how plugins generate Terraform + + + + Explore available plugins + + diff --git a/docs/projects.mdx b/docs/foundations/projects.mdx similarity index 97% rename from docs/projects.mdx rename to docs/foundations/projects.mdx index 4f1d5e5a..8b09af98 100644 --- a/docs/projects.mdx +++ b/docs/foundations/projects.mdx @@ -1,5 +1,5 @@ --- -title: "Projects Overview" +title: "Projects" description: "Understanding Suga projects - the application specifications that define your cloud architecture" --- @@ -7,7 +7,7 @@ Projects in Suga are application specifications that define your cloud architect ## What is a Project? -A Suga project is defined by a `suga.yaml` file that describes your application's infrastructure requirements using cloud-agnostic resource types. When combined with a [Platform](/platforms), this specification gets transformed into deployable cloud infrastructure. +A Suga project is defined by a `suga.yaml` file that describes your application's infrastructure requirements using cloud-agnostic resource types. When combined with a [Platform](/foundations/platforms), this specification gets transformed into deployable cloud infrastructure. diff --git a/docs/guides/build-platform.mdx b/docs/guides/build-platform.mdx index 4b93a51b..a7e44b71 100644 --- a/docs/guides/build-platform.mdx +++ b/docs/guides/build-platform.mdx @@ -3,14 +3,14 @@ title: "Platform Development Guide" description: "Learn to build platforms with Suga through a hands-on example." --- -Platforms can start simple and evolve as your needs grow. This guide walks through building a single platform that supports multiple deployment strategies using standard [plugin](/platforms#plugins) libraries provided by the Suga team, which include plugins for Lambda, Fargate, CloudFront, S3, VPC, and Neon databases. +Platforms can start simple and evolve as your needs grow. This guide walks through building a single platform that supports multiple deployment strategies using standard [plugin](/foundations/platforms#plugins) libraries provided by the Suga team, which include plugins for Lambda, Fargate, CloudFront, S3, VPC, and Neon databases. **Phase 1: Serverless Platform** - Build a minimal platform with Lambda functions, databases, storage, and CDN. **Phase 2: Add Stateful Services** - Extend the same platform to support containers running on Amazon ECS Fargate, alongside Lambda by adding VPC infrastructure, load balancers, and security groups. - **New to Suga platforms?** See the [Platforms Overview](/platforms) to understand how platforms work and why they're useful. Don't want to manage platforms? Use Suga's default platforms and jump to the [Quickstart](/quickstart). + **New to Suga platforms?** See the [Platforms Overview](/foundations/platforms) to understand how platforms work and why they're useful. Don't want to manage platforms? Use Suga's default platforms and jump to the [Quickstart](/quickstart). ## Phase 1: Build Serverless Platform @@ -43,8 +43,8 @@ Fill out the platform details and click **"Create Platform"**: The platform editor has two sections: -- **[Foundations](/platforms#variables)** - Common infrastructure shared by other resources (VPCs, load balancers) and common variables for platform configuration -- **[Resource Blueprints](/platforms#resource-blueprints)** - Templates that define how to provision application specific resources, such as services, databases, buckets, and entrypoints +- **[Foundations](/foundations/platforms#variables)** - Common infrastructure shared by other resources (VPCs, load balancers) and common variables for platform configuration +- **[Resource Blueprints](/foundations/platforms#resource-blueprints)** - Templates that define how to provision application specific resources, such as services, databases, buckets, and entrypoints ![Edit Platform Dialog](/images/build-platform/edit-platform.png) @@ -148,7 +148,7 @@ Click "Commit Revision" in the platform editor, add a descriptive commit message ### Test with an Application -Create an [application](/projects) from the project editor and design your application architecture using the platform you just created. +Create an [application](/foundations/projects) from the project editor and design your application architecture using the platform you just created. Not familiar with building applications with Suga? Start with the [Quickstart guide](/quickstart). @@ -406,7 +406,7 @@ If building an application produces Terraform errors: ## Next Steps -- **Test with a real application**: Create an [application](/projects) using this platform, [build the Terraform](/cli/build), and deploy to AWS to verify everything works end-to-end +- **Test with a real application**: Create an [application](/foundations/projects) using this platform, [build the Terraform](/cli/build), and deploy to AWS to verify everything works end-to-end - **Share with your team**: Make the platform available to your team so they can start building applications - **Create environment variants**: Duplicate your platform with environment-specific variables (e.g., smaller instances for dev, larger for prod) diff --git a/docs/guides/plugin-development.mdx b/docs/guides/plugin-development.mdx index c8ca05c0..ac428cea 100644 --- a/docs/guides/plugin-development.mdx +++ b/docs/guides/plugin-development.mdx @@ -504,9 +504,11 @@ go mod init github.com/myorg/my-plugins # Create your first plugin mkdir lambda cd lambda +``` + +Create the plugin manifest: -# Create manifest -cat > manifest.yaml << 'EOF' +```yaml title="lambda/manifest.yaml" name: lambda type: service description: "My custom Lambda implementation" @@ -527,14 +529,16 @@ inputs: description: "Memory allocation in MB" outputs: {} -EOF +``` + +Create the Terraform module directory and files: -# Create Terraform module +```bash mkdir module cd module +``` -# Create basic Terraform files -cat > variables.tf << 'EOF' +```hcl title="module/variables.tf" variable "name" { type = string description = "Function name" @@ -551,22 +555,21 @@ variable "memory" { description = "Memory in MB" default = 1024 } -EOF +``` -cat > main.tf << 'EOF' +```hcl title="module/main.tf" resource "aws_lambda_function" "this" { function_name = var.name timeout = var.timeout memory_size = var.memory # ... add your custom Lambda configuration } -EOF +``` -cat > outputs.tf << 'EOF' +```hcl title="module/outputs.tf" output "function_arn" { value = aws_lambda_function.this.arn } -EOF ``` ### Step 2: Start the Plugin Development Server @@ -810,7 +813,7 @@ This is particularly valuable when writing runtime adapters if you're more famil - [Platform Development Guide](/guides/build-platform) - Learn how platforms compose plugins - [Suga MCP Integration](/guides/mcp-integration) - Use AI agents to help build plugins -- [Platforms Overview](/platforms) - Understand how plugins fit into the architecture +- [Platforms Overview](/foundations/platforms) - Understand how plugins fit into the architecture - [Suga CLI Reference](/cli) - Complete CLI documentation diff --git a/docs/guides/static-website-hosting.mdx b/docs/guides/static-website-hosting.mdx new file mode 100644 index 00000000..ab3ac8af --- /dev/null +++ b/docs/guides/static-website-hosting.mdx @@ -0,0 +1,335 @@ +--- +title: "Static Website Hosting" +description: "Deploy static websites and single-page applications with Suga" +--- + +Host static websites and single-page applications (React, Vue, Angular, Svelte) with Suga using buckets and entrypoints for CDN-backed delivery. + +## How It Works + +Static website hosting in Suga combines two resources: + +1. **Bucket** - Stores your static files (HTML, CSS, JavaScript, images) +2. **Entrypoint** - Routes traffic to the bucket through a CDN + +```yaml title="Basic static site" +buckets: + frontend: + content_path: ./build # Your build output directory + +entrypoints: + web: + routes: + /: frontend # Serve files from bucket +``` + +When you deploy: +1. Files from `./build` are uploaded to the bucket +2. The entrypoint (CDN) serves files from the bucket +3. Users access your site via HTTPS with automatic SSL + +## Single Page Applications (SPAs) + +Deploy React, Vue, Angular, or Svelte applications: + +```yaml title="suga.yaml" +target: suga/aws@1 +name: my-app + +buckets: + frontend: + content_path: ./dist # Vite/Vue/Angular build output + +entrypoints: + web: + routes: + /: frontend +``` + +**Build your app, then deploy:** + +```bash +# Build your frontend +npm run build + +# Generate infrastructure +suga build + +# Deploy +cd terraform/stacks/my-app +terraform init +terraform apply +``` + +Your SPA is now live with CDN delivery and HTTPS! + +## Static Site + API + +Most applications need both frontend and backend. Route different paths to different destinations: + +```yaml title="Frontend + Backend" +services: + api: + dev: + script: npm run dev + container: + docker: + dockerfile: Dockerfile + context: . + +buckets: + frontend: + content_path: ./frontend/build + +entrypoints: + web: + routes: + /api/: api # API requests go to service + /: frontend # Everything else goes to static files +``` + +**How routing works:** +- `https://yoursite.com/` → Static files from bucket +- `https://yoursite.com/about` → Static files from bucket +- `https://yoursite.com/api/users` → API service +- `https://yoursite.com/api/products` → API service + +## Multi-Page Applications + +Deploy traditional multi-page websites: + +```yaml +buckets: + website: + content_path: ./public + +entrypoints: + web: + routes: + /: website +``` + +**Directory structure:** + +``` +public/ +├── index.html +├── about.html +├── contact.html +├── css/ +│ └── style.css +├── js/ +│ └── script.js +└── images/ + └── logo.png +``` + +All files are uploaded to the bucket and served via CDN. + +## Build Process Integration + +Integrate with your existing build tools: + +### React (Create React App / Vite) + +```yaml +buckets: + frontend: + content_path: ./build # CRA output + # OR + content_path: ./dist # Vite output +``` + +```bash +npm run build +suga build +cd terraform/stacks/my-app && terraform apply +``` + +### Vue.js + +```yaml +buckets: + frontend: + content_path: ./dist +``` + +```bash +npm run build +suga build +cd terraform/stacks/my-app && terraform apply +``` + +### Angular + +```yaml +buckets: + frontend: + content_path: ./dist/my-app # Angular outputs to dist/project-name +``` + +```bash +ng build --configuration production +suga build +cd terraform/stacks/my-app && terraform apply +``` + +### Next.js (Static Export) + +```yaml +buckets: + frontend: + content_path: ./out +``` + +```json title="package.json" +{ + "scripts": { + "build": "next build && next export" + } +} +``` + +```bash +npm run build +suga build +cd terraform/stacks/my-app && terraform apply +``` + +### Svelte/SvelteKit + +```yaml +buckets: + frontend: + content_path: ./build +``` + +```bash +npm run build +suga build +cd terraform/stacks/my-app && terraform apply +``` + +## Custom Domains + +Most platforms support custom domains through Terraform variables: + + + + After running `suga build`, configure your domain: + + ```hcl title="terraform/stacks/my-app/terraform.tfvars" + entrypoint_web_domain = "www.example.com" + entrypoint_web_certificate_arn = "arn:aws:acm:us-east-1:..." + ``` + + Then apply: + + ```bash + terraform apply + ``` + + + AWS requires ACM certificates in `us-east-1` for CloudFront. Create your certificate in ACM first. + + + + + After running `suga build`, configure your domain: + + ```hcl title="terraform/stacks/my-app/terraform.tfvars" + entrypoint_web_domain = "www.example.com" + ``` + + Then apply: + + ```bash + terraform apply + ``` + + + +## Environment Variables in Frontend + +Frontend applications often need runtime configuration (API URLs, feature flags, etc.): + +### Build-time Variables + +```yaml title="suga.yaml" +services: + api: + dev: + script: npm run dev + +buckets: + frontend: + content_path: ./build + +entrypoints: + web: + routes: + /api/: api + /: frontend +``` + +```javascript title=".env.production" +REACT_APP_API_URL=/api +VITE_API_URL=/api +``` + +Build and deploy: + +```bash +npm run build # Variables baked into bundle +suga build +cd terraform/stacks/my-app && terraform apply +``` + +## Local Development + +During `suga dev`: + +```bash +suga dev +``` + +- Buckets are emulated in `.suga/buckets/` +- Static files are served from the local filesystem +- Changes to files in `content_path` require rebuild and re-upload in production + +**Development workflow:** + +```bash +# Terminal 1: Run Suga dev server +suga dev + +# Terminal 2: Run frontend dev server separately +cd frontend +npm run dev # Usually runs on :3000 or :5173 +``` + +During development, use your framework's dev server (with hot reload) rather than the production build. + + + Learn more about local development workflow + + +## Learn More + + + + Object storage configuration + + + + HTTP routing and CDN + + + + Deployment workflow + + + + Automate deployments + + diff --git a/docs/images/develop/access-control/service-to-bucket-access-control.png b/docs/images/develop/access-control/service-to-bucket-access-control.png new file mode 100644 index 0000000000000000000000000000000000000000..183f49f03bd714efecd90fefeb4aab608c0d3fb5 GIT binary patch literal 94278 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

0(=PZ+EFp>9YKyi4b{^|W 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

=Klbf8sMxqc>P}3TlUC8@<`s#?t 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%0Ajpy&45D&72y>Vas(Ibg z^iqHJLNpIefVYA#aDYoxD*SNeoMV6H=xmj=Vf#3>RtjQ0|zZ1U2`|h(rooH z&49ZqRLJTs&?>s7@9SHn1NHY=6Z#DA?o9ZNiz!(31~Wp5xENqR{!m zsP?Y&>L7O^Hrh-81d>wM7i$$D`uG;EaSa`0Dm@lAtBx0F8y{#)rFX7Sy}pu)i&jec zJwbF}Hkc?xqA|!+d>GIY93JtWAt1)s%U_ieKXa=Y2ef z1o5Fz>p~bSi1}hNbHogLZ-ENOuO+ONu?Pc4OEpQ}f zE(A>0kDRgN>*)zZVv3VY&YC^qh0KW%0Xpg#W>)Iu)3_|_T@4`o z5(M7H2;;7qbVF7`ysY)qZfQXVNMM{{!=}9)Whf6iTA@xzO#YW#zzTb#6T*A(T+beO z<~=aNWf~M@O%~=qa_evNJE>JMKVbUPtSvRccyCO1u%b23^4^aH8&<$O_|+V$Vk-#D zkVd_}Ldp|PpVY997e8!npY5TWFhWwFT!RcTK#b@EAc%mLQJ@*-h0RbyU9p-Fya-n; zh*${S#LAE!7oP(h0=pCy0vhQW^t10HGH-qjCpwr%8SE!PHda@RXaGeJlB-M8_F;k$ zi%FFshk;M+8CC6dT9^^>*W$?795?-3$PKHx5H{fV?gAam=I)N!`LdbEE@hZtpdoA* zH896U^Ho8D=c#qGpOJVRR9K$;9SIrKAU;{xl=h8fS0^04S<(%3(gv4ow>!C!?e|2^ zaBTp2lG%!USUp?8c7kQF;(EJX;h%2P?_BnqPv7>tY|v*khK1;-1gCv>rZe?nfzX!CJ>CCDL+`2r)d(?q)dv&! zMD2!*s>9Fb^9Eqj(0bSEmm%!f&Fn?4&T5I>%}VR^wMbB1OF~XeG>ueyeepXpaf&zo zrXPz%Rg?0!4-0Am0i;r*ra4T1fF7s;teARKV>(XaD-|R3%ik3;AcTc+Y`B^+yhv6S zujZ9vQF#$K=l^xA{|g=d)3o8PA|1i@z*N)Sx}nZTDwpq1RScM}ku8XI5|J-X6XE^g zU4E}CPlWcOy74g_4(*FZ`iP4~ww27?1Nl>Mkn&0V_p0K|hwjL zs#!%G2hGHfaaH*1DiC&2EU#cT-B#ZsN)T_oy^t}Yl|4Qf>zrVC z`G745Q7BQWD?bPP1iwEPa?UuI`+uNA0rXCEXL|UTP(f7~g%XB8p6mO*5BT7NlJmC! zIF^8f=yy2}X*o^V;D(-xOv9Je4m31H{8R>q^qSf3zxrc@vd=EzYyXI~KisL6jFh1G zx1M9OVg}Jnefk7S2mr{*7B6%+f`+b(Oz-MZ6wm6})yY-<@i;C6f(ZQF`A-&wKnV5wA`FHmN|9aYk zN=9~;mX;Jh?g72YAEvP!bcjy!P4;<-d1}_yrmywHVOE5{hCTtAYq6BC^rdBXbZwpb zKx=7yt?m0S=>wQ8t03&$-P*=3y+JPjT7d<@9q7~k5#SS=C7vFNAuDK?zvd=fS{%40 z0o&i7lV7rHEYa$7Ar#q_oBwlSBd@~A{;&@EW4KUbaD)X()Fcy%W-6%p*Wlj7UrK4B zUo?0IRD`3k10yipn~}kLe}4B=IZz;VZj)91b9N6ZHhBl-+xH{@wT}e`>Qqpqc7I}| zBniZ;Uud=ApTHo>oB(vN5oo{p`meXi(3x2-B|)9UYH|{O-FqZb9U7`MCaw^wI>UQK z@GoPkuS!5mLNPmD@n>vk!4Ahqz&DKa{QikFM{4YN`p^PC~#Sh@pc> z2SJctq)O-@U8?lnt0F}d6QqfNbm;_8M3CO38fhX$se*K*qaZ~EtpA4M>-V4UJ90c6 zlD&8D?Ck8!b7!6*3aN3LUB3q`M*wVoN)40uX7%c1X|C{F`33O$0w2v|5`fUnC`^iv zv%RnvG1>Aq0Rbl(?gkkzTOQ1cI|(%j3jZgA@TrIu@%ed;hEidQXDyn;$nGZ}nb(_m z({qB#Un~a)63s|?DT9QTjb@hom52|vI}1j4mXVR`=0mxfn}XI(SGO|C9|N^JLxeSXC;}?<|dOQnfll(^&XlBw-kndSZ?Tzb>Ln<8>5vHZa~N7)xC@^_Qw~Al4+{`1;!x2 zo=BZKK8^}=a5(M~AU?$T>)CVqcP=I!J^(*um;ak{I-VCxG6{CFI;ISdi)}$+FDSi~ zYxl#Sf_Q0tg|lUYR%9}?ceaMVVm4-6GKD$NZ=A zL&73K7?AM+MbXhjYLH#i)eJBtM^NyyHeKSN>uvz953*4rd;5r%!*ecj4M`DRxqd!K zF%v-Zpi1_U7ye}uesnJxxK@?OyKndr_!*VJpWA*8=pC>Arc{4;UeaR7FJXd7SoWBe)SOnecyRWU_3#VJ5xchnFiV95wiDvTb1Qb>F?6#~}c# z$;b6cmpNp_xTks-+&nywQ80b=1G~mUX#6+V$T0&I5HR#O_#!ED)lgsiL2ZtyB8$W7 zW7S`82$R&)0;?D=>IEIItza`A8K17uzjinooF?UpKYb3iy+g+MGl52d;^e{OVq91S z1%n6}S0mT8EZ8Nzf-}ATawlP5gQXP@^i9$_6a))Kh*(KR;KcQ>Om9u>%uat!6_v$5 z6V8_c@!3Pht|b3Nd}gkl(=AOWr2fS(3-j6sw|2(MvyYyH^KV+w1(=T^Gn1vja8I6l zGhW7LR9NzE&Kox;HRMWbc-0NBK6`1LDW*9v5z}>8gVYa)Esc4!a&!N+{DhQ|BzxI< zrstfvQ)@;J&QDql-lhsfw1IlX?|U_VF}2P3TY?&CAc>7F{hNo9K*MiRsOg#dsCv9> zb5jV+j;S3YwcYm6_JK?r$$TL}pt# zQNkte{QlWNLTglNT4UQ0b<3q^j|PVDhC=yYbUWKxXMqw86)31pK>qG+!wjbAvB0f~ zpIJ6HM1Mc=E^zBZ2O#c2VO5}SvSrN#pi2-ei{QnJ7voIk2uopLWO_cfAM2f=Xc+WVT#iGkQ!b^IO-J0L3abqSE&rK0G$Kv zBD461L?3&0{T9WO7kp2<4~~vk#`}Q`Ea3A-@fLiZwOh0HDEOYkn9izJB{N_nQ9j>x zIxz7xLpDCXByGS9~>G2$WyX&asXsK1rh{` zXj$ISM36Bmph1J?QBGVuyXy03RrK0zSD#vI&<>TgaQX#v_vXq#zGhd6SzR6}m*jqo zk2?a#V=ex!m~`Ov3beqsqX+`SqjN93K^sw30Gr*a7Ft6XMw3#L;Hoi@5(3t0pReFM znb9T)XFD2&uRxsrpwg?qQ%B~jg0_-j=q?SzAjA0H=3E;$hPU*29u16+139}(T`lz4 zZY5Ejj2M)FSpUwCkvy+?WrFTi_(3-3QMSlIWFnTTI75(>3PFCD@ zz2rID4md6ra-mZLK##F9P3(%Ks$!ot72wvAf^Y=tBQ*({373@w2j^8u1O%d^sM`$S zTM7um@Fbc7;gRV}ejT7zmU`h%{FY6=QnQ3m%L;@gl#!9KiXh+zEKR}cXcAfl zbPuG6JuZor8?;}RPlnSic7%luWs+GAD3`sjsLA1v>e+s^%N(#WrYi&hN#+}+XA-mY6lRbvofr>kvf0k zB1OEhY%;zja>jSJwO#osdpTGFEuF)~YCOVh`EvfsMXGJ$$EfQi_+Wri%Gf`7^@wD|v z`M&73mW6lmD6+6X$~N9#8O(kr94*2w68C%{A^l@%3V)7-&#F={ar{0`6<&CSe(=l1 zq&Wu*gJxkFrYCnDdfqg%q2wG=Pu1FH$Zd;z=dIG_jGSs(Wa%?Seq1lXO*FOK!i;3gIEMU+*}}@dyndNDbN~Dgk)mcIeC1v?Wk8H1KN;wEh;}WK$x6(h(vI0^g`W5G;^~-kIk~XlJXe z_D;SC9_j`#@P`xLwbGW=v7`vpOg%Jhm#4(ZRFx^!PPU)_$;s)!8;GlGs`gmrPh8W0 z{=Mn4M@8ec^v=ZA#|-}1Q8tJo4wNJbo=A=ALMjgNxvGPAImK7cC_{p$Kta>^Dd>uY zvz-e34Cjqnry5b(Zlo67le=q#D8V;~%@Z)V^`QQ6f}ilorc@%(sH^ZYH19@ggm|eX zq>zokLWN%V58&!L$vLoL%*XfP>b$J4o(>dI`(a^Fk6_OD)2&;7c8uM7NQT!WihkH3 zAQ7fXHfLatFh#Vm5|f`_&(*?=~Z!De=ZMID>4}0%6fyKSrOw~ z>^>P3f3@{`V_dSnWAZtTUN2FqyX_9QE*Lzkd%gTiO{|~akD-OM9p|o)jR&o~Q{A?z zWR~5vO%q2YublGD^uyq|%P}GjkJ`8d&W@J;B)hw)^f9`1;YO?}L1GR>_7?qSnKI-| zj8(_g1cXS@&%}pLD_f6P2;7i1MZRpIo20To1BF;wanDkl^w~#n{Z({r6(pDj(25Eh zi-e4bCj3mKbzH$PcgO7mqecp-r&5EF)_j`NPvcz?9-5&nszR)RF}`~XVTyqAXbAm| zJ`4}Wg|k?d3ES`IM+Pjq+3~*!kHo)w6ZO`In5}{adOELyr2WjJtAM6?JR9* zM;?>5J%pYbZjD=s;zy0EMpo=NWbQgktM@OIsa@#k%#zt;2x?5P=_WJG?8 zF;j`s+S67%v~l|O>5j>Y6%*+Nxuj-x=_wz^9NtuzKEK%>@^sqo0lm%;DYdP^XLVwz z^BL$^sUD=1P2z^(=WcblbJoVFGDK)a`mI~heN^-%*svO!&_n=gWQ(*`Zf`H#lP%4k z)y>B{0;Oz@=JeN~_bxrtpoYj9_{0=pEj`W-m04PZQn37ZDX54v9%yo6zN@GZPJF}I zdEN$|TAmvm!4A3PFg+0Ut2?Pd4xD;m#}ryE_O|tR-iU!Q9#S@)axfXCr~ie!oJlhz zy6Cs^12tRW;3?-zzF<_t#7ld)6=Xo&7T|bl{z8|CQS^ioi^kvp zji?r-N#KEt4u~R@AOZ=rOyXiOqDfZ|Jj`wu)J7OpVaD3>xrFMe3i5{vTlsckuLGsw zn}>-Cq7kU8ps~wpZo*N(45Gg+1nHOM@MVANiY?RK!`uu|8h_qPF;i=EXK7dJBVp{M z{B!?#a*yl>+XMUfm+Ajd0v-AM21+cYh3xcfS~ry~$o(_$ZezbCZ0dDj)$R4wZ(6Sd zWluR=t;g38SkoYe6PMg+y2e$H-N|t+7EV`e#-88)M9p%`r#F87Gt&nlC5jIeKlY0d zc)iV1Z_Q?!`%-d9NGV`{yvSxCS#)gi*iY)#E?Le|9FSImjzb(ft zcFKiOVG+--0pzK)q>>l@g}{EzP1|u=t*3b6V#PIlYA1?-I5jF4b2m@zI4rGBfn;0F z2bxJY97IhxQDo!{3-SD-W#W(B=@Fd;;OMJCTVi^fnm#V9zv@1yPgnyOSsnj&?J@fT zu9sZxDw$TR^mRM02)uMP8Svc3A88~rn|>?2*Xle7EnHd4n^KHCj$%E0_$LhY3||bP zm-Cujk?P_8)OZjSipHTpyHoMpTLc|O9QcK=QUOA{%HZ?k_;x5+_;WQt#EaRey*KUf zWI$)ie)6z)j2Ojibr{1%VR8G8t{1DJ`MqOt9gBDn408p9^?cN2$wyH>_=_>Q+Iu?7 z8vpl|fYR&B<>!Dg)d8*)8lQ$cRSWi`bVAgCaw!fKgpZux znv7E(@2P@#REx3yX!Z}yVZoTTqF(%L9pfNQ)e=v)dK|?01h}th`{6S?!oGCsWQ#<; z;m6C6?g5y?*7LxmgEhn32<|LY_ek8I^7O&Q@&kkfgsYM8O6}>NitMi~;rpFI3m*Ni zGv4+cK)NXFda7e21KcoOoh68ucS7lNcyV3YAW!n)RjmzRvTxlow?90)=<1PzuXp>) zwQluy`r)YEd`I8U+I_R<3lD~o%A+S6Ge6yQoL#TK9?8SUhPNf*h}0;XaH5IQBh-;Y z&;tIPBv~#mZFAX?^TC7Z{B(ySxKxuJlT-nn(}(4)sL4c>I6Yy*2xQM>4mZo5_QiwW zm=rwCStYba`tKf!LFw$4T29rTs`_;h2k*c?4AXoDRLO6AA1y9ke6yEExy#RQoz)~F zcN@-vq31kc8_Bn*n;6nW5B;S4k@Mt4X6yAgyF-)84*2H;yWQkiU>-4k3Gwrbn8`k{U-Yne$A=q!k8<%fq#|v&0}3va0=rRl zFs-9Ij4QH)r1p;VXOq`(9f$$&oJa(!zk8VT^npIdvMP^A)&NUhFaXOnPl4&_ix?aj zwnK<&n^=ix+CXL3^O&QnR|1;(0$7^3Fl^#QjW!RkV3&!XWnQVL{)bNudl#^M6|Uyz zsxxAbYO$(Rus>|vd{P#sX5^hbgvYFitMB2q#cy=B{1pV|>N%9{%SgG)$mf=e57efs zUmYTVaX5F1fT5Vtw~nvYYk6Yf1rD1G!gCqNA2 zyL0*H82wy>9>=S>kL>DJS_1$VL(SuN)npuZ-0^6N)Hqbbtv<`=+9pr%6i;{=nW9*< z&OKB@J9ks-A7Q;NZ z|7!kzO}_T}fwXmL@CLTWs3hW0Tv%do&f!s;wk~+2T-3s@q<>$u`O_0eVlY)jJ@ot- zK1_CaSSrImyc%$~^I<0aY#uQUxSl>4A0WhqVd&F3#e|J9$D0Ho(#Vw-SC3GWGwOH5=3hM^z!Vq*-?JIgtGCB2dy~orB--gegXH{bH3sawx;r40n+~2R zkzE#q2@*UwD;c8W1oDtOPWD%I#Aa0oegCqm7(q6|3E4qH$(UpiQ8zxmGXyWGLDC)p zlnSPZ3oItkd(TWhi*IUnnpq|K3}B?}5`Omk1QF<-;?QOLOoJgGP(T#2H(1>lcl@0n z6_24e!4q|ModF+#Y)}e^u3OyZ45zE21~7ne#@3=c&QFnc1Yk>@&t9FW@!?inLJf8T z(iBU;(7g3)#{2U%&qa3W>#+E6`Y*A&7$(D+)y!3%H&@pV-6Abf~l zsgszPzq~g_akG zdc_au9FPzyc;}-)liHB3cW*~D5U8D=r6m?flsl%f&JJNhCaP&RLV`nDx3Hspn{Gm# zL1=p6PCF{Rvcl=36O4tRftwiF!)jJA?2%3et4=VIN9emYKE0;G44uU#kV5G~cnCp6 zX^IG4Jc&t2vQe1wnokgx@%i9;8)i+6y>EhuR<tink1f66weYh5MCG_ddg-38ZmrAs^$!mI zuIUPjL!wDG?|@uOOlS?Q)306ZrJfLXx+AJpgwFc>gSoE5(6us#_Z+@|O?Rk!rAzud zji(HFE@huj6bv0o@`hUqH!811>M7VHO9{U37CN)}Gz>Bp?~Z(IxOg@3s)8@wWf8&pwdfu63j)bAQk&1DY%qA983{l6UPH)>ujYN0M+=3fj~7tRkQ0P*Qa?k8ID&lk{|idm<;PrS&Ue z{a-+)W1v8P+O^FtA%)vrZKzH*?YIH+UFji+bhaM}Ew-^_L$+6u=$Fi;#bjPks)(jT zt?(O7Gr_TXrE}y2Q0Hc#$7lSR2r58&WvGpK%IM5Sx*YD0_RxSsCy)zh?{DUr(Tx_>1yI+&@*{4^S(ISUX0P6aRqX1q*I+f z?>@jNU2BB)H;hX)yUU57{5fO_^aX(BNI05g05P?A-c@q>osgqiI)Uh!aXJJeELv|} zEdm=@IsW{n#W381R7gv|0Ge-g-vM!_Kpt;d@q7NNgGq(UnPTj>kG^j%Q>PYWs_);Q zux)J%0w8BX6sz_f)QX@M@z+IjnZc(XO|7heSE?E0&rrek3swV$g1Yie9n;?ot)&n04+!gpcvx^ z23d&|jtkbZ=b1nOAnPhgz!#I~9ngdUuI2j;3z<-Mepc75rBH}y z45Y>!hvjF*g*-Ke_|m|JuMsK_A<>G>0B}cQX(G<#pN5ule58iZgY2m}@t1GW*eK1on zSGeO<`kPryu_0s*0ibOOXbw>SY0)qc^uWd=+@JyZ3b%8ji)o78#o~m?f9NTlp-_dW zOPkpfX8q)iM~<&E*+E>()eGKxrJTV{lv&_C>LCSegHpthf|BIXn=HH^(?HxFlV^S_ z;Y9flv%mbUf=nPN3tjmpV^rp;a{*s^K>;c*C{O;&)^L+jZS~Iww^F%NQ|nsY2QTe_ zkK{wVIdoogRAl1+oFPq+r^%=Onr+jmrcZn5tuUw zWKIwB6XReV#<8aTcp|n+5Zz%w&)zD*?r(>n1U?R+LSdJOEPOxHpx*Hu#Rd6DHUGh+ z-P9Vr_6iVb>f$@r*5uaN97g~gf;ZrU$@U48%MGCB2+EvMu9_UQkck;Sb;-_SoX9AUQxFZl3`PGmJqQmD26Vk^mg36lzlVmal%O+RQY8Ul9NJMyM0Ao1*Xm$i1FnykD1%OD&vZ|`_8?t4W zhVhY7KJl~X%h^F^_^_?&SX#_o)mXk9eD*4df9&RjT^ZZoWx_JSGSeTX@CDuagK_@d z|Fc!`wA?jtvVIp z9t#mKm?)08zSqdF6qNRCFWAVyLLwVG+{m{FLTB`#o18{M>x#7{wqLb;+qR#3p&$noNZj%bpxaWVN&`m^~-NRQ^ zbfspeZ<`(EhD0l~1TAYV%zdrRs6gF}134xjBsXt4$}Bm!_H0)6o1j`?`d0(k?)Ab(z4+huygvp&@D0KrUN`rN|Fs|A0amlUw!No6xEK+1aeG}{-}G?; zj+6pCInjx!18@k;1MEZf*91Kvm^zP5T_lWR4D5Y=r8Nq1Gw`=hgZOIL35JFDep^j>hfR~AHVZlq~N{> z8IUzUxjh>H@yVm5XUAN(m{#IYu-JXH79Uyu z?eldQspG9(_S3BKcXb)M&yQ?VstRoHI{QYH|5W3UL`b*HV=zd26?gt`jvYm+CyYbC z`x2UPrc~(CkZc}4RS<6%1H#Z7Q^sn0RYT z1;RT=xgzl-qHu1y?-Kiy*A}|s#G3428HXfX|E87#KtTaJFBQj&68K{(TN|X1u$diw?w#Ji)cV)p zSM&#x`w+uAI2CZh0zWh1hqngU+2+DD9y>dQXA8mu(RYa_n|8*zlf;Rb?Enq*(E|LZ z-0AWx*{MZ4b@chUR6~~!l66cSj6MICZvwHou%nG1auu+Nse_(W+7m11z3$?XnSN{T zsAK*6M+OwmviL-nJ&>sO*mG?f)H%n2db*Sc1~(tI(h9tAjYbswBBAByM#aFL8>U$i z&{Se}ttl7@FB+bzol8oRX`FBLSom2Mx?9(f1tg%#d|SZi8Cv=8_jjrd{xTE`avfDZ ziQFmgloXs(NWGQE1I8)ml5*u}+l^xRi?UD`;M1>|+KEq-LOpM`iM_uWIXwm5YpA`6 zo3iSxEkeOSPYT-zag_vOuKlQ>je4h6o`%z^&vusIGD}`t0DL*cMkS{8mEoE#fZtad zu%v?Y5En-JhOi4kr{S@T(zWH~<+t{?LD}=eDRci{0S2_Rv>1^4Qs>y0z5#RiEDzax z`}VB>Xb9Nsc*-_u%2xH)g@i;d9VWn#KunBTBg9VWKhb8C2|!YTK3F9O9k80d3~Kat z0&rl24fnpv2@v%-On;<+7<#Yt=MMdm3tEPHsp~ENd3Zg$my|$+{UziBj3<&9PKmf| z()OzQLtf#t2D+4~uWu_G3(+<{HwMH$rJGO-VW1pzNXkfbE0XBklZyh&dw;&keopSw z`W)Ueb@6BVzRcRUl2WO!>n#8hxnw9N^il-(Kxl*Y{1?@1&>e?$K~L%Q@Vj?34V~@V zwp7A$7(`9Q6Vl=$B+E}L(4c4|br}g|18kPo-Em3= z-AGO}f7BIF^JUjv{`fKHPbY{)C{ux42tgf-sY91yYO-+q;~#P}O{+gH&fMz@S}3?n zSz~_Ai3KT9&d~=mp4#4~eq`94ilt-@a8^ z*_>&HL#7ua7`ez>AjsKGcx0eqD=pfH9kOeCi4FSv^CaP!SOlUiF>YO}S42(@ib#bZ z+8zkKg;h0A!pp-G$*kzFu-DdSGVV zjfAS>bKq4`at6>offyH#n1elxTXom1sHt$sSx3(fL&MK=%p8cudLgqmVEkfjJrr2Hc5^MJrCJtN0Xz8 zU`Y1Po{_yE=Sxh{aJ>bfu z5PN~WZ(F*)naoI!&KwNxbo7= zc{PpA*c&Hq|7zo6+D$s!K!n#=Jy@_qmugzUoSWUD0(XOM>gh~37CMbH{X#x&=}2sx zmwY>LbxiJ8(L^a+9vkq{dm#cb%p6TjG0hXZrq#BkldPzCn- z9Iy@N8xV^ELtyFl>AOWcG*2qMwl_h%wYf5s#Ke5Dn>^!PR^T`>Jx#KiIDQ4D6ua1y zfI?5`)B01JcBw>iY+uxB-tsdi#N2963?a$PlaiKJ6u+t&3@=Z89~(1XGy*9*H9kK6?p?~k=kE*lWr##` zUa`apSMh}!S2m?BLs!<;y1$L1wkZWQ#xB5o{ryi|v91lfhwP>;%(zI4@lI|s=9BE);mG)a>qxW@3439$qQZ7Pr+V4rxpOEE zc5VaN7}|LE$%Okhb?D`96&j>D<>VPIX>OnJhb(cM(X zW5E@;gJ7f!W9KqP8@AU{el;5rD5Ky?;D;p^9rWV95VpTmLgKs09DHG{Wb*{7kM{3S z%pePHt>LGgS@Iy#_(~KS5qacm?jg+FfjR#b2}aXgo>~zPa$7r1h;EugIPb4<8JaBg9U1H+^=kIlBJgUH<-` z1c4ga-<+9v^Ob~WrZgvfFj*4}xZLu?wef!+KqU=zT)*|Zdv{OKe`~$+f?`Dv-@XzS z2Of}5(3)D{pZOim^6>w-i%=X z0pWZ;JfYEn!sMU7;@G_x#b#QIHDJ5^+LrRef{9{ddF81*(Pm?d z>lRF$t5?Xm>0#GCrSz60V2_mjV3mB}v18TR@{K;4U;dL*i-jx!wE|Fzll23x1^+2U z5*L(kJ!Sc}VKH9a!4HcDtZCymP^BBRuj@YQa_e>Cmv}y-xZvKgaz~=}DK}57r`&NH zQ8=0#5;F{6n9%A|nMvZptnKgbZ@Z_N8oq=7Y|O_#?`bG;%{;y(jsh-7I(9Cs-{LBv zM%>`&@iv9RCv6+w85wyrfURwSY8+|5%mKv7IsH}GS>z*Dq&Os8P5$A_DFe!*i5^b( zXwoQH@C<)h@LQSnPzZ^!9-FQVyqZdJYm!8r?LUeBD>p7|1{+{dj+qBO%8k z`d7gYf5%+GYs}Lrq1XSc`~N=)-7UP;*;7S9{(ErjS>kd=KS^;7kG}>GZw4`huyGl! z2O-C@1`7s~<8Y6E+|9V7l^8qbt9?~WGv=?RBSLVyo((%)S|_R+O_5A)6mVoIt&5= zdbFD%Z|L*+FE9c1qMOWYtl zb;!;ScIVzivX_mEeYf5uyt>oVXNFmw>z}2JI|Y5g_0T%go!`*%Sil%zE*y#VsDjz^ z*S8H6;FsgU!#oZc<)}KIK3*P|VV;lAh4@s5nO@fXu5h%Cc^*In(7#$NjJ%6vh+KWH zlE>NAJ@b5W=3hHK%Upgh{J$&h5tsiAnTGzra9a%GcgX4l*WABG@B{Ilv0eX#o&c%u z$L4@q2lt1}q(GrVj_mO%uoVYe?j%?q8xs81i$}{*aBZ1o{av9#dsq{}w~UjY@{C@K z4u4BH2h>G<<`VJ0_Bk#TeZSpitiZu95i)rGNEU_euwea{l7YMo_e`x4;6=;J%Nkd_ ziTVDKAPej~B2{Gc#W}^OXsN#+=;ngb>5j*|Zn+9xcj`sWVyCXvCsMy7yR#Bg?Hx9C zOU(G63IDqVu|?XXN?0o5@`nAp4?I=3$3E6vzg$6_aP|NAJ_>&AoNmzS?|EUy^FJRVM&QrVin4&uebNh?(XSRr$#zrVIv6zWAER;fBEty1_MpEva-rK z=Y(ldK+nz1wY0RXt+{R}U|iMpKTS@aJ&nT0vN`DDi&rTr zDF%TjZw9-%y1vbp1(BId6k!Rk%N(NIYo=vu%O@L?o{li0J`wEY^?7B5`$Y)w9d80B zkxhZ|++&0OM43O%3SVqOyW^II*f$|ck3kLrx1z*}Qc{t6{}og=Dv9;-c^-!@FQkLo zE2?DBGbjH(n?ZP?ync8|NlDsd4Q>ZZT2DBM@Ra8mr`wYWm5CyEJ&1ouoYEb)Gm>3S za^ijQ3Q~vkZs1PhUHbF2KDq@i@{?z~UfD@WUyRsqow8+lc&~)gn&~D9d{)4LO>+;X z%MQ~OgY|0aWN<*mykFkRXj zf|qa>#umu1CyXv;lMp*1L0(iSu{2L+1=)~>H{D!bCJ*OgU2wuB<&NAJj7Q-31gS&u z@ywH$dXoM~bNX-r$i=J(=4mU2iLwXFGjLQw+?{*DP%L@9aI_MHN6e$w!bJD- z91lAs&hs`0JYW-er3BVo=MTg2$rF0x@sSTZry_O3tGhaY3u`?!dmr& zB;#~#qDz&CA@11%cC@DcGxBoUyTZ}!g85gN2!b}%LS>||mXxRh7rc1b`~soMzJq5~ z^xYA!{tzde6fue&kAF#wZs0KB>ot*tDc{q*58X76;@*fOh}h5CWJ?OqFVcjhGdq?u zB~xTC!Dm6}jgIfpQ27MQ>0;^1zpzIV7kBq-Aqci9A!LO;afB!fHpnTiIb!tPng*!_ zXL&ZmlAKw;07qX#!>)l4nb4nf`_wFugg7)RHP>|o8ge%i5=q`7ti*gpKzLISM3!Fj z#7GfnKY>gXcb;I4&}k+RLc=t*^J3dZJGJSx?^?U^EOa@f?r1EOoo@pxVwty;B_6AU zf9>BE4=0nM;Ksxyv%>eFQg{SO^el9b&x8$x-EWZ|vq?64<0g1GC<*Oi7mRo$86u{& zZ}CKK?<+no;TfW8{0kQ8g@f=r{Ef@K__zo8SQhfez0avD#`(xFm0j+s)@63lh#2C}LR)VpfxpEDI5F%QKWL1u^93 zctF(bQ{CO~9D0i+VEQ@X+2I~}m{992#8X~vyk_cP#m>UWc@#yo$j{xfu*b{hNsL3f zk)d*7%mC2}JPB1jPG`t6lw^iWghUAj!G}7Hyh6vvlFD7?1v7Lk9O=^`cwBAUEYb*s z&tDtva;Ios5E-gYuX`7!TLAAs7O5zy7#q`eozzqQE=-PIAyo(k5ptmJpc8+4UBILd zjxu*>VBn>70n+f10OcNgTbted{QCNO{Iit^Na!-MbnM-`aMIPsecvXEOY7fwWczJR zBzR?aR%zWjIS_&mkSBOxuiv_HTfW|g{0)iW+bT&pxJrkf%4YGnpGxhUQe;)cP=#7^ zt>7fcz(?OSSy|aHlNeE+Vg(T0c5wppWPihhB~34!Mx>_g_$)m=BZDISHTzip!c6>EEGW8>2zly^KuH8zcp(CECm4}tMQ5$e z7B-;lY-b>k?r^lE8mEKqol+@`(F-SaU`4jr(du$5N-0Ufq?Fpb&RXb7;!PP}p-cMf zyFd#s<7L_nqDm2!PSFGx)69a^B~^dyGvMR$Q+8xuXG$v|J?)TA1bQW7ZTdEeFJ9)T zm43m0{U^I3ho{4jK#}12NL@(CkW^lzZq?Ft5^uW!3n;78?T5=@GQoQZY)you+4-C} zi%4_Gu5wB&3F1YYM}ao$@9&S~ zkJhCP9G9Re&DgQaTn>Y4s1~2xBUa*t$YGot39=QFY(h_iPS}>L3INt|w)?)QHeDg4 zX2%jE7v__$IfPgTC>7XPgaaV7j$t9$;ghh>6Y)cvuk#|L)&XG6nCzZMVbw9e%5dJAVfGHO0W136g z-HlF7KXzx6)n|Y1-fle;43J@cEs|1AVb>e+l-%IWb9|lohh$Mqn|SFWvlePO#aEG| z=|6wxuVWjDs)ld!joo}O5S2Tw%wh(7JVy=9{ri9l>q(X_)ipK5u|M{&!;87b%ChTO zKl%Eyi|W`9VdIm=HTwT}1}v_y-!-(N+V{VE76u=U=eC47Wqx<(%Jj%xy2Qf@>%hmf zwk^^LTK^8DgPrzzPp>J@qx{cbQShj{!1?R&VderZ)iiHdIjb$r1u$r`ieF>btdTdwuTvqN>l`GY4U>6Z;v$hm1?BOs}=gYEvp zA-M5>{ojQ~v-ydjA6@8Bwcg2>&eZ)a_GU_*^S?OZUk45Rj*TYnsxa%kSeKd6c`o_% zrG_k;%AbAY8KM?>nV)OM&;1YY@V^PisR6+&os-gs!DA)dZ)<3Xgp^t}=E2*OBmaJh zoIEuxDTy=aB{p_PUV(cTU$_CTTs}M?9GN` z$BOxVWl18%{GO}Gjei=y^?K{I%b)T7mC2>f@8427V{1E0#ota8D;}>eHi0-gR_9c- zW^}Z6td{oN*w=h#_d+i>S7$GePaDqf(0w{8F2{Z_sGA=WA!tif%%{w!)PM8~UQRil z&M;wmMtb6mS^AluR_FO(9g5)jKGf4Da7aR@Q`bK-PmNv_7Lm@7iTLb(+hRRxqt;N? z<4n#hi_EuS*zhsyVeS0XOP zL2g4)r6~?sC296XOyr0}pqn;>Miy5o$F5rkEdS1}ujgtX*F8yQetn7}{OPSViutaS;5bt7{k!S!H*bySoUA#YJSS!3(~5Yu>gxLJ0sb~f zRuHqYhn5u$k*B6--@au$GrJPn6Z-9wi`U{shNMa&-lvT!t9FuA7p;Li+@X1 z^M3z`#i_5RYU8YW$MIBmBChmT6ETywM{&v1)m7(JS2uSLmj#D%X&soEjkCL}wev0K zPXgjZ?_lBtDR3$<$olkC99qd@iOMkdV+pD zbR-AeZaC9aFxD&JrDRXH|3~8+BO?wK5nplrWA9`ME(}}ewKg48EQn26q zvVB^oJ{tSqs1_|~oV_=rrK#;TB`qOZS$^(wQMTXZ09%^d6c_}sTMSTN!?bY7?@2kY z_tNwe(FuV`I;M5c@=MNZ{Wh>VMfO0hatBf@8i(2S(wQ#5GV%1W?c<%}iRHm-*O|s9 z$_f?V+RNBp;@0ek)JmJ{aNCNwj^X7cFzWa3U*V6*MZe!)O zPxvxi$nPno8p^Z!WmA8-c_O=fI?y)wzu26c8urQX*Vvn|=M3-a&6=O_F~1I^Z1S;q z;PL$O>xo^y3oA)FX$^nzL#!I&lgX#|6B!I!YfI-x8Vs|Z{k9L2X{mZ!cgifA@Z&Y| zt}rl-dfg#0Lbh3&PKSxa4Hmxw$8f^CvWb2Vy&mttUYFVaJ>pwg%k4ggd`>1eWodjk zJUYVE@cfG9XI$6jiju@BJ-)x&iICIV+IzBNq|}PCx9B<8>$STtFATkK^SPT7QmYVl zAH@UC?*g{`9UIEAiHi!+q%~ldl$gEz zks5s(PbTpK=V#cB%oKmnX6n;=Vqct`Uh=W0F@V3Ky~5e*CXqsq5jVG@(NdFgl()m! z#-)Lah7<-Icz|rXmewJE>I!jjPzqCS-`lsR+he!3!X7hRskvw9_r7GX<%Z#-?q|o^ z#{%on!TMYGhJNw{7Rlmf;>f*w#3Bsk%!75FUn>bSa_58ZNo&C+t%|E|p{&-9`rMYuu`3_!n%1XZUr+dSQM$GBLMX5{b(K`BfnSOl1 zeJMFQ(5b{QzjMRpfZ6ACCrbAjweYvN^XqG3V&Wr##!rp0lebwUM-() zk-8+XmO&k)SF=EWHqCkMwcDL!QR-FRBO8arC{U)Rr>CWEhd8gfx?PoF)w(f8{M^^) zldZ_3*EG9^#;W%v{UTJk7RO@l<{zIeYIc@dEy(st&*zT_kqbtb4A6r z;iTnKi|v(F=jqxfIqvO*`U*FVI};wCzl&HN*GYP$-rO++NkV z@WT81>J!T1jC$lcAIarg7sN@}cSw@|dX3mZM09(>9?M{YcpKYPfM{*Z

1L*uCw9OB6+!L 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 KR{T!S_x}K%42-b= literal 0 HcmV?d00001 diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index f0dffcc6..85dff0e6 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -375,8 +375,8 @@ If you make changes to your application in the future, you can re-run `suga buil Now that you know how to use Suga to develop and deploy cloud applications, consider some of these docs to continue learning about Suga: -- [Projects overview](/projects) -- [Platforms overview](/platforms) +- [Projects overview](/foundations/projects) +- [Platforms overview](/foundations/platforms) - [Add Suga to an existing application](/guides/add-suga) diff --git a/docs/sdks/go/client.mdx b/docs/sdks/go/client.mdx new file mode 100644 index 00000000..f063e121 --- /dev/null +++ b/docs/sdks/go/client.mdx @@ -0,0 +1,56 @@ +--- +title: "Suga Client (Go)" +description: "Suga client initialization and configuration for Go" +--- + +Initialize and configure the Suga client in Go applications. + +## Installation + +Generated client is part of your project after running: + +```bash +suga generate --go --go-out ./suga --go-package-name suga +``` + +## Basic Usage + +```go +package main + +import ( + "myapp/suga" + "log" +) + +func main() { + // Initialize client + client, err := suga.NewClient() + if err != nil { + log.Fatal(err) + } + + // Access resources + err = client.Uploads.Write("file.txt", []byte("data")) + if err != nil { + log.Fatal(err) + } + + data, err := client.Uploads.Read("file.txt") + if err != nil { + log.Fatal(err) + } +} +``` + +## Learn More + + + + Bucket operations + + + + Database operations + + diff --git a/docs/sdks/go/databases.mdx b/docs/sdks/go/databases.mdx new file mode 100644 index 00000000..eb641dba --- /dev/null +++ b/docs/sdks/go/databases.mdx @@ -0,0 +1,229 @@ +--- +title: "Databases" +description: "Accessing PostgreSQL databases from Go applications" +--- + +Access PostgreSQL databases from Go applications using standard PostgreSQL libraries with automatically injected connection strings. + +## Connection String Injection + +Suga automatically injects database connection strings as environment variables for services with database access: + +```yaml title="suga.yaml" +databases: + main: + subtype: neon + access: + api: [query] + env_var_key: DATABASE_URL +``` + +The `api` service automatically receives `DATABASE_URL` containing the full connection string. + +## Using pgx + +```bash +go get github.com/jackc/pgx/v5/pgxpool +``` + +```go +package main + +import ( + "context" + "fmt" + "os" + "github.com/jackc/pgx/v5/pgxpool" +) + +func main() { + // Connection string automatically injected by Suga + pool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) + if err != nil { + panic(err) + } + defer pool.Close() + + // Query with parameters + rows, err := pool.Query(context.Background(), + "SELECT * FROM users WHERE active = $1", true) + if err != nil { + panic(err) + } + defer rows.Close() + + // Insert data + _, err = pool.Exec(context.Background(), + "INSERT INTO users (name, email) VALUES ($1, $2)", + "Alice", "alice@example.com") + + // Update data + _, err = pool.Exec(context.Background(), + "UPDATE users SET name = $1 WHERE id = $2", + "Bob", 1) + + // Delete data + _, err = pool.Exec(context.Background(), + "DELETE FROM users WHERE id = $1", 1) +} +``` + +## Using GORM + +```bash +go get gorm.io/gorm +go get gorm.io/driver/postgres +``` + +```go +package main + +import ( + "os" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +type User struct { + ID uint + Name string + Email string `gorm:"unique"` + Active bool `gorm:"default:true"` +} + +func main() { + // Connection string automatically injected by Suga + db, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{}) + if err != nil { + panic(err) + } + + // Query + var users []User + db.Where("active = ?", true).Find(&users) + + // Insert + db.Create(&User{ + Name: "Alice", + Email: "alice@example.com", + }) + + // Update + db.Model(&User{}).Where("id = ?", 1).Update("name", "Bob") + + // Delete + db.Delete(&User{}, 1) +} +``` + +## Using sqlx + +```bash +go get github.com/jmoiron/sqlx +go get github.com/lib/pq +``` + +```go +package main + +import ( + "os" + "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" +) + +type User struct { + ID int `db:"id"` + Name string `db:"name"` + Email string `db:"email"` + Active bool `db:"active"` +} + +func main() { + // Connection string automatically injected by Suga + db, err := sqlx.Connect("postgres", os.Getenv("DATABASE_URL")) + if err != nil { + panic(err) + } + defer db.Close() + + // Query + users := []User{} + db.Select(&users, "SELECT * FROM users WHERE active = $1", true) + + // Insert + db.Exec("INSERT INTO users (name, email) VALUES ($1, $2)", + "Alice", "alice@example.com") + + // Update + db.Exec("UPDATE users SET name = $1 WHERE id = $2", "Bob", 1) +} +``` + +## Multiple Databases + +When accessing multiple databases, each has a unique environment variable: + +```yaml title="suga.yaml" +databases: + users: + access: + api: [query] + env_var_key: USERS_DATABASE_URL + + products: + access: + api: [query] + env_var_key: PRODUCTS_DATABASE_URL +``` + +```go +import ( + "context" + "os" + "github.com/jackc/pgx/v5/pgxpool" +) + +// Connect to different databases +usersPool, _ := pgxpool.New(context.Background(), os.Getenv("USERS_DATABASE_URL")) +productsPool, _ := pgxpool.New(context.Background(), os.Getenv("PRODUCTS_DATABASE_URL")) + +// Query different databases +usersRows, _ := usersPool.Query(context.Background(), "SELECT * FROM users") +productsRows, _ := productsPool.Query(context.Background(), "SELECT * FROM products") +``` + +## Connection Pooling + +pgxpool provides automatic connection pooling: + +```go +import ( + "context" + "os" + "github.com/jackc/pgx/v5/pgxpool" +) + +// Create pool with custom configuration +config, _ := pgxpool.ParseConfig(os.Getenv("DATABASE_URL")) +config.MaxConns = 20 +config.MinConns = 5 + +pool, _ := pgxpool.NewWithConfig(context.Background(), config) +defer pool.Close() + +// Pool automatically manages connections +rows, _ := pool.Query(context.Background(), "SELECT * FROM users") +``` + +## Learn More + + + + Learn about database setup + + + + Manage schema changes + + diff --git a/docs/sdks/node/client.mdx b/docs/sdks/node/client.mdx new file mode 100644 index 00000000..acade4cd --- /dev/null +++ b/docs/sdks/node/client.mdx @@ -0,0 +1,39 @@ +--- +title: "Suga Client (Node.js)" +description: "SugaClient initialization and configuration for Node.js/TypeScript" +--- + +Initialize and configure the Suga client in Node.js and TypeScript applications. + +## Installation + +Generated client is part of your project after running: + +```bash +suga generate --node --node-out ./suga +``` + +## Basic Usage + +```typescript +import { SugaClient } from './suga/client'; + +// Initialize client +const suga = new SugaClient(); + +// Access resources +await suga.uploads.write('file.txt', Buffer.from('data')); +const data = await suga.uploads.read('file.txt'); +``` + +## Learn More + + + + Bucket operations + + + + Database operations + + diff --git a/docs/sdks/node/databases.mdx b/docs/sdks/node/databases.mdx new file mode 100644 index 00000000..aad64d46 --- /dev/null +++ b/docs/sdks/node/databases.mdx @@ -0,0 +1,195 @@ +--- +title: "Databases" +description: "Accessing PostgreSQL databases from Node.js/TypeScript applications" +--- + +Access PostgreSQL databases from Node.js and TypeScript applications using standard PostgreSQL libraries with automatically injected connection strings. + +## Connection String Injection + +Suga automatically injects database connection strings as environment variables for services with database access: + +```yaml title="suga.yaml" +databases: + main: + subtype: neon + access: + api: [query] + env_var_key: DATABASE_URL +``` + +The `api` service automatically receives `DATABASE_URL` containing the full connection string. + +## Using pg (node-postgres) + +```bash +npm install pg +``` + +```typescript +import { Pool } from 'pg'; + +// Connection string automatically injected by Suga +const pool = new Pool({ + connectionString: process.env.DATABASE_URL +}); + +// Query with parameters +const result = await pool.query( + 'SELECT * FROM users WHERE active = $1', + [true] +); +const users = result.rows; + +// Insert data +await pool.query( + 'INSERT INTO users (name, email) VALUES ($1, $2)', + ['Alice', 'alice@example.com'] +); + +// Update data +await pool.query( + 'UPDATE users SET name = $1 WHERE id = $2', + ['Bob', 1] +); + +// Delete data +await pool.query('DELETE FROM users WHERE id = $1', [1]); +``` + +## Using Prisma ORM + +```bash +npm install prisma @prisma/client +``` + +```javascript title="prisma/schema.prisma" +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id Int @id @default(autoincrement()) + name String + email String @unique + active Boolean @default(true) +} +``` + +```typescript +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +// Query +const users = await prisma.user.findMany({ + where: { active: true } +}); + +// Insert +await prisma.user.create({ + data: { name: 'Alice', email: 'alice@example.com' } +}); + +// Update +await prisma.user.update({ + where: { id: 1 }, + data: { name: 'Bob' } +}); +``` + +## Using TypeORM + +```bash +npm install typeorm reflect-metadata pg +``` + +```typescript +import { DataSource } from 'typeorm'; +import { User } from './entities/User'; + +const dataSource = new DataSource({ + type: 'postgres', + url: process.env.DATABASE_URL, + entities: [User], + synchronize: false, // Use migrations in production +}); + +await dataSource.initialize(); + +// Query +const users = await dataSource.getRepository(User).find({ + where: { active: true } +}); + +// Insert +await dataSource.getRepository(User).save({ + name: 'Alice', + email: 'alice@example.com' +}); +``` + +## Multiple Databases + +When accessing multiple databases, each has a unique environment variable: + +```yaml title="suga.yaml" +databases: + users: + access: + api: [query] + env_var_key: USERS_DATABASE_URL + + products: + access: + api: [query] + env_var_key: PRODUCTS_DATABASE_URL +``` + +```typescript +import { Pool } from 'pg'; + +const usersPool = new Pool({ + connectionString: process.env.USERS_DATABASE_URL +}); + +const productsPool = new Pool({ + connectionString: process.env.PRODUCTS_DATABASE_URL +}); + +// Query different databases +const users = await usersPool.query('SELECT * FROM users'); +const products = await productsPool.query('SELECT * FROM products'); +``` + +## Connection Pooling + +Always use connection pooling for better performance: + +```typescript +import { Pool } from 'pg'; + +// Create pool once +const pool = new Pool({ + connectionString: process.env.DATABASE_URL, + max: 20, // Maximum connections + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 2000, +}); + +// Reuse the pool throughout your application +export default pool; +``` + +## Learn More + + + + Learn about database setup + + + + Manage schema changes + + diff --git a/docs/sdks/python/client.mdx b/docs/sdks/python/client.mdx new file mode 100644 index 00000000..c2e9ec73 --- /dev/null +++ b/docs/sdks/python/client.mdx @@ -0,0 +1,39 @@ +--- +title: "Suga Client (Python)" +description: "SugaClient initialization and configuration for Python" +--- + +Initialize and configure the Suga client in Python applications. + +## Installation + +Generated client is part of your project after running: + +```bash +suga generate --python --python-out ./suga_gen +``` + +## Basic Usage + +```python +from suga.client import SugaClient + +# Initialize client +suga = SugaClient() + +# Access resources +suga.uploads.write('file.txt', b'data') +data = suga.uploads.read('file.txt') +``` + +## Learn More + + + + Bucket operations + + + + Database operations + + diff --git a/docs/sdks/python/databases.mdx b/docs/sdks/python/databases.mdx new file mode 100644 index 00000000..f46dc313 --- /dev/null +++ b/docs/sdks/python/databases.mdx @@ -0,0 +1,189 @@ +--- +title: "Databases" +description: "Accessing PostgreSQL databases from Python applications" +--- + +Access PostgreSQL databases from Python applications using standard PostgreSQL libraries with automatically injected connection strings. + +## Connection String Injection + +Suga automatically injects database connection strings as environment variables for services with database access: + +```yaml title="suga.yaml" +databases: + main: + subtype: neon + access: + api: [query] + env_var_key: DATABASE_URL +``` + +The `api` service automatically receives `DATABASE_URL` containing the full connection string. + +## Using psycopg2 + +```bash +pip install psycopg2-binary +``` + +```python +import psycopg2 +import os + +# Connection string automatically injected by Suga +conn = psycopg2.connect(os.environ['DATABASE_URL']) +cursor = conn.cursor() + +# Query with parameters +cursor.execute('SELECT * FROM users WHERE active = %s', [True]) +users = cursor.fetchall() + +# Insert data +cursor.execute( + 'INSERT INTO users (name, email) VALUES (%s, %s)', + ['Alice', 'alice@example.com'] +) +conn.commit() + +# Update data +cursor.execute( + 'UPDATE users SET name = %s WHERE id = %s', + ['Bob', 1] +) +conn.commit() + +# Delete data +cursor.execute('DELETE FROM users WHERE id = %s', [1]) +conn.commit() + +cursor.close() +conn.close() +``` + +## Using SQLAlchemy ORM + +```bash +pip install sqlalchemy psycopg2-binary +``` + +```python +from sqlalchemy import create_engine, Column, Integer, String, Boolean +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +import os + +# Connection string automatically injected by Suga +engine = create_engine(os.environ['DATABASE_URL']) +Base = declarative_base() + +class User(Base): + __tablename__ = 'users' + id = Column(Integer, primary_key=True) + name = Column(String) + email = Column(String, unique=True) + active = Column(Boolean, default=True) + +Session = sessionmaker(bind=engine) +session = Session() + +# Query +users = session.query(User).filter(User.active == True).all() + +# Insert +user = User(name='Alice', email='alice@example.com') +session.add(user) +session.commit() + +# Update +user = session.query(User).filter(User.id == 1).first() +user.name = 'Bob' +session.commit() +``` + +## Using Django ORM + +```python title="settings.py" +import os +import dj_database_url + +DATABASES = { + 'default': dj_database_url.config( + default=os.environ['DATABASE_URL'], + conn_max_age=600 + ) +} +``` + +```bash +pip install dj-database-url psycopg2-binary +``` + +## Multiple Databases + +When accessing multiple databases, each has a unique environment variable: + +```yaml title="suga.yaml" +databases: + users: + access: + api: [query] + env_var_key: USERS_DATABASE_URL + + products: + access: + api: [query] + env_var_key: PRODUCTS_DATABASE_URL +``` + +```python +import psycopg2 +import os + +# Connect to different databases +users_conn = psycopg2.connect(os.environ['USERS_DATABASE_URL']) +products_conn = psycopg2.connect(os.environ['PRODUCTS_DATABASE_URL']) + +# Query different databases +users_cursor = users_conn.cursor() +users_cursor.execute('SELECT * FROM users') +users = users_cursor.fetchall() + +products_cursor = products_conn.cursor() +products_cursor.execute('SELECT * FROM products') +products = products_cursor.fetchall() +``` + +## Connection Pooling + +Use connection pooling for better performance: + +```python +from psycopg2 import pool +import os + +# Create connection pool +connection_pool = pool.SimpleConnectionPool( + 1, 20, # Min and max connections + os.environ['DATABASE_URL'] +) + +# Get connection from pool +conn = connection_pool.getconn() +cursor = conn.cursor() +cursor.execute('SELECT * FROM users') + +# Return connection to pool +connection_pool.putconn(conn) +``` + +## Learn More + + + + Learn about database setup + + + + Manage schema changes + + diff --git a/docs/support.mdx b/docs/support.mdx new file mode 100644 index 00000000..44be2aaa --- /dev/null +++ b/docs/support.mdx @@ -0,0 +1,89 @@ +--- +title: "Support" +description: "Get help with Suga" +--- + +Need help with Suga? We're here to assist you. + +## Documentation + +Start with our comprehensive documentation: + + + + Get started in minutes + + + + Understand core concepts + + + + Step-by-step tutorials + + + + Common questions answered + + + +## Contact Support + +### Email Support + +For general questions, technical issues, or account help: + +**[support@addsuga.com](mailto:support@addsuga.com)** + +We typically respond within 24 hours during business days. + +### GitHub Issues + +For bug reports, feature requests, and public discussions: + +**[github.com/nitrictech/suga/issues](https://github.com/nitrictech/suga/issues)** + +Please search existing issues before creating a new one. + +## Enterprise Support + +Need dedicated support for your organization? + +Contact us about enterprise support options including: +- Priority support response times +- Dedicated Slack channel +- Architecture consulting +- Custom platform development +- Training for your team + +**Email:** [sales@addsuga.com](mailto:sales@addsuga.com) + +## Security Issues + +For security vulnerabilities, please email directly rather than opening public issues: + +**[support@addsuga.com](mailto:support@addsuga.com)** + +Subject: "SECURITY - [Brief Description]" + +## Community + +Connect with other Suga users: + +- **GitHub Discussions** - [github.com/nitrictech/suga/discussions](https://github.com/nitrictech/suga/discussions) +- **Twitter/X** - [@sugasrc](https://twitter.com/sugasrc) + +## Documentation Feedback + +Found an issue with the documentation? + +- **GitHub Issues** - Report doc problems +- **Email** - [support@addsuga.com](mailto:support@addsuga.com) + +Help us improve by being specific about what's unclear or incorrect. + +## Sales & Partnerships + +For business inquiries: + +**Email:** [sales@addsuga.com](mailto:sales@addsuga.com) diff --git a/docs/why-suga.mdx b/docs/why-suga.mdx new file mode 100644 index 00000000..eccfb4e2 --- /dev/null +++ b/docs/why-suga.mdx @@ -0,0 +1,170 @@ +--- +title: "Why Suga?" +description: "Understanding when and why to use Suga for cloud infrastructure" +--- + +Suga bridges the gap between developer productivity and enterprise control. It combines visual infrastructure design with platform-driven governance to deliver fast, production-ready deployments while maintaining complete flexibility and control. + +## What Makes Suga Different? + +Suga takes a unique approach to cloud infrastructure by combining three key capabilities: + +**Visual Design with Code Generation** +- Design your architecture visually in an intuitive editor +- Generate production-ready Terraform automatically +- Maintain full control over the generated infrastructure + +**Platform-Driven Governance** +- Platform teams define reusable blueprints and standards +- Developers get guardrails, not blockers +- Organizations enforce policies while enabling velocity + +### Visual Design + Generated Infrastructure + +Design your architecture visually, then generate production-ready Terraform. No more choosing between developer experience and infrastructure control. + + + +```yaml title="Design becomes configuration" +services: + api: + dev: + script: npm run dev + +buckets: + uploads: + access: + api: [read, write] + +entrypoints: + web: + routes: + /api/: api +``` + +```bash title="Configuration becomes Terraform" +suga build +# ✓ Terraform generated successfully +# output written to terraform/stacks/my-app +``` + +### Platform-Driven Governance + +Platform teams create reusable blueprints that enforce organizational standards while delivering seamless developer experiences. + +**For Developers:** +- Visual infrastructure design +- Local development with emulated cloud services +- Deploy anywhere without changing code +- Type-safe client libraries + +**For Platform Teams:** +- Enforce security policies and compliance +- Control cloud resource configurations +- Standardize architectures across teams +- Audit and govern all deployments + +### True Multi-Cloud + +Not just provider-agnostic abstractions - Suga generates native Terraform for each cloud provider while keeping your application code portable. + +```yaml title="Same application, different clouds" +# Deploy to AWS +target: suga/aws@1 + +# Or deploy to GCP +target: suga/gcp@1 +``` + +The generated Terraform uses native cloud resources (Lambda, Cloud Run, S3, Cloud Storage) with proper networking, IAM, and security configurations. + +## How is Suga Different? + +### vs. Developer Platforms + +Suga provides a similar developer experience to hosted platforms while giving you complete control over the generated infrastructure. + +| Aspect | Hosted Platforms | Suga | +|--------|-----------------|------| +| **Deployment Speed** | Instant | Instant (after first Terraform apply) | +| **Infrastructure Control** | Platform-managed | Complete (generated Terraform) | +| **Cloud Provider** | Platform-specific | Multi-cloud (AWS, GCP, Azure, custom) | +| **Customization** | Platform-limited | Full platform customization | +| **Local Development** | Platform-dependent | Full local emulation | +| **Cost Model** | Platform pricing | Direct cloud provider rates | +| **Governance** | Platform-dictated | Organization-controlled | + +**Use Suga if:** You want great developer experience but need full control, multi-cloud support, or enterprise governance. + +### vs. Infrastructure as Code (Terraform/Pulumi) + +Suga builds on top of IaC tools rather than replacing them. It generates standard Terraform that you can inspect, modify, and manage with your existing workflows. + +| Aspect | Direct Terraform/Pulumi | Suga | +|--------|------------------------|------| +| **Approach** | Write infrastructure code | Generate from high-level design | +| **Visual Design** | External tools | Built-in visual editor | +| **Local Development** | Manual setup | `suga dev` | +| **Reusability** | Modules (per-project) | Platforms (organization-wide) | +| **Standardization** | Code reviews & guidelines | Platform-enforced patterns | +| **Flexibility** | Complete control | Extensible platforms + direct Terraform access | + +**Use Suga if:** You want to maximize reuse across teams, enforce organizational standards, or accelerate delivery with visual design while keeping Terraform's flexibility. + +**Use Suga with Terraform if:** You need both platform standardization and custom infrastructure - Suga generates Terraform you can augment with custom resources. + +### vs. Nitric (Suga's Inspiration) + +Suga is built by the team behind [Nitric](https://nitric.io) and incorporates lessons from years of cloud framework development. + +| Aspect | Nitric | Suga | +|--------|--------|------| +| **Approach** | Code-first | Configuration-first | +| **Infrastructure Definition** | Application code annotations | Separate `suga.yaml` + visual editor | +| **Deployment** | Pulumi or Terraform | Terraform | +| **Visual Design** | None | Core feature | +| **Platform System** | Provider plugins | Distributed platform packages | +| **Target Audience** | Developer-focused | Multi-role teams (platform engineers, SREs, DevOps, developers) | + +**Use Suga if:** You work in organizations with multiple roles (platform teams, SREs, DevOps, developers) who need specialized tooling for their responsibilities. + +**Use Nitric if:** You're a developer team that prefers defining infrastructure directly in application code. + +## When to Use Suga + +### ✅ Ideal Use Cases + +**Enterprise Development Teams** +- Need developer velocity without sacrificing governance +- Want to standardize infrastructure across multiple teams +- Require audit trails and compliance controls + +**Multi-Cloud Strategies** +- Building portable applications across clouds +- Avoiding vendor lock-in +- Testing different cloud providers + +**Platform Engineering** +- Creating internal developer platforms +- Enforcing organizational standards +- Providing self-service infrastructure + +**Greenfield Projects** +- Starting new applications with best practices +- Want rapid iteration with production-ready infrastructure +- Need local development that matches production + +## Getting Started + +Ready to try Suga? Start with our [Quickstart Guide](/quickstart) to deploy your first application in minutes. + +Want to understand how Suga works? Explore the [Foundations](/foundations/overview) section to learn about projects, platforms, and infrastructure generation. + +Building an internal platform? Check out the [Platform Development Guide](/guides/build-platform) to create custom platforms for your organization. + + + **Need help deciding?** Contact [support@addsuga.com](mailto:support@addsuga.com) to discuss your use case and whether Suga is a good fit. + From 9d8c550546b19a561e1f071ed9a2756248577398 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Wed, 12 Nov 2025 09:51:50 +1100 Subject: [PATCH 02/16] chore: move 'foundations' to 'core concepts' --- docs/{foundations => core}/deployment.mdx | 4 +-- .../infrastructure-generation.mdx | 2 +- .../local-development.mdx | 4 +-- docs/{foundations => core}/overview.mdx | 24 ++++++++-------- docs/{foundations => core}/platforms.mdx | 4 +-- docs/{foundations => core}/plugins.mdx | 2 +- docs/{foundations => core}/projects.mdx | 2 +- docs/deploy/aws.mdx | 2 +- docs/deploy/gcp.mdx | 2 +- docs/deploy/overview.mdx | 4 +-- docs/develop/access-control.mdx | 2 +- docs/develop/buckets.mdx | 4 +-- docs/develop/databases.mdx | 4 +-- docs/develop/entrypoints.mdx | 2 +- docs/develop/overview.mdx | 2 +- docs/develop/services.mdx | 2 +- docs/develop/suga-client.mdx | 2 +- docs/docs.json | 21 +++++++------- docs/faq.mdx | 2 +- docs/guides/build-platform.mdx | 28 +++++++++---------- docs/guides/plugin-development.mdx | 2 +- docs/guides/static-website-hosting.mdx | 4 +-- docs/quickstart.mdx | 4 +-- docs/support.mdx | 2 +- docs/why-suga.mdx | 2 +- 25 files changed, 66 insertions(+), 67 deletions(-) rename docs/{foundations => core}/deployment.mdx (98%) rename docs/{foundations => core}/infrastructure-generation.mdx (98%) rename docs/{foundations => core}/local-development.mdx (98%) rename docs/{foundations => core}/overview.mdx (87%) rename docs/{foundations => core}/platforms.mdx (96%) rename docs/{foundations => core}/plugins.mdx (98%) rename docs/{foundations => core}/projects.mdx (97%) diff --git a/docs/foundations/deployment.mdx b/docs/core/deployment.mdx similarity index 98% rename from docs/foundations/deployment.mdx rename to docs/core/deployment.mdx index 663439b5..c7e415f5 100644 --- a/docs/foundations/deployment.mdx +++ b/docs/core/deployment.mdx @@ -394,7 +394,7 @@ terraform plan ## Learn More - + Understand how Terraform is generated @@ -406,7 +406,7 @@ terraform plan Best practices for Terraform configuration - + How to develop applications locally with Suga diff --git a/docs/foundations/infrastructure-generation.mdx b/docs/core/infrastructure-generation.mdx similarity index 98% rename from docs/foundations/infrastructure-generation.mdx rename to docs/core/infrastructure-generation.mdx index cb5848e8..782a96b4 100644 --- a/docs/foundations/infrastructure-generation.mdx +++ b/docs/core/infrastructure-generation.mdx @@ -180,7 +180,7 @@ terraform plan # Review before apply ## Learn More - + Understand the deployment process diff --git a/docs/foundations/local-development.mdx b/docs/core/local-development.mdx similarity index 98% rename from docs/foundations/local-development.mdx rename to docs/core/local-development.mdx index 318ce1c3..d3fb72a3 100644 --- a/docs/foundations/local-development.mdx +++ b/docs/core/local-development.mdx @@ -324,7 +324,7 @@ For features that can't be emulated: 2. **Mock externals** - Use mocks for cloud-specific APIs 3. **Integration tests** - Test cloud features in CI/CD pipelines - + Learn how to deploy to cloud environments for testing @@ -343,7 +343,7 @@ For features that can't be emulated: Configure databases and connection strings - + Deploy to cloud after local testing diff --git a/docs/foundations/overview.mdx b/docs/core/overview.mdx similarity index 87% rename from docs/foundations/overview.mdx rename to docs/core/overview.mdx index 76b3a50b..7d9893e0 100644 --- a/docs/foundations/overview.mdx +++ b/docs/core/overview.mdx @@ -1,9 +1,9 @@ --- -title: "Foundations Overview" +title: "Core Concepts Overview" description: "Understanding Suga's architecture and core concepts" --- -Suga is built on a clear separation of concerns that enables both developer productivity and platform governance. Understanding these foundations will help you make the most of the platform. +Suga is built on a clear separation of concerns that enables both developer productivity and platform governance. Understanding these core concepts will help you make the most of the platform. ## The Suga Architecture @@ -23,7 +23,7 @@ graph TB ### 1. Projects: What You Want -[Projects](/foundations/projects) are your application specifications - declarative YAML files that describe what your application needs: +[Projects](/core/projects) are your application specifications - declarative YAML files that describe what your application needs: - **Services** - Application containers that run your code - **Buckets** - Cloud storage for files and assets @@ -54,7 +54,7 @@ entrypoints: ### 2. Platforms: How to Build It -[Platforms](/foundations/platforms) are blueprints that map your project's abstract resources to specific cloud implementations. They define: +[Platforms](/core/platforms) are blueprints that map your project's abstract resources to specific cloud implementations. They define: - Which cloud services to use (Lambda vs Fargate, S3 vs Cloud Storage) - How to configure those services (memory, CPU, networking) @@ -65,7 +65,7 @@ Platform teams create and publish platforms to enforce organizational standards ### 3. Plugins: Cloud Resources -[Plugins](/foundations/plugins) are the lowest-level building blocks - reusable Terraform modules that provision specific cloud resources. Each plugin contains: +[Plugins](/core/plugins) are the lowest-level building blocks - reusable Terraform modules that provision specific cloud resources. Each plugin contains: - **Terraform module** - Infrastructure-as-code for a specific cloud service - **Input schema** - Configuration properties the module accepts @@ -263,30 +263,30 @@ Enable teams to work independently while maintaining consistency: ## Next Steps -Now that you understand Suga's foundations, dive deeper into each component: +Now that you understand Suga's core concepts, dive deeper into each component: - + Learn how to define application requirements - + Understand platform blueprints and governance - + Explore the building blocks of infrastructure - + See how Suga transforms projects into Terraform - + Master local development workflow - + Understand deployment and operations diff --git a/docs/foundations/platforms.mdx b/docs/core/platforms.mdx similarity index 96% rename from docs/foundations/platforms.mdx rename to docs/core/platforms.mdx index 14111685..4b0f5510 100644 --- a/docs/foundations/platforms.mdx +++ b/docs/core/platforms.mdx @@ -3,7 +3,7 @@ title: "Platforms" description: "Understanding Suga's platforms and ecosystem" --- -Platforms in Suga solve a critical challenge: delivering the seamless developer experience of modern deployment platforms while maintaining enterprise control and flexibility. They're blueprints that transform application specifications ([Projects](/foundations/projects)) into deployable infrastructure by generating Terraform HCL and providing runtime adapters that translate abstract resource operations into cloud-specific API calls. +Platforms in Suga solve a critical challenge: delivering the seamless developer experience of modern deployment platforms while maintaining enterprise control and flexibility. They're blueprints that transform application specifications ([Projects](/core/projects)) into deployable infrastructure by generating Terraform HCL and providing runtime adapters that translate abstract resource operations into cloud-specific API calls. Platform teams can create, customize, and govern these distributed packages to provide developers with instant deployments, automatic scaling, and zero-configuration infrastructure, while maintaining full control over security, compliance, and infrastructure standards. @@ -68,7 +68,7 @@ Platforms operate through two key mechanisms: **Infrastructure Generation** and ### Infrastructure Generation -When you run `suga build`, Suga uses your target platform to transform your [Project](/foundations/projects) specification into cloud-specific Terraform HCL (called stacks). This process: +When you run `suga build`, Suga uses your target platform to transform your [Project](/core/projects) specification into cloud-specific Terraform HCL (called stacks). This process: 1. **Maps abstract resources** - Takes your high-level resource definitions (services, buckets, databases) and selects appropriate cloud implementations 2. **Generates Terraform modules** - Creates infrastructure-as-code that provisions actual cloud resources with proper networking, security, and permissions diff --git a/docs/foundations/plugins.mdx b/docs/core/plugins.mdx similarity index 98% rename from docs/foundations/plugins.mdx rename to docs/core/plugins.mdx index 49abc452..2fb8d615 100644 --- a/docs/foundations/plugins.mdx +++ b/docs/core/plugins.mdx @@ -269,7 +269,7 @@ Organizations can create custom plugins for: Create custom plugins for your needs - + See how plugins generate Terraform diff --git a/docs/foundations/projects.mdx b/docs/core/projects.mdx similarity index 97% rename from docs/foundations/projects.mdx rename to docs/core/projects.mdx index 8b09af98..f6390938 100644 --- a/docs/foundations/projects.mdx +++ b/docs/core/projects.mdx @@ -7,7 +7,7 @@ Projects in Suga are application specifications that define your cloud architect ## What is a Project? -A Suga project is defined by a `suga.yaml` file that describes your application's infrastructure requirements using cloud-agnostic resource types. When combined with a [Platform](/foundations/platforms), this specification gets transformed into deployable cloud infrastructure. +A Suga project is defined by a `suga.yaml` file that describes your application's infrastructure requirements using cloud-agnostic resource types. When combined with a [Platform](/core/platforms), this specification gets transformed into deployable cloud infrastructure. diff --git a/docs/deploy/aws.mdx b/docs/deploy/aws.mdx index 991fc83e..466bec0d 100644 --- a/docs/deploy/aws.mdx +++ b/docs/deploy/aws.mdx @@ -36,6 +36,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/gcp.mdx b/docs/deploy/gcp.mdx index c294a3f3..e8dfec4e 100644 --- a/docs/deploy/gcp.mdx +++ b/docs/deploy/gcp.mdx @@ -35,6 +35,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/overview.mdx b/docs/deploy/overview.mdx index 6d855c14..23d32bfd 100644 --- a/docs/deploy/overview.mdx +++ b/docs/deploy/overview.mdx @@ -5,8 +5,8 @@ description: "Overview of deploying Suga applications to cloud providers" Deploying with Suga means running standard Terraform commands on infrastructure generated by `suga build`. - - See the comprehensive deployment guide in Foundations + + See the comprehensive deployment guide in Core Concepts ## Quick Links diff --git a/docs/develop/access-control.mdx b/docs/develop/access-control.mdx index a7105b98..85fd9178 100644 --- a/docs/develop/access-control.mdx +++ b/docs/develop/access-control.mdx @@ -86,7 +86,7 @@ When using the standard Suga AWS Platforms (`suga/aws`), here is an example of t ``` - If you use your own Suga [resource plugins](/foundations/plugins), you're free to construct the IAM, roles, etc. as you see fit. + If you use your own Suga [resource plugins](/core/plugins), you're free to construct the IAM, roles, etc. as you see fit. ## Best Practices diff --git a/docs/develop/buckets.mdx b/docs/develop/buckets.mdx index 7855cecb..2004a339 100644 --- a/docs/develop/buckets.mdx +++ b/docs/develop/buckets.mdx @@ -139,7 +139,7 @@ You can: - Seed buckets by placing files there - Test bucket operations without cloud access - + Learn how to develop applications locally with Suga @@ -158,7 +158,7 @@ You can: Deploy static websites - + Test buckets locally diff --git a/docs/develop/databases.mdx b/docs/develop/databases.mdx index 2a72ef51..d0d7c24a 100644 --- a/docs/develop/databases.mdx +++ b/docs/develop/databases.mdx @@ -255,7 +255,7 @@ suga dev Your services receive `DATABASE_URL` (or your custom `env_var_key`) automatically, making the same code work in both local development and production. - + Learn more about local development with databases @@ -270,7 +270,7 @@ Your services receive `DATABASE_URL` (or your custom `env_var_key`) automaticall Schema management - + Local PostgreSQL during suga dev diff --git a/docs/develop/entrypoints.mdx b/docs/develop/entrypoints.mdx index 600f07a1..38477824 100644 --- a/docs/develop/entrypoints.mdx +++ b/docs/develop/entrypoints.mdx @@ -43,7 +43,7 @@ Routes are evaluated in order - most specific first. ## Custom Domains - Most entrypoints support custom domains, however, this functionality is [platform](/foundations/platforms.mdx) specific. + Most entrypoints support custom domains, however, this functionality is [platform](/core/platforms.mdx) specific. For example, the `suga/aws` platform will generate Terraform Variables during `suga build`, which allow you to specify a custom domain per entrypoint. diff --git a/docs/develop/overview.mdx b/docs/develop/overview.mdx index 40d03da4..16fd290f 100644 --- a/docs/develop/overview.mdx +++ b/docs/develop/overview.mdx @@ -129,7 +129,7 @@ entrypoints: subtype: cloudfront # AWS CloudFront ``` -The available subtypes depend on your target [platform](/foundations/platforms): +The available subtypes depend on your target [platform](/core/platforms): - `suga/aws@1` - Lambda, Fargate, S3, CloudFront - `suga/gcp@1` - Cloud Run, Cloud Storage, Cloud CDN - `you/custom@1` - Any other cloud or resources you like, including cross-cloud deployments diff --git a/docs/develop/services.mdx b/docs/develop/services.mdx index f8ae66dd..00e33f15 100644 --- a/docs/develop/services.mdx +++ b/docs/develop/services.mdx @@ -211,7 +211,7 @@ Services interact with resources like buckets using generated Suga client librar Grant resource access - + Test services locally diff --git a/docs/develop/suga-client.mdx b/docs/develop/suga-client.mdx index 12ba74a6..02b36d16 100644 --- a/docs/develop/suga-client.mdx +++ b/docs/develop/suga-client.mdx @@ -236,7 +236,7 @@ You can mix both approaches - use Suga clients for common operations and native Complete API documentation - + Learn about local development workflow diff --git a/docs/docs.json b/docs/docs.json index 2fba9291..9a2ca30f 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -22,15 +22,15 @@ "pages": ["introduction", "why-suga", "installation", "quickstart"] }, { - "group": "Foundations", + "group": "Core Concepts", "pages": [ - "foundations/overview", - "foundations/projects", - "foundations/platforms", - "foundations/plugins", - "foundations/infrastructure-generation", - "foundations/local-development", - "foundations/deployment" + "core/overview", + "core/projects", + "core/platforms", + "core/plugins", + "core/infrastructure-generation", + "core/local-development", + "core/deployment" ] }, { @@ -42,7 +42,6 @@ "develop/buckets", "develop/databases", "develop/suga-client", - "develop/environment-variables", "develop/access-control" ] }, @@ -211,11 +210,11 @@ "redirects": [ { "source": "/projects", - "destination": "/foundations/projects" + "destination": "/core/projects" }, { "source": "/platforms", - "destination": "/foundations/platforms" + "destination": "/core/platforms" } ] } diff --git a/docs/faq.mdx b/docs/faq.mdx index 6aa37559..d5ee8a94 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -113,7 +113,7 @@ Yes! Suga works with Express, FastAPI, Django, Go HTTP, and any other framework ### How do I debug services locally? -Use your language's standard debugger with `suga dev`. See the [Local Development](/foundations/local-development) guide. +Use your language's standard debugger with `suga dev`. See the [Local Development](/core/local-development) guide. ### Can services communicate with each other? diff --git a/docs/guides/build-platform.mdx b/docs/guides/build-platform.mdx index a7e44b71..7c225572 100644 --- a/docs/guides/build-platform.mdx +++ b/docs/guides/build-platform.mdx @@ -3,14 +3,14 @@ title: "Platform Development Guide" description: "Learn to build platforms with Suga through a hands-on example." --- -Platforms can start simple and evolve as your needs grow. This guide walks through building a single platform that supports multiple deployment strategies using standard [plugin](/foundations/platforms#plugins) libraries provided by the Suga team, which include plugins for Lambda, Fargate, CloudFront, S3, VPC, and Neon databases. +Platforms can start simple and evolve as your needs grow. This guide walks through building a single platform that supports multiple deployment strategies using standard [plugin](/core/platforms#plugins) libraries provided by the Suga team, which include plugins for Lambda, Fargate, CloudFront, S3, VPC, and Neon databases. **Phase 1: Serverless Platform** - Build a minimal platform with Lambda functions, databases, storage, and CDN. **Phase 2: Add Stateful Services** - Extend the same platform to support containers running on Amazon ECS Fargate, alongside Lambda by adding VPC infrastructure, load balancers, and security groups. - **New to Suga platforms?** See the [Platforms Overview](/foundations/platforms) to understand how platforms work and why they're useful. Don't want to manage platforms? Use Suga's default platforms and jump to the [Quickstart](/quickstart). + **New to Suga platforms?** See the [Platforms Overview](/core/platforms) to understand how platforms work and why they're useful. Don't want to manage platforms? Use Suga's default platforms and jump to the [Quickstart](/quickstart). ## Phase 1: Build Serverless Platform @@ -43,8 +43,8 @@ Fill out the platform details and click **"Create Platform"**: The platform editor has two sections: -- **[Foundations](/foundations/platforms#variables)** - Common infrastructure shared by other resources (VPCs, load balancers) and common variables for platform configuration -- **[Resource Blueprints](/foundations/platforms#resource-blueprints)** - Templates that define how to provision application specific resources, such as services, databases, buckets, and entrypoints +- **[Core Concepts](/core/platforms#variables)** - Common infrastructure shared by other resources (VPCs, load balancers) and common variables for platform configuration +- **[Resource Blueprints](/core/platforms#resource-blueprints)** - Templates that define how to provision application specific resources, such as services, databases, buckets, and entrypoints ![Edit Platform Dialog](/images/build-platform/edit-platform.png) @@ -102,7 +102,7 @@ This blueprint maps an application's databases to Neon PostgreSQL with automatic Expand **Database Blueprints** in Resource Blueprints. -Add platform variable in **Foundations** to specify which Neon project to create databases in: +Add platform variable in **Core Concepts** to specify which Neon project to create databases in: ```yaml neon_project_id: type: string @@ -129,7 +129,7 @@ branch_id: ${self.neon_branch_id} Suga uses three types of references in platform configurations: - - `${var.name}` - References platform variables from Foundations + - `${var.name}` - References platform variables from Core Concepts - `${self.name}` - References resource-specific variables defined in the same resource blueprint - `${infra.name.output}` - References outputs from infrastructure components (you'll see this in Phase 2) @@ -148,7 +148,7 @@ Click "Commit Revision" in the platform editor, add a descriptive commit message ### Test with an Application -Create an [application](/foundations/projects) from the project editor and design your application architecture using the platform you just created. +Create an [application](/core/projects) from the project editor and design your application architecture using the platform you just created. Not familiar with building applications with Suga? Start with the [Quickstart guide](/quickstart). @@ -172,7 +172,7 @@ This architecture shows CloudFront routing to an Application Load Balancer, whic To extend the platform with stateful services, the platform will need the following infrastructure and blueprints: -**Shared Infrastructure (Foundations)**: +**Shared Infrastructure (Core Concepts)**: - **VPC** - Private network for Fargate containers - **Security Group Rules** - Firewall rules for container traffic - **Load Balancer** - Internal ALB for routing to Fargate containers @@ -188,7 +188,7 @@ To extend the platform with stateful services, the platform will need the follow This shared infrastructure configures the VPC network foundation with isolated subnets, NAT gateways, and routing for stateful containers. Unlike serverless Lambda functions, Fargate containers require a private network to run securely. -In the **Foundations** section, expand **Infrastructure**. +In the **Core Concepts** section, expand **Infrastructure**. Add the `vpc` plugin and apply the following configuration: ```yaml @@ -214,7 +214,7 @@ single_nat_gateway: ${self.single_nat_gateway} These platform variables configure the network ports for container communication. The `container_port` defines where containers listen for traffic, while `lb_listener_port` defines where the load balancer accepts incoming requests. -Add platform variables in **Foundations**: +Add platform variables in **Core Concepts**: ```yaml container_port: @@ -234,7 +234,7 @@ lb_listener_port: This shared infrastructure configures firewall rules for container network traffic: outbound internet access, health check access, and CDN-only ingress. These rules ensure containers can communicate with external services while blocking unauthorized access. -In the **Foundations** section, expand **Infrastructure**. +In the **Core Concepts** section, expand **Infrastructure**. **Outbound Internet Access** @@ -308,7 +308,7 @@ security_group_ids: ["${infra.aws_vpc.default_security_group_id}"] This shared infrastructure configures an internal Application Load Balancer to route traffic and perform health checks for containers. The load balancer distributes incoming requests across container instances and removes unhealthy containers from rotation. -In the **Foundations** section, expand **Infrastructure**. +In the **Core Concepts** section, expand **Infrastructure**. Add the `loadbalancer` plugin and apply the following configuration: @@ -388,7 +388,7 @@ This enables different services within the same application to use different arc If you see errors about missing infrastructure references: - Verify plugin names match exactly (e.g., `${infra.aws_vpc}` requires a plugin named `aws_vpc`) - Check that dependencies are declared before using outputs -- Ensure infrastructure components are in the Foundations section, not Resource Blueprints +- Ensure infrastructure components are in the Core Concepts section, not Resource Blueprints **Platform won't commit** @@ -406,7 +406,7 @@ If building an application produces Terraform errors: ## Next Steps -- **Test with a real application**: Create an [application](/foundations/projects) using this platform, [build the Terraform](/cli/build), and deploy to AWS to verify everything works end-to-end +- **Test with a real application**: Create an [application](/core/projects) using this platform, [build the Terraform](/cli/build), and deploy to AWS to verify everything works end-to-end - **Share with your team**: Make the platform available to your team so they can start building applications - **Create environment variants**: Duplicate your platform with environment-specific variables (e.g., smaller instances for dev, larger for prod) diff --git a/docs/guides/plugin-development.mdx b/docs/guides/plugin-development.mdx index ac428cea..9c1edc81 100644 --- a/docs/guides/plugin-development.mdx +++ b/docs/guides/plugin-development.mdx @@ -813,7 +813,7 @@ This is particularly valuable when writing runtime adapters if you're more famil - [Platform Development Guide](/guides/build-platform) - Learn how platforms compose plugins - [Suga MCP Integration](/guides/mcp-integration) - Use AI agents to help build plugins -- [Platforms Overview](/foundations/platforms) - Understand how plugins fit into the architecture +- [Platforms Overview](/core/platforms) - Understand how plugins fit into the architecture - [Suga CLI Reference](/cli) - Complete CLI documentation diff --git a/docs/guides/static-website-hosting.mdx b/docs/guides/static-website-hosting.mdx index ab3ac8af..37b30b16 100644 --- a/docs/guides/static-website-hosting.mdx +++ b/docs/guides/static-website-hosting.mdx @@ -310,7 +310,7 @@ npm run dev # Usually runs on :3000 or :5173 During development, use your framework's dev server (with hot reload) rather than the production build. - + Learn more about local development workflow @@ -325,7 +325,7 @@ During development, use your framework's dev server (with hot reload) rather tha HTTP routing and CDN - + Deployment workflow diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 85dff0e6..450d1aaf 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -375,8 +375,8 @@ If you make changes to your application in the future, you can re-run `suga buil Now that you know how to use Suga to develop and deploy cloud applications, consider some of these docs to continue learning about Suga: -- [Projects overview](/foundations/projects) -- [Platforms overview](/foundations/platforms) +- [Projects overview](/core/projects) +- [Platforms overview](/core/platforms) - [Add Suga to an existing application](/guides/add-suga) diff --git a/docs/support.mdx b/docs/support.mdx index 44be2aaa..8620c672 100644 --- a/docs/support.mdx +++ b/docs/support.mdx @@ -14,7 +14,7 @@ Start with our comprehensive documentation: Get started in minutes - + Understand core concepts diff --git a/docs/why-suga.mdx b/docs/why-suga.mdx index eccfb4e2..d2e4a578 100644 --- a/docs/why-suga.mdx +++ b/docs/why-suga.mdx @@ -161,7 +161,7 @@ Suga is built by the team behind [Nitric](https://nitric.io) and incorporates le Ready to try Suga? Start with our [Quickstart Guide](/quickstart) to deploy your first application in minutes. -Want to understand how Suga works? Explore the [Foundations](/foundations/overview) section to learn about projects, platforms, and infrastructure generation. +Want to understand how Suga works? Explore the [Core Concepts](/core/overview) section to learn about projects, platforms, and infrastructure generation. Building an internal platform? Check out the [Platform Development Guide](/guides/build-platform) to create custom platforms for your organization. From 2e53e55cf94dd93073ccab1661e7190ec8bad34b Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Wed, 12 Nov 2025 09:59:22 +1100 Subject: [PATCH 03/16] chore: improve diagram text contrast --- docs/core/overview.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index 7d9893e0..c2b2a813 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -15,10 +15,10 @@ graph TB D --> B[Plugins
Cloud resources] B --> C[Terraform
Deployed infrastructure] - style A fill:#2BC65F - style D fill:#25B355 - style B fill:#1E9A47 - style C fill:#178A3D + style A fill:#2BC65F,stroke:#1E9A47,stroke-width:2px,color:#fff,font-weight:500 + style D fill:#25B355,stroke:#1E9A47,stroke-width:2px,color:#fff,font-weight:500 + style B fill:#1E9A47,stroke:#178A3D,stroke-width:2px,color:#fff,font-weight:500 + style C fill:#178A3D,stroke:#125E2F,stroke-width:2px,color:#fff,font-weight:500 ``` ### 1. Projects: What You Want From ba13f51c7ae226877323f9805d25d3276d0f836c Mon Sep 17 00:00:00 2001 From: Ryan Cartwright Date: Wed, 12 Nov 2025 16:41:15 +1100 Subject: [PATCH 04/16] chore: fix escaped quotes on storage prefix param python --- docs/sdks/python/storage.mdx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/sdks/python/storage.mdx b/docs/sdks/python/storage.mdx index 84324000..8fd62332 100644 --- a/docs/sdks/python/storage.mdx +++ b/docs/sdks/python/storage.mdx @@ -86,7 +86,7 @@ def list(prefix: str = "") -> List[str] #### Parameters - + Filter results to keys starting with this prefix @@ -148,7 +148,11 @@ def get_upload_url(key: str, options: Optional[PresignUrlOptions] = None) -> str The key/path of the file - + Configuration with expiry in seconds @@ -167,4 +171,4 @@ download_url = client.image.get_download_url("file.txt") # Upload URL with custom expiry (1 hour) upload_url = client.image.get_upload_url("file.txt", PresignUrlOptions(expiry=3600)) -``` \ No newline at end of file +``` From c555f3faff83bbd4bf39dbd8deb6846043a1be62 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Wed, 12 Nov 2025 18:54:38 +1100 Subject: [PATCH 05/16] chore: edits from code review Co-authored-by: Ryan Cartwright <39504851+HomelessDinosaur@users.noreply.github.com> Co-authored-by: David Moore <4121492+davemooreuws@users.noreply.github.com> --- docs/core/infrastructure-generation.mdx | 8 ++--- docs/core/local-development.mdx | 20 ++++++++----- docs/core/overview.mdx | 3 +- docs/core/plugins.mdx | 4 +-- docs/deploy/environment-management.mdx | 2 +- docs/develop/access-control.mdx | 11 ++++--- docs/develop/buckets.mdx | 8 ++--- docs/develop/databases.mdx | 27 +++++++++-------- docs/develop/entrypoints.mdx | 40 +++++++++++++++---------- docs/develop/overview.mdx | 4 +-- docs/develop/services.mdx | 2 ++ docs/develop/suga-client.mdx | 2 +- docs/guides/static-website-hosting.mdx | 31 +++++++++++-------- docs/why-suga.mdx | 2 +- 14 files changed, 94 insertions(+), 70 deletions(-) diff --git a/docs/core/infrastructure-generation.mdx b/docs/core/infrastructure-generation.mdx index 782a96b4..982b7702 100644 --- a/docs/core/infrastructure-generation.mdx +++ b/docs/core/infrastructure-generation.mdx @@ -70,7 +70,7 @@ The `suga build` command orchestrates a multi-step process: ``` terraform/stacks/my-app/ ├── cdk.tf.json # Main Terraform Entrypoint - └── .terraform/ # Plugin Terraform modules + └── .terraform/ # Plugin Terraform modules └── modules/ ├── api/ ├── api_image/ @@ -86,7 +86,7 @@ Suga generates consistent module names for application resources: ### Terraform Module Names -Pattern: `{resource_name}[_{submodule_name}]` +Pattern: `{resource_name}_{submodule_name}` ```hcl module "api" # Service named "api" @@ -140,7 +140,7 @@ The same generated Terraform can deploy to multiple environments using Terraform Learn best practices for managing multiple environments with Terraform workspaces and variables
-See the [CLI reference](/cli/build) for complete options. +See the [CLI reference](/cli/build) for complete build options. ## Getting Help @@ -185,7 +185,7 @@ terraform plan # Review before apply
- Complete CLI reference for suga build + Complete CLI reference for `suga build` diff --git a/docs/core/local-development.mdx b/docs/core/local-development.mdx index d3fb72a3..c69bea82 100644 --- a/docs/core/local-development.mdx +++ b/docs/core/local-development.mdx @@ -104,14 +104,20 @@ Local behavior: Entrypoints provide local HTTP servers with routing: ```yaml title="suga.yaml" +services: + api: ... +buckets: + frontend: ... entrypoints: web: routes: - /api/: api - /: frontend + /api/: + name: api + /: + name: frontend ``` -Results in: +Running `suga dev` will result in: ``` http://localhost:3000/api/ → Routes to 'api' service @@ -287,7 +293,7 @@ During `suga dev`: - Service receives environment variables from `env` config - Database connection strings automatically injected based on `env_var_key` - Same variables are available in production (after Terraform deployment) -- Use for configuration, API keys, feature flags +- Use for configuration, feature flags, etc. Use different values for local vs production by adding platform-specific overrides or using Terraform variables. @@ -312,9 +318,9 @@ Local emulation provides high fidelity but has some limitations: ### Performance Differences -- **Cold starts** - Lambda cold starts don't occur locally +- **Cold starts** - Service cold starts don't occur locally - **Latency** - No network latency between services -- **Resource limits** - Local resources not limited like Lambda (memory, timeout) +- **Resource limits** - Local resources not limited like a deployed service (memory, timeout) ### Workarounds @@ -336,7 +342,7 @@ For features that can't be emulated: - Complete CLI reference for suga dev + Complete CLI reference for `suga dev` diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index c2b2a813..5a61e335 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -49,7 +49,8 @@ buckets: entrypoints: web: routes: - /api/: api + /api/: + name: api ``` ### 2. Platforms: How to Build It diff --git a/docs/core/plugins.mdx b/docs/core/plugins.mdx index 2fb8d615..d8e2d039 100644 --- a/docs/core/plugins.mdx +++ b/docs/core/plugins.mdx @@ -15,7 +15,7 @@ A plugin is a package containing: ``` plugin-directory/ -├── manifest.yaml # Plugin schema and metadata +├── manifest.yaml # Plugin schema and metadata ├── main.tf # Terraform resources ├── variables.tf # Input variables ├── outputs.tf # Output values @@ -152,7 +152,7 @@ Properties can reference platform or blueprint variables: properties: memory: ${self.memory} # Blueprint variable project_id: ${var.project_id} # Platform variable - vpc_id: ${infra.aws_vpc.vpc_id} # Infrastructure output + vpc_id: ${infra.aws_vpc.vpc_id} # Infrastructure output ``` ## Plugin Outputs diff --git a/docs/deploy/environment-management.mdx b/docs/deploy/environment-management.mdx index 0caff067..5caa026b 100644 --- a/docs/deploy/environment-management.mdx +++ b/docs/deploy/environment-management.mdx @@ -3,7 +3,7 @@ title: "Environment Management" description: "Managing multiple deployment environments (dev, staging, production)" --- -Manage multiple environments using Terraform workspaces and variable files. +Manage multiple environments using [Terraform workspaces](https://developer.hashicorp.com/terraform/language/state/workspaces) and variable files. ## Using Workspaces diff --git a/docs/develop/access-control.mdx b/docs/develop/access-control.mdx index 85fd9178..dd92285b 100644 --- a/docs/develop/access-control.mdx +++ b/docs/develop/access-control.mdx @@ -12,16 +12,19 @@ Suga's access control model defines which services can access which resources, a Access is granted through the `access` property on resources, which can be modified in your project's `suga.yaml` or through the visual editor with the `suga edit` CLI command. ```yaml +services: + api: ... + worker: ... buckets: uploads: access: api: [read, write] # API service can read and write - worker: [read, delete] # Worker can read and delete + worker: [read, delete] # Worker service can read and delete databases: main: access: - api: [query] # API can query database + api: [query] # API service can query database ``` When you deploy, Suga generates: @@ -110,8 +113,4 @@ When using the standard Suga AWS Platforms (`suga/aws`), here is an example of t Database access - - - AWS IAM details - diff --git a/docs/develop/buckets.mdx b/docs/develop/buckets.mdx index 2004a339..0613a0ef 100644 --- a/docs/develop/buckets.mdx +++ b/docs/develop/buckets.mdx @@ -9,7 +9,7 @@ Buckets provide cloud object storage for your application - think files, images, A bucket is object storage that: - **Stores files** - Any file type, any size -- **Provides access** - Read, write, delete operations +- **Configurable access** - Set read, write, delete permissions - **Scales automatically** - No capacity planning needed - **Works everywhere** - Same interface locally and in production @@ -34,7 +34,7 @@ Grant services access to buckets: buckets: uploads: access: - api: [read, write, delete] # Full access + api: [read, write, delete] # Full access worker: [read, delete] # Read and delete only frontend: [read] # Read-only ``` @@ -139,8 +139,8 @@ You can: - Seed buckets by placing files there - Test bucket operations without cloud access - - Learn how to develop applications locally with Suga + + Learn how to develop buckets locally with Suga ## Learn More diff --git a/docs/develop/databases.mdx b/docs/develop/databases.mdx index d0d7c24a..7ff8a497 100644 --- a/docs/develop/databases.mdx +++ b/docs/develop/databases.mdx @@ -85,6 +85,12 @@ Access databases using standard PostgreSQL libraries with the automatically inje + Install the PostgreSQL client: + ```bash + npm install pg + ``` + + Then develop like you normally would, using the `env_var_key` you defined in your `suga.yaml`. ```typescript import { Pool } from 'pg'; @@ -112,14 +118,15 @@ Access databases using standard PostgreSQL libraries with the automatically inje ['Bob', 1] ); ``` + + Install the PostgreSQL client: ```bash - npm install pg + pip install psycopg2-binary ``` - - + Then develop like you normally would, using the `env_var_key` you defined in your `suga.yaml`. ```python import psycopg2 import os @@ -146,14 +153,15 @@ Access databases using standard PostgreSQL libraries with the automatically inje ) conn.commit() ``` + + Install the PostgreSQL client: ```bash - pip install psycopg2-binary + go get github.com/jackc/pgx/v5/pgxpool ``` - - + Then develop like you normally would, using the `env_var_key` you defined in your `suga.yaml`. ```go import ( "context" @@ -182,11 +190,6 @@ Access databases using standard PostgreSQL libraries with the automatically inje "UPDATE users SET name = $1 WHERE id = $2", "Bob", 1) ``` - - Install the PostgreSQL client: - ```bash - go get github.com/jackc/pgx/v5/pgxpool - ``` @@ -271,7 +274,7 @@ Your services receive `DATABASE_URL` (or your custom `env_var_key`) automaticall - Local PostgreSQL during suga dev + Local PostgreSQL during `suga dev` diff --git a/docs/develop/entrypoints.mdx b/docs/develop/entrypoints.mdx index 38477824..dde2070e 100644 --- a/docs/develop/entrypoints.mdx +++ b/docs/develop/entrypoints.mdx @@ -17,8 +17,10 @@ An entrypoint is a CDN + router that: entrypoints: web: routes: - /api/: api # Route /api/* to api service - /: frontend # Route /* to frontend service + /api/: + name: api # Route /api/* to api service + /: + name: frontend # Route /* to frontend service ``` ## Route Configuration @@ -29,9 +31,12 @@ Routes map URL paths to destinations: entrypoints: web: routes: - /api/: api-service # Service destination - /static/: assets # Bucket destination - /: frontend # Service destination + /api/: + name: api-service # Service destination + /static/: + name: assets # Bucket destination + /: + name: frontend # Service destination ``` **Path Matching:** @@ -55,8 +60,10 @@ Routes are evaluated in order - most specific first. entrypoints: web: routes: - /api/: api - /: frontend + /api/: + name: api + /: + name: frontend ``` **Microservices Gateway:** @@ -64,9 +71,12 @@ entrypoints: entrypoints: gateway: routes: - /users/: users-service - /products/: products-service - /orders/: orders-service + /users/: + name: users-service + /products/: + name: products-service + /orders/: + name: orders-service ``` **Static Site with API:** @@ -74,8 +84,10 @@ entrypoints: entrypoints: web: routes: - /api/: api - /: static-assets # Bucket with static files + /api/: + name: api + /: + name: static-assets # Bucket with static files ``` ## Learn More @@ -85,10 +97,6 @@ entrypoints: Static website hosting - - CloudFront configuration - - Route to static files in buckets diff --git a/docs/develop/overview.mdx b/docs/develop/overview.mdx index 16fd290f..bddef042 100644 --- a/docs/develop/overview.mdx +++ b/docs/develop/overview.mdx @@ -148,7 +148,7 @@ buckets: databases: main: access: - api: [query] # API can query the database + api: [query] # API service can query the database ``` This generates appropriate IAM policies or service account permissions. @@ -157,8 +157,6 @@ This generates appropriate IAM policies or service account permissions. Learn more about access control patterns - - ## Accessing Resources from Code Once you've defined resources in your `suga.yaml`, Suga provides generated client libraries for cloud-agnostic resource access. The same code works locally with `suga dev` and in production across any cloud provider. diff --git a/docs/develop/services.mdx b/docs/develop/services.mdx index 00e33f15..9a5d7f67 100644 --- a/docs/develop/services.mdx +++ b/docs/develop/services.mdx @@ -84,6 +84,8 @@ services: FEATURE_XYZ: "true" ``` +There are a few reserved environment variables that should be avoided. These are `PORT` and environment variables with the prefix `SUGA_`. + #### PORT environment variable In order to establish HTTP routes/requests Suga will automatically inject a `PORT` env var into each of your services, indicating which port it should start on. diff --git a/docs/develop/suga-client.mdx b/docs/develop/suga-client.mdx index 02b36d16..b54c455f 100644 --- a/docs/develop/suga-client.mdx +++ b/docs/develop/suga-client.mdx @@ -53,7 +53,7 @@ Generate type-safe client libraries using the `suga generate` command: ```bash - suga generate --python --python-out ./suga_gen + suga generate --python --python-out ./suga ``` ```python diff --git a/docs/guides/static-website-hosting.mdx b/docs/guides/static-website-hosting.mdx index 37b30b16..b2c229f7 100644 --- a/docs/guides/static-website-hosting.mdx +++ b/docs/guides/static-website-hosting.mdx @@ -20,7 +20,8 @@ buckets: entrypoints: web: routes: - /: frontend # Serve files from bucket + /: + name: frontend # Serve files from bucket ``` When you deploy: @@ -43,7 +44,8 @@ buckets: entrypoints: web: routes: - /: frontend + /: + name: frontend ``` **Build your app, then deploy:** @@ -84,8 +86,10 @@ buckets: entrypoints: web: routes: - /api/: api # API requests go to service - /: frontend # Everything else goes to static files + /api/: + name: api # API requests go to service + /: + name: frontend # Everything else goes to static files ``` **How routing works:** @@ -106,7 +110,8 @@ buckets: entrypoints: web: routes: - /: website + /: + name: website ``` **Directory structure:** @@ -124,7 +129,7 @@ public/ └── logo.png ``` -All files are uploaded to the bucket and served via CDN. +All files are uploaded to the bucket at deploy time and served via CDN. ## Build Process Integration @@ -219,8 +224,7 @@ Most platforms support custom domains through Terraform variables: After running `suga build`, configure your domain: ```hcl title="terraform/stacks/my-app/terraform.tfvars" - entrypoint_web_domain = "www.example.com" - entrypoint_web_certificate_arn = "arn:aws:acm:us-east-1:..." + custom_domain = "www.example.com" ``` Then apply: @@ -235,10 +239,11 @@ Most platforms support custom domains through Terraform variables: - After running `suga build`, configure your domain: + The GCP platform requires that you have a Cloud DNS zone already created. After it's created and you've run `suga build`, you can add the configuration: ```hcl title="terraform/stacks/my-app/terraform.tfvars" - entrypoint_web_domain = "www.example.com" + dns_zone_name = "name_of_your_zone" + domain_name = "www.example.com" ``` Then apply: @@ -268,8 +273,10 @@ buckets: entrypoints: web: routes: - /api/: api - /: frontend + /api/: + name: api + /: + name: frontend ``` ```javascript title=".env.production" diff --git a/docs/why-suga.mdx b/docs/why-suga.mdx index d2e4a578..4d1a815c 100644 --- a/docs/why-suga.mdx +++ b/docs/why-suga.mdx @@ -59,7 +59,7 @@ Platform teams create reusable blueprints that enforce organizational standards - Visual infrastructure design - Local development with emulated cloud services - Deploy anywhere without changing code -- Type-safe client libraries +- Generated type-safe client libraries (Node.js, Python, Go, etc) **For Platform Teams:** - Enforce security policies and compliance From 7f8ed2dec576b8b30f21765e563c75a6311ddbaa Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Wed, 12 Nov 2025 19:05:45 +1100 Subject: [PATCH 06/16] docs: merge env mgmt into tf config page --- docs/core/deployment.mdx | 10 ++++----- docs/core/infrastructure-generation.mdx | 4 ++-- docs/deploy/terraform-configuration.mdx | 29 +++++++++++++++++++++---- docs/docs.json | 3 +-- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/docs/core/deployment.mdx b/docs/core/deployment.mdx index c7e415f5..3ec974cf 100644 --- a/docs/core/deployment.mdx +++ b/docs/core/deployment.mdx @@ -256,8 +256,8 @@ terraform destroy Deploy the same application to multiple environments (dev, staging, production) using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration per environment. - - Learn detailed strategies for managing multiple environments with Terraform workspaces and promotion workflows + + Learn how to manage multiple environments with Terraform workspaces and variables ## Cloud Provider Setup @@ -309,7 +309,7 @@ Configure a remote backend for team deployments. See the [Terraform Backend Conf ### 3. Separate Environments -Use Terraform workspaces or separate state files. See the [Environment Management](/deploy/environment-management) guide. +Use Terraform workspaces or separate state files. See the [Environment Management](/deploy/terraform-configuration#environment-management) docs. ### 4. Version Control Everything @@ -398,8 +398,8 @@ terraform plan Understand how Terraform is generated - - Manage multiple deployment environments + + Learn how to manage multiple environments with Terraform workspaces and variables diff --git a/docs/core/infrastructure-generation.mdx b/docs/core/infrastructure-generation.mdx index 982b7702..1d639a9c 100644 --- a/docs/core/infrastructure-generation.mdx +++ b/docs/core/infrastructure-generation.mdx @@ -136,8 +136,8 @@ module "service_api" { The same generated Terraform can deploy to multiple environments using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration for dev, staging, and production. - - Learn best practices for managing multiple environments with Terraform workspaces and variables + + Learn how to manage multiple environments with Terraform workspaces and variables See the [CLI reference](/cli/build) for complete build options. diff --git a/docs/deploy/terraform-configuration.mdx b/docs/deploy/terraform-configuration.mdx index df463da5..96ba1cb0 100644 --- a/docs/deploy/terraform-configuration.mdx +++ b/docs/deploy/terraform-configuration.mdx @@ -9,14 +9,35 @@ description: "Configure Terraform backends, state management, and variables" See the complete backend configuration guide -## Workspaces for Multiple Environments +## Environment Management + +Manage multiple environments using [Terraform workspaces](https://developer.hashicorp.com/terraform/language/state/workspaces) and variable files. + +## Using Workspaces ```bash +# Create workspaces terraform workspace new dev terraform workspace new staging terraform workspace new prod + +# Deploy to dev +terraform workspace select dev +terraform apply -var-file=environments/dev.tfvars + +# Deploy to prod +terraform workspace select prod +terraform apply -var-file=environments/prod.tfvars ``` - - Learn about managing multiple environments - +## Environment-Specific Configuration + +```hcl title="environments/dev.tfvars" +services_api_memory = 512 +services_api_timeout = 10 +``` + +```hcl title="environments/prod.tfvars" +services_api_memory = 2048 +services_api_timeout = 30 +``` diff --git a/docs/docs.json b/docs/docs.json index 9a2ca30f..78d760b0 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -52,8 +52,7 @@ "deploy/aws", "deploy/gcp", "deploy/azure", - "deploy/terraform-configuration", - "deploy/environment-management" + "deploy/terraform-configuration" ] }, { From f61219d6be80946aaab1893e295e8224d32aceed Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Wed, 12 Nov 2025 19:23:06 +1100 Subject: [PATCH 07/16] docs: improvements from review feedback --- docs/cli/login.mdx | 2 +- docs/core/deployment.mdx | 412 ------------------------ docs/core/infrastructure-generation.mdx | 2 +- docs/core/local-development.mdx | 4 +- docs/core/overview.mdx | 2 +- docs/deploy/aws.mdx | 2 +- docs/deploy/gcp.mdx | 2 +- docs/deploy/overview.mdx | 402 ++++++++++++++++++++++- docs/docs.json | 3 +- docs/faq.mdx | 8 +- docs/guides/static-website-hosting.mdx | 2 +- docs/installation.mdx | 2 +- docs/quickstart.mdx | 14 +- docs/why-suga.mdx | 22 +- 14 files changed, 425 insertions(+), 454 deletions(-) delete mode 100644 docs/core/deployment.mdx diff --git a/docs/cli/login.mdx b/docs/cli/login.mdx index bc539efe..40a8c318 100644 --- a/docs/cli/login.mdx +++ b/docs/cli/login.mdx @@ -9,7 +9,7 @@ Login to the Suga CLI. suga login ``` -Opens your browser to complete the authentication flow with the Suga platform. This is required for all CLI operations during the early access period. +Opens your browser to complete the authentication flow with the Suga platform. This is required for all CLI operations. ## What happens during login diff --git a/docs/core/deployment.mdx b/docs/core/deployment.mdx deleted file mode 100644 index 3ec974cf..00000000 --- a/docs/core/deployment.mdx +++ /dev/null @@ -1,412 +0,0 @@ ---- -title: "Deployment" -description: "Understand how Suga applications are deployed to the cloud" ---- - -Deploying with Suga means running standard Terraform commands on the infrastructure generated by `suga build`. This page explains the deployment lifecycle, how to deploy to different environments, and best practices for production deployments. - -## Deployment Overview - -Suga's deployment model is transparent and uses standard tools: - -1. **Generate Terraform** - `suga build` creates Terraform modules -2. **Configure Provider** - Set up cloud provider credentials and configuration -3. **Initialize Terraform** - Download providers and modules -4. **Preview Changes** - Review what will be created/modified -5. **Apply Changes** - Deploy to your cloud provider -6. **Verify Deployment** - Test deployed resources - -## The Deployment Lifecycle - - - - Generate Terraform from your project: - - ```bash - suga build - ``` - - Output: - ``` - ✓ Terraform generated successfully - output written to terraform/stacks/my-app - - Next steps: - 1. Run cd terraform/stacks/my-app to move to the stack directory - 2. Initialize the stack terraform init -upgrade - 3. Optionally, preview with terraform plan - 4. Deploy with terraform apply - ``` - - - - Change to the generated Terraform directory: - - ```bash - cd terraform/stacks/my-app - ``` - - Contents: - ``` - my-app/ - ├── cdk.tf.json # Main Terraform Entrypoint - └── .terraform/ # Plugin Terraform modules - └── modules/ - ├── api/ - ├── api_image/ - ├── uploads_bucket/ - └── ... - ``` - - - - Set up provider configuration and credentials: - - - - ```bash - # Configure credentials - aws configure - ``` - - Create provider configuration: - - ```hcl title="provider.tf" - provider "aws" { - region = "us-west-2" - } - ``` - - - - ```bash - # Configure credentials - gcloud auth application-default login - ``` - - Set required variables: - - ```hcl title="terraform.tfvars" - project_id = "my-gcp-project" - region = "us-central1" - ``` - - - - - Files like `provider.tf` and `terraform.tfvars` are preserved across builds and won't be overwritten. - - - - - Download providers and modules: - - ```bash - terraform init -upgrade - ``` - - This downloads: - - Cloud provider Terraform providers (AWS, GCP, etc.) - - Plugin modules referenced by your platform - - Backend configuration (if configured) - - - - Review what Terraform will create: - - ```bash - terraform plan - ``` - - Output shows: - - Resources to be created (`+`) - - Resources to be modified (`~`) - - Resources to be deleted (`-`) - - - Always review the plan carefully before applying, especially in production environments. - - - - - Apply the Terraform configuration: - - ```bash - terraform apply - ``` - - Terraform will: - 1. Show the plan again - 2. Ask for confirmation - 3. Create resources in your cloud account - 4. Save state to track resources - - ```bash - Apply complete! Resources: 15 added, 0 changed, 0 destroyed. - - Outputs: - entrypoint_web_url = "https://d123abc.cloudfront.net" - service_api_function_name = "my-app-api" - ``` - - - - Test your deployed application: - - ```bash - # Get the entrypoint URL from outputs - terraform output entrypoint_web_url - - # Test the endpoint - curl https://d123abc.cloudfront.net/api/health - ``` - - - -## Managing Deployments - -### Updating Your Application - -When you make changes to your project: - -1. **Rebuild Terraform:** - ```bash - suga build - ``` - -2. **Preview changes:** - ```bash - cd terraform/stacks/my-app - terraform plan - ``` - -3. **Apply updates:** - ```bash - terraform apply - ``` - -Terraform intelligently updates only what changed: -- Modified services are redeployed -- New resources are created -- Removed resources are deleted -- Unchanged resources remain untouched - -### Deploying Code Updates - -When you update service code without changing infrastructure: - -```bash -# Simply re-run terraform apply -cd terraform/stacks/my-app -terraform apply -``` - -Terraform automatically: -1. Builds new container images from your updated code -2. Pushes images to the container registry (ECR, Artifact Registry, etc.) -3. Updates services to use the new images -4. Handles rolling deployments with zero downtime - -No manual Docker commands needed - the generated Terraform includes container build and push logic. - - - CI/CD pipelines typically automate this by running `terraform apply` on every commit. See the [CI/CD Authentication Guide](/guides/cicd-authentication) for details. - - -### Rolling Back - -If a deployment causes issues, roll back: - -```bash -# Revert code changes -git revert - -# Rebuild Terraform -suga build - -# Apply previous configuration -cd terraform/stacks/my-app -terraform apply -``` - -Or roll back to a previous Terraform state: - -```bash -# List state backups -terraform state list - -# If using versioned state backend, restore previous version -# (AWS S3, GCS, Terraform Cloud all support versioning) -``` - -### Destroying Resources - -When you're done with a deployment: - -```bash -cd terraform/stacks/my-app -terraform destroy -``` - - - `terraform destroy` permanently deletes all cloud resources. Databases, buckets, and all data will be lost. Use with extreme caution, especially in production. - - -## Multi-Environment Deployments - -Deploy the same application to multiple environments (dev, staging, production) using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration per environment. - - - Learn how to manage multiple environments with Terraform workspaces and variables - - -## Cloud Provider Setup - -Each cloud provider requires specific credentials and permissions. Detailed setup instructions including required permissions, authentication methods, and provider configuration are available in the provider-specific guides: - - - - AWS credentials, IAM permissions, and configuration - - - - GCP service accounts, permissions, and configuration - - - - Azure credentials, RBAC, and configuration - - - -## Terraform State Management - -Terraform state tracks deployed resources and must be managed carefully. By default, state is stored locally, which is suitable for personal projects but not recommended for teams. For production deployments, use a remote backend for state locking, versioning, and team collaboration. - - - Complete guide to configuring remote state backends (S3, GCS, Terraform Cloud) - - -## CI/CD Integration - -Automate deployments with CI/CD pipelines to build infrastructure and deploy on every commit. Common patterns include GitHub Actions, GitLab CI, CircleCI, and Jenkins. - - - Learn how to authenticate Suga in CI/CD pipelines with example workflows - - -## Best Practices - -### 1. Always Preview Before Applying - -```bash -terraform plan # Review changes -terraform apply # Only after reviewing -``` - -### 2. Use Remote State for Teams - -Configure a remote backend for team deployments. See the [Terraform Backend Configuration](/guides/terraform-backend-config) guide. - -### 3. Separate Environments - -Use Terraform workspaces or separate state files. See the [Environment Management](/deploy/terraform-configuration#environment-management) docs. - -### 4. Version Control Everything - -Commit generated Terraform to git: - -```bash -git add terraform/ -git commit -m "Update infrastructure" -``` - -### 5. Test in Non-Production First - -Always deploy to dev/staging before production: - -```bash -# Deploy to dev -terraform workspace select dev -terraform apply - -# Test thoroughly -# Then deploy to prod -terraform workspace select prod -terraform apply -``` - -### 6. Use Terraform Variables for Configuration - -Use variable files for environment-specific configuration. See the [Terraform Configuration](/deploy/terraform-configuration) guide. - -### 7. Monitor Deployments - -Set up monitoring for deployed resources: -- CloudWatch (AWS) -- Cloud Monitoring (GCP) -- Application Performance Monitoring (APM) tools - -### 8. Document Your Deployments - -Maintain deployment documentation: - -```markdown title="DEPLOYMENT.md" -## Production Deployment - -1. Ensure tests pass: `npm test` -2. Build infrastructure: `suga build` -3. Review changes: `terraform plan` -4. Deploy: `terraform apply` -5. Verify: `curl https://api.example.com/health` -6. Monitor: Check CloudWatch dashboard -``` - -## Troubleshooting - -### Common Deployment Issues - -**"No valid credential sources found"** - -Solution: Configure cloud provider credentials properly. - -**"Resource already exists"** - -Solution: Import existing resource into Terraform state: -```bash -terraform import . -``` - -**"State lock timeout"** - -Solution: Another apply is running, or a previous one crashed. Release lock: -```bash -terraform force-unlock -``` - -**"Plan shows unwanted changes"** - -Solution: Check for drift between state and actual resources: -```bash -terraform refresh -terraform plan -``` - -## Learn More - - - - Understand how Terraform is generated - - - - Learn how to manage multiple environments with Terraform workspaces and variables - - - - Best practices for Terraform configuration - - - - How to develop applications locally with Suga - - diff --git a/docs/core/infrastructure-generation.mdx b/docs/core/infrastructure-generation.mdx index 1d639a9c..f1e859d0 100644 --- a/docs/core/infrastructure-generation.mdx +++ b/docs/core/infrastructure-generation.mdx @@ -180,7 +180,7 @@ terraform plan # Review before apply ## Learn More - + Understand the deployment process diff --git a/docs/core/local-development.mdx b/docs/core/local-development.mdx index c69bea82..a4fe27de 100644 --- a/docs/core/local-development.mdx +++ b/docs/core/local-development.mdx @@ -330,7 +330,7 @@ For features that can't be emulated: 2. **Mock externals** - Use mocks for cloud-specific APIs 3. **Integration tests** - Test cloud features in CI/CD pipelines - + Learn how to deploy to cloud environments for testing @@ -349,7 +349,7 @@ For features that can't be emulated: Configure databases and connection strings - + Deploy to cloud after local testing diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index 5a61e335..3b76a6c5 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -287,7 +287,7 @@ Now that you understand Suga's core concepts, dive deeper into each component: Master local development workflow - + Understand deployment and operations diff --git a/docs/deploy/aws.mdx b/docs/deploy/aws.mdx index 466bec0d..d1c22912 100644 --- a/docs/deploy/aws.mdx +++ b/docs/deploy/aws.mdx @@ -36,6 +36,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/gcp.mdx b/docs/deploy/gcp.mdx index e8dfec4e..c7f78b91 100644 --- a/docs/deploy/gcp.mdx +++ b/docs/deploy/gcp.mdx @@ -35,6 +35,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/overview.mdx b/docs/deploy/overview.mdx index 23d32bfd..3ec974cf 100644 --- a/docs/deploy/overview.mdx +++ b/docs/deploy/overview.mdx @@ -1,30 +1,412 @@ --- -title: "Deployment Overview" -description: "Overview of deploying Suga applications to cloud providers" +title: "Deployment" +description: "Understand how Suga applications are deployed to the cloud" --- -Deploying with Suga means running standard Terraform commands on infrastructure generated by `suga build`. +Deploying with Suga means running standard Terraform commands on the infrastructure generated by `suga build`. This page explains the deployment lifecycle, how to deploy to different environments, and best practices for production deployments. - - See the comprehensive deployment guide in Core Concepts +## Deployment Overview + +Suga's deployment model is transparent and uses standard tools: + +1. **Generate Terraform** - `suga build` creates Terraform modules +2. **Configure Provider** - Set up cloud provider credentials and configuration +3. **Initialize Terraform** - Download providers and modules +4. **Preview Changes** - Review what will be created/modified +5. **Apply Changes** - Deploy to your cloud provider +6. **Verify Deployment** - Test deployed resources + +## The Deployment Lifecycle + + + + Generate Terraform from your project: + + ```bash + suga build + ``` + + Output: + ``` + ✓ Terraform generated successfully + output written to terraform/stacks/my-app + + Next steps: + 1. Run cd terraform/stacks/my-app to move to the stack directory + 2. Initialize the stack terraform init -upgrade + 3. Optionally, preview with terraform plan + 4. Deploy with terraform apply + ``` + + + + Change to the generated Terraform directory: + + ```bash + cd terraform/stacks/my-app + ``` + + Contents: + ``` + my-app/ + ├── cdk.tf.json # Main Terraform Entrypoint + └── .terraform/ # Plugin Terraform modules + └── modules/ + ├── api/ + ├── api_image/ + ├── uploads_bucket/ + └── ... + ``` + + + + Set up provider configuration and credentials: + + + + ```bash + # Configure credentials + aws configure + ``` + + Create provider configuration: + + ```hcl title="provider.tf" + provider "aws" { + region = "us-west-2" + } + ``` + + + + ```bash + # Configure credentials + gcloud auth application-default login + ``` + + Set required variables: + + ```hcl title="terraform.tfvars" + project_id = "my-gcp-project" + region = "us-central1" + ``` + + + + + Files like `provider.tf` and `terraform.tfvars` are preserved across builds and won't be overwritten. + + + + + Download providers and modules: + + ```bash + terraform init -upgrade + ``` + + This downloads: + - Cloud provider Terraform providers (AWS, GCP, etc.) + - Plugin modules referenced by your platform + - Backend configuration (if configured) + + + + Review what Terraform will create: + + ```bash + terraform plan + ``` + + Output shows: + - Resources to be created (`+`) + - Resources to be modified (`~`) + - Resources to be deleted (`-`) + + + Always review the plan carefully before applying, especially in production environments. + + + + + Apply the Terraform configuration: + + ```bash + terraform apply + ``` + + Terraform will: + 1. Show the plan again + 2. Ask for confirmation + 3. Create resources in your cloud account + 4. Save state to track resources + + ```bash + Apply complete! Resources: 15 added, 0 changed, 0 destroyed. + + Outputs: + entrypoint_web_url = "https://d123abc.cloudfront.net" + service_api_function_name = "my-app-api" + ``` + + + + Test your deployed application: + + ```bash + # Get the entrypoint URL from outputs + terraform output entrypoint_web_url + + # Test the endpoint + curl https://d123abc.cloudfront.net/api/health + ``` + + + +## Managing Deployments + +### Updating Your Application + +When you make changes to your project: + +1. **Rebuild Terraform:** + ```bash + suga build + ``` + +2. **Preview changes:** + ```bash + cd terraform/stacks/my-app + terraform plan + ``` + +3. **Apply updates:** + ```bash + terraform apply + ``` + +Terraform intelligently updates only what changed: +- Modified services are redeployed +- New resources are created +- Removed resources are deleted +- Unchanged resources remain untouched + +### Deploying Code Updates + +When you update service code without changing infrastructure: + +```bash +# Simply re-run terraform apply +cd terraform/stacks/my-app +terraform apply +``` + +Terraform automatically: +1. Builds new container images from your updated code +2. Pushes images to the container registry (ECR, Artifact Registry, etc.) +3. Updates services to use the new images +4. Handles rolling deployments with zero downtime + +No manual Docker commands needed - the generated Terraform includes container build and push logic. + + + CI/CD pipelines typically automate this by running `terraform apply` on every commit. See the [CI/CD Authentication Guide](/guides/cicd-authentication) for details. + + +### Rolling Back + +If a deployment causes issues, roll back: + +```bash +# Revert code changes +git revert + +# Rebuild Terraform +suga build + +# Apply previous configuration +cd terraform/stacks/my-app +terraform apply +``` + +Or roll back to a previous Terraform state: + +```bash +# List state backups +terraform state list + +# If using versioned state backend, restore previous version +# (AWS S3, GCS, Terraform Cloud all support versioning) +``` + +### Destroying Resources + +When you're done with a deployment: + +```bash +cd terraform/stacks/my-app +terraform destroy +``` + + + `terraform destroy` permanently deletes all cloud resources. Databases, buckets, and all data will be lost. Use with extreme caution, especially in production. + + +## Multi-Environment Deployments + +Deploy the same application to multiple environments (dev, staging, production) using Terraform workspaces and environment-specific variable files. This allows you to maintain a single infrastructure definition while customizing configuration per environment. + + + Learn how to manage multiple environments with Terraform workspaces and variables -## Quick Links +## Cloud Provider Setup + +Each cloud provider requires specific credentials and permissions. Detailed setup instructions including required permissions, authentication methods, and provider configuration are available in the provider-specific guides: - Deploy to Amazon Web Services + AWS credentials, IAM permissions, and configuration - Deploy to Google Cloud Platform + GCP service accounts, permissions, and configuration - Deploy to Microsoft Azure + Azure credentials, RBAC, and configuration + + + +## Terraform State Management + +Terraform state tracks deployed resources and must be managed carefully. By default, state is stored locally, which is suitable for personal projects but not recommended for teams. For production deployments, use a remote backend for state locking, versioning, and team collaboration. + + + Complete guide to configuring remote state backends (S3, GCS, Terraform Cloud) + + +## CI/CD Integration + +Automate deployments with CI/CD pipelines to build infrastructure and deploy on every commit. Common patterns include GitHub Actions, GitLab CI, CircleCI, and Jenkins. + + + Learn how to authenticate Suga in CI/CD pipelines with example workflows + + +## Best Practices + +### 1. Always Preview Before Applying + +```bash +terraform plan # Review changes +terraform apply # Only after reviewing +``` + +### 2. Use Remote State for Teams + +Configure a remote backend for team deployments. See the [Terraform Backend Configuration](/guides/terraform-backend-config) guide. + +### 3. Separate Environments + +Use Terraform workspaces or separate state files. See the [Environment Management](/deploy/terraform-configuration#environment-management) docs. + +### 4. Version Control Everything + +Commit generated Terraform to git: + +```bash +git add terraform/ +git commit -m "Update infrastructure" +``` + +### 5. Test in Non-Production First + +Always deploy to dev/staging before production: + +```bash +# Deploy to dev +terraform workspace select dev +terraform apply + +# Test thoroughly +# Then deploy to prod +terraform workspace select prod +terraform apply +``` + +### 6. Use Terraform Variables for Configuration + +Use variable files for environment-specific configuration. See the [Terraform Configuration](/deploy/terraform-configuration) guide. + +### 7. Monitor Deployments + +Set up monitoring for deployed resources: +- CloudWatch (AWS) +- Cloud Monitoring (GCP) +- Application Performance Monitoring (APM) tools + +### 8. Document Your Deployments + +Maintain deployment documentation: + +```markdown title="DEPLOYMENT.md" +## Production Deployment + +1. Ensure tests pass: `npm test` +2. Build infrastructure: `suga build` +3. Review changes: `terraform plan` +4. Deploy: `terraform apply` +5. Verify: `curl https://api.example.com/health` +6. Monitor: Check CloudWatch dashboard +``` + +## Troubleshooting + +### Common Deployment Issues + +**"No valid credential sources found"** + +Solution: Configure cloud provider credentials properly. + +**"Resource already exists"** + +Solution: Import existing resource into Terraform state: +```bash +terraform import . +``` + +**"State lock timeout"** + +Solution: Another apply is running, or a previous one crashed. Release lock: +```bash +terraform force-unlock +``` + +**"Plan shows unwanted changes"** + +Solution: Check for drift between state and actual resources: +```bash +terraform refresh +terraform plan +``` + +## Learn More + + + + Understand how Terraform is generated + + + + Learn how to manage multiple environments with Terraform workspaces and variables - Configure Terraform backends and state + Best practices for Terraform configuration + + + + How to develop applications locally with Suga diff --git a/docs/docs.json b/docs/docs.json index 78d760b0..26249542 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -29,8 +29,7 @@ "core/platforms", "core/plugins", "core/infrastructure-generation", - "core/local-development", - "core/deployment" + "core/local-development" ] }, { diff --git a/docs/faq.mdx b/docs/faq.mdx index d5ee8a94..963f2cab 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -17,6 +17,8 @@ See our [Why Suga?](/why-suga) page for detailed comparisons with PaaS platforms The Suga CLI, official platforms and plugins are open-source, including the Terraform generation code (engines). +You can access, review and contribute on [GitHub](https://github.com/nitrictech/suga) + ### What cloud providers does Suga support? - **AWS** - Lambda, Fargate, S3, CloudFront (full support) @@ -78,7 +80,7 @@ Not yet, but Kubernetes platform support is planned. ### How much does deployment cost? -Suga itself is free during early access. You pay only your cloud provider's standard rates for resources (Lambda, S3, CloudFront, etc.). +Suga is free to get started, you can see complete pricing details on the [pricing page](https://addsuga.com/pricing) There is no Suga markup on cloud costs. @@ -152,13 +154,13 @@ Plugins are Terraform modules and run with your cloud provider credentials durin ### Is Suga free? -Suga is currently in early access. Pricing for future releases and enterprise features will be announced. +Suga is free to sign-up and has paid offering for teams and enterprise, see the [pricing page](https://addsuga.com/pricing) for complete details. You only pay your cloud provider for infrastructure resources. ### Do I need a Suga account? -Yes, currently a Suga account is required. Sign up at [addsuga.com](https://addsuga.com). +Yes, a Suga account is required. Sign up at [addsuga.com](https://app.addsuga.com/signup). In the future, some features may work without an account. diff --git a/docs/guides/static-website-hosting.mdx b/docs/guides/static-website-hosting.mdx index b2c229f7..ee2f1dc8 100644 --- a/docs/guides/static-website-hosting.mdx +++ b/docs/guides/static-website-hosting.mdx @@ -332,7 +332,7 @@ During development, use your framework's dev server (with hot reload) rather tha HTTP routing and CDN - + Deployment workflow diff --git a/docs/installation.mdx b/docs/installation.mdx index 2f125560..957a0b72 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -10,7 +10,7 @@ import { OSTabs } from '/snippets/os-tabs.jsx'; The Suga CLI is all you need to get started with Suga. It provides everything required to build, test, and deploy cloud-native applications with automatic infrastructure generation. - **Early Access:** During the early access period, a Suga account is required, you can request an invite at https://addsuga.com. You'll need to run `suga login` after installation to authenticate. We plan to make certain functionality available without an account in future releases. + A Suga account is required, sign-up for a free account at https://app.addsuga.com/signup. ## Quick Install diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 450d1aaf..1f0e8cab 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -6,9 +6,7 @@ description: "Get started with Suga in minutes - build, test, and deploy cloud a The Suga CLI provides everything you need to build cloud applications with automatic infrastructure generation for many cloud providers. - **Prerequisites:** This guide assumes you have the Suga CLI installed. If you - need to install it, see the [Installation Guide](/installation) for - platform-specific instructions. + **Prerequisites:** This guide assumes you have the Suga CLI installed. See the [Installation Guide](/installation) for instructions. ## Sign In to Suga @@ -19,9 +17,9 @@ Sign in to the Suga platform: suga login ``` - - If you don't have a Suga account yet you can request access at [addsuga.com](https://addsuga.com) - + + A Suga account is required, sign-up for a free account at https://app.addsuga.com/signup. + You'll see a confirmation: ```bash @@ -30,10 +28,6 @@ You'll see a confirmation: ✓ Logged in as User ``` - - During early access authentication is required to access all Suga platform features. In the future, certain features may be made available without signing in. - - ## Create Your Project Create a new project from a template: diff --git a/docs/why-suga.mdx b/docs/why-suga.mdx index 4d1a815c..74e7c047 100644 --- a/docs/why-suga.mdx +++ b/docs/why-suga.mdx @@ -29,20 +29,26 @@ Design your architecture visually, then generate production-ready Terraform. No ```yaml title="Design becomes configuration" -services: +entrypoints: api: + routes: + /: + name: frontend + /api/: + name: app + +services: + app: + dev: + script: npm run dev + frontend: dev: script: npm run dev buckets: - uploads: + bucket: access: - api: [read, write] - -entrypoints: - web: - routes: - /api/: api + app: [read, write] ``` ```bash title="Configuration becomes Terraform" From 363df33b3e959a323acb8da6afe6e28b9da63229 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 08:27:11 +1100 Subject: [PATCH 08/16] docs: fix python examples --- docs/sdks/python.mdx | 6 +++--- docs/sdks/python/client.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sdks/python.mdx b/docs/sdks/python.mdx index f74209db..19a44cb7 100644 --- a/docs/sdks/python.mdx +++ b/docs/sdks/python.mdx @@ -32,11 +32,11 @@ from suga_gen.client import SugaClient ```python # Initialize client -client = SugaClient() +suga = SugaClient() # Access your resources (names from your suga.yaml) -client.image.write("file.txt", b"data") -content = client.image.read("file.txt") +suga.image.write("file.txt", b"data") +content = suga.image.read("file.txt") ``` ## Available Resources diff --git a/docs/sdks/python/client.mdx b/docs/sdks/python/client.mdx index c2e9ec73..96bf0074 100644 --- a/docs/sdks/python/client.mdx +++ b/docs/sdks/python/client.mdx @@ -16,7 +16,7 @@ suga generate --python --python-out ./suga_gen ## Basic Usage ```python -from suga.client import SugaClient +from suga_gen.client import SugaClient # Initialize client suga = SugaClient() From a60bf8c65d80a91514ca4809c6ae3a0f88f14b26 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 10:25:58 +1100 Subject: [PATCH 09/16] docs: edits from feedback --- docs/cli/login.mdx | 2 +- docs/core/infrastructure-generation.mdx | 4 +++- docs/core/local-development.mdx | 2 +- docs/core/overview.mdx | 3 +-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/cli/login.mdx b/docs/cli/login.mdx index 40a8c318..2af5a5c8 100644 --- a/docs/cli/login.mdx +++ b/docs/cli/login.mdx @@ -9,7 +9,7 @@ Login to the Suga CLI. suga login ``` -Opens your browser to complete the authentication flow with the Suga platform. This is required for all CLI operations. +Opens your browser to complete the authentication flow with the Suga platform. This is required for most CLI operations. ## What happens during login diff --git a/docs/core/infrastructure-generation.mdx b/docs/core/infrastructure-generation.mdx index f1e859d0..d2eedc88 100644 --- a/docs/core/infrastructure-generation.mdx +++ b/docs/core/infrastructure-generation.mdx @@ -19,10 +19,12 @@ The `suga build` command orchestrates a multi-step process: services: api: + subtype: lambda dev: script: npm run dev buckets: + subtype: s3 uploads: access: api: [read, write] @@ -65,7 +67,7 @@ The `suga build` command orchestrates a multi-step process: - Suga then uses Terraform CDK to resolve the modules, variables and other configuration and produce a functional Terraform stack. + Suga then uses Terraform CDK to resolve the modules, variables and other configuration to produce a Terraform stack. ``` terraform/stacks/my-app/ diff --git a/docs/core/local-development.mdx b/docs/core/local-development.mdx index a4fe27de..1652559d 100644 --- a/docs/core/local-development.mdx +++ b/docs/core/local-development.mdx @@ -199,7 +199,7 @@ suga dev ### Making Code Changes 1. **Edit your service code** - Changes are detected automatically -2. **Service restarts** - Suga restarts the affected service +2. **Service restarts** - Using a watcher in your dev script 3. **Test immediately** - New code is running ### Debugging Services diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index 3b76a6c5..6ef6f3d2 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -33,7 +33,6 @@ graph TB Projects are **deployment-agnostic** - they describe requirements without specifying how they're implemented. ```yaml title="Example: A simple web application" -target: suga/aws@1 name: my-app services: @@ -96,7 +95,7 @@ Understanding how these pieces work together: ``` Local development provides: - - Hot reloading for code changes + - Hot reloading for code changes, using watcher dev scripts - Emulated buckets, entrypoints, and databases - Fast iteration without cloud costs From e9683a24f6e7caa1dde2728041134d3d8584bedb Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 10:57:02 +1100 Subject: [PATCH 10/16] docs: add note about local schedules Co-authored-by: David Moore <4121492+davemooreuws@users.noreply.github.com> --- docs/core/local-development.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/local-development.mdx b/docs/core/local-development.mdx index 1652559d..fc43dbc6 100644 --- a/docs/core/local-development.mdx +++ b/docs/core/local-development.mdx @@ -9,7 +9,7 @@ Suga's local development environment (`suga dev`) lets you build and test cloud The `suga dev` command starts a local development server that: -- **Emulates cloud resources** - Buckets, entrypoints, databases +- **Emulates cloud resources** - Buckets, entrypoints, databases, schedules - **Runs your services** - Using the `dev.script` from your `suga.yaml` - **Hot reloads code** - Automatically restarts services when files change - **Provides local URLs** - Access your application at `localhost` ports From a5f05cbbe38f20d37db5daa73608aa7562f25e47 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:15:17 +1100 Subject: [PATCH 11/16] docs: add missing subtypes in example config --- docs/core/projects.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/core/projects.mdx b/docs/core/projects.mdx index f6390938..84804347 100644 --- a/docs/core/projects.mdx +++ b/docs/core/projects.mdx @@ -40,6 +40,7 @@ description: An example web application with storage services: app: + subtype: lambda dev: script: npm run dev path: ./app @@ -50,6 +51,7 @@ services: buckets: bucket: + subtype: s3 access: app: - read @@ -57,6 +59,7 @@ buckets: entrypoints: api: + subtype: cloudfront routes: /: name: frontend @@ -100,6 +103,7 @@ Services are your application containers that handle business logic: ```yaml title="Service definitions" services: app: + subtype: lambda env: EXT_URL: https://somewhere.example.com container: @@ -110,6 +114,7 @@ services: script: npm run dev worker: + subtype: fargate container: image: id: "my-registry/worker:latest" From 4bf417daa765827d8be5a423cde677a9ac72d82d Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:37:52 +1100 Subject: [PATCH 12/16] docs: add relevant links to cloud deployment pages --- docs/deploy/aws.mdx | 18 ++++++++++--- docs/deploy/environment-management.mdx | 35 -------------------------- docs/deploy/gcp.mdx | 20 +++++++++------ 3 files changed, 27 insertions(+), 46 deletions(-) delete mode 100644 docs/deploy/environment-management.mdx diff --git a/docs/deploy/aws.mdx b/docs/deploy/aws.mdx index d1c22912..517245ea 100644 --- a/docs/deploy/aws.mdx +++ b/docs/deploy/aws.mdx @@ -5,11 +5,21 @@ description: "Deploy Suga applications to Amazon Web Services" Deploy Suga applications to AWS using Lambda, Fargate, S3, and CloudFront. +## Platform-Specific Requirements + +The exact setup steps (account creation, IAM roles, etc.) depend on which Suga platform you're using. Each platform has specific requirements documented in the platform browser. + + + View available platforms and their setup requirements + + +Generally, deployments to AWS will require the following. + ## Prerequisites -- AWS account -- AWS CLI configured -- Terraform installed +- **AWS CLI** - [Installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) +- **Terraform** - [Installation guide](https://developer.hashicorp.com/terraform/install) +- **Suga CLI** - See [Installation](/installation) ## Quick Start @@ -36,6 +46,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/environment-management.mdx b/docs/deploy/environment-management.mdx deleted file mode 100644 index 5caa026b..00000000 --- a/docs/deploy/environment-management.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "Environment Management" -description: "Managing multiple deployment environments (dev, staging, production)" ---- - -Manage multiple environments using [Terraform workspaces](https://developer.hashicorp.com/terraform/language/state/workspaces) and variable files. - -## Using Workspaces - -```bash -# Create workspaces -terraform workspace new dev -terraform workspace new staging -terraform workspace new prod - -# Deploy to dev -terraform workspace select dev -terraform apply -var-file=environments/dev.tfvars - -# Deploy to prod -terraform workspace select prod -terraform apply -var-file=environments/prod.tfvars -``` - -## Environment-Specific Configuration - -```hcl title="environments/dev.tfvars" -services_api_memory = 512 -services_api_timeout = 10 -``` - -```hcl title="environments/prod.tfvars" -services_api_memory = 2048 -services_api_timeout = 30 -``` diff --git a/docs/deploy/gcp.mdx b/docs/deploy/gcp.mdx index c7f78b91..4a4a6af3 100644 --- a/docs/deploy/gcp.mdx +++ b/docs/deploy/gcp.mdx @@ -5,11 +5,21 @@ description: "Deploy Suga applications to Google Cloud Platform" Deploy Suga applications to GCP using Cloud Run, Cloud Storage, and Cloud CDN. +## Platform-Specific Requirements + +The exact setup steps (project creation, API enablement, IAM roles, etc.) depend on which Suga platform you're using. Each platform has specific requirements documented in the platform browser. + + + View available platforms and their setup requirements + + +Generally, deployments to GCP will require the following. + ## Prerequisites -- Google Cloud account -- gcloud CLI configured -- Terraform installed +- **Google Cloud CLI** - [Installation guide](https://cloud.google.com/sdk/docs/install) +- **Terraform** - [Installation guide](https://developer.hashicorp.com/terraform/install) +- **Suga CLI** - See [Installation](/installation) ## Quick Start @@ -34,7 +44,3 @@ Deploy: terraform init terraform apply ``` - - - See the full deployment workflow - From 4603244069323bbf291316ef3aacdc8539f8ae25 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:39:10 +1100 Subject: [PATCH 13/16] docs: add missing subtypes in config example --- docs/core/overview.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index 6ef6f3d2..9964e4ae 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -34,19 +34,23 @@ Projects are **deployment-agnostic** - they describe requirements without specif ```yaml title="Example: A simple web application" name: my-app +target: suga/aws@1 # Or any other target you like services: api: + subtype: lambda dev: script: npm run dev buckets: uploads: + subtype: s3 access: api: [read, write] entrypoints: web: + subtype: cloudfront routes: /api/: name: api From 39c76f05341bfac18078d13ef6acbc133f52d265 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:44:25 +1100 Subject: [PATCH 14/16] docs: add more subtype notes to config examples --- docs/develop/access-control.mdx | 4 ++++ docs/develop/buckets.mdx | 5 +++++ docs/develop/databases.mdx | 9 +++++---- docs/develop/entrypoints.mdx | 5 +++++ docs/develop/overview.mdx | 3 +++ docs/develop/services.mdx | 11 +++++++++++ 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/develop/access-control.mdx b/docs/develop/access-control.mdx index dd92285b..de83f9da 100644 --- a/docs/develop/access-control.mdx +++ b/docs/develop/access-control.mdx @@ -17,12 +17,14 @@ services: worker: ... buckets: uploads: + subtype: s3 access: api: [read, write] # API service can read and write worker: [read, delete] # Worker service can read and delete databases: main: + subtype: rds access: api: [query] # API service can query database ``` @@ -44,6 +46,7 @@ When you deploy, Suga generates: ```yaml buckets: data: + subtype: s3 access: uploader: [write] processor: [read, delete] @@ -57,6 +60,7 @@ buckets: ```yaml databases: main: + subtype: rds access: api: [query] analytics: [query] diff --git a/docs/develop/buckets.mdx b/docs/develop/buckets.mdx index 0613a0ef..7f1a249a 100644 --- a/docs/develop/buckets.mdx +++ b/docs/develop/buckets.mdx @@ -16,9 +16,11 @@ A bucket is object storage that: ```yaml title="Basic bucket definition" buckets: uploads: + subtype: # your choice, from target platform access: api: [read, write, delete] profile-images: + subtype: # your choice, from target platform access: api: [read, write] frontend: [read] @@ -33,6 +35,7 @@ Grant services access to buckets: ```yaml buckets: uploads: + subtype: # your choice, from target platform access: api: [read, write, delete] # Full access worker: [read, delete] # Read and delete only @@ -52,10 +55,12 @@ Deploy static files to a bucket: ```yaml buckets: frontend: + subtype: # your choice, from target platform content_path: ./build # Deploy React/Vue/Angular build entrypoints: web: + subtype: # your choice, from target platform routes: /: frontend # Serve static files from bucket ``` diff --git a/docs/develop/databases.mdx b/docs/develop/databases.mdx index 7ff8a497..0bbab59d 100644 --- a/docs/develop/databases.mdx +++ b/docs/develop/databases.mdx @@ -16,6 +16,7 @@ A database in Suga is a PostgreSQL database that: ```yaml title="Basic database" databases: main: + subtype: # your choice, from target platform access: api: [query] worker: [query] @@ -30,7 +31,7 @@ When you grant a service access to a database, Suga automatically injects the da ```yaml title="Database with environment variable injection" databases: main: - subtype: neon + subtype: # your choice, from target platform access: api: [query] worker: [query] @@ -52,19 +53,19 @@ When using multiple databases, each must have a unique `env_var_key` to avoid co ```yaml title="Multiple databases with unique env vars" databases: users: - subtype: neon + subtype: # your choice, from target platform access: api: [query] env_var_key: USERS_DATABASE_URL products: - subtype: neon + subtype: # your choice, from target platform access: api: [query] env_var_key: PRODUCTS_DATABASE_URL orders: - subtype: neon + subtype: # your choice, from target platform access: api: [query] env_var_key: ORDERS_DATABASE_URL diff --git a/docs/develop/entrypoints.mdx b/docs/develop/entrypoints.mdx index dde2070e..d2ba691e 100644 --- a/docs/develop/entrypoints.mdx +++ b/docs/develop/entrypoints.mdx @@ -16,6 +16,7 @@ An entrypoint is a CDN + router that: ```yaml title="Basic entrypoint" entrypoints: web: + subtype: # your choice, from target platform routes: /api/: name: api # Route /api/* to api service @@ -29,6 +30,7 @@ Routes map URL paths to destinations: ```yaml entrypoints: + subtype: # your choice, from target platform web: routes: /api/: @@ -59,6 +61,7 @@ Routes are evaluated in order - most specific first. ```yaml entrypoints: web: + subtype: # your choice, from target platform routes: /api/: name: api @@ -70,6 +73,7 @@ entrypoints: ```yaml entrypoints: gateway: + subtype: # your choice, from target platform routes: /users/: name: users-service @@ -83,6 +87,7 @@ entrypoints: ```yaml entrypoints: web: + subtype: # your choice, from target platform routes: /api/: name: api diff --git a/docs/develop/overview.mdx b/docs/develop/overview.mdx index bddef042..5c57ddaf 100644 --- a/docs/develop/overview.mdx +++ b/docs/develop/overview.mdx @@ -78,6 +78,7 @@ You can also edit `suga.yaml` directly: ```yaml title="suga.yaml" services: api: + subtype: # your choice, from target platform container: docker: dockerfile: Dockerfile @@ -141,12 +142,14 @@ Resources can grant access to services: ```yaml title="Grant service access to resources" buckets: uploads: + ... access: api: [read, write, delete] # API service can read/write/delete frontend: [read] # Frontend can only read databases: main: + ... access: api: [query] # API service can query the database ``` diff --git a/docs/develop/services.mdx b/docs/develop/services.mdx index 9a5d7f67..e1e20e02 100644 --- a/docs/develop/services.mdx +++ b/docs/develop/services.mdx @@ -16,6 +16,7 @@ A service is an application container that: ```yaml title="Basic service definition" services: api: + subtype: # your choice, from target platform dev: script: npm run dev container: @@ -35,12 +36,15 @@ The `dev.script` tells Suga how to run your service locally: ```yaml services: api: + subtype: # your choice, from target platform dev: script: npm run dev # Node.js worker: + subtype: # your choice, from target platform dev: script: python main.py # Python processor: + subtype: # your choice, from target platform dev: script: go run main.go # Go ``` @@ -55,6 +59,7 @@ For production deployment, services need container configuration: ```yaml services: api: + subtype: # your choice, from target platform container: docker: dockerfile: Dockerfile @@ -65,6 +70,7 @@ services: ```yaml services: api: + subtype: # your choice, from target platform container: image: id: "my-registry/api:latest" @@ -77,6 +83,7 @@ Configure services with environment variables: ```yaml services: api: + subtype: # your choice, from target platform env: DATABASE_URL: postgresql://... REDIS_URL: redis://... @@ -104,6 +111,7 @@ The `working_directory` property sets the base directory for the service. All ot ```yaml title="Service with working directory" services: api: + subtype: # your choice, from target platform working_directory: ./api dev: script: npm run dev # Runs from ./api directory @@ -122,6 +130,7 @@ Working directories are particularly useful in monorepo structures: ```yaml title="Monorepo with multiple services" services: api: + subtype: # your choice, from target platform working_directory: ./services/api dev: script: npm run dev @@ -133,6 +142,7 @@ services: SERVICE_NAME: api frontend: + subtype: # your choice, from target platform working_directory: ./services/frontend dev: script: npm run dev @@ -144,6 +154,7 @@ services: SERVICE_NAME: frontend worker: + subtype: # your choice, from target platform working_directory: ./services/worker dev: script: python main.py From 090de69168e61a52b233a835ee9a47b32f2250eb Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:47:14 +1100 Subject: [PATCH 15/16] chore: spelling and links --- docs/.vale/styles/config/vocabularies/Suga/accept.txt | 3 ++- docs/deploy/aws.mdx | 2 +- docs/deploy/gcp.mdx | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/.vale/styles/config/vocabularies/Suga/accept.txt b/docs/.vale/styles/config/vocabularies/Suga/accept.txt index 6d0c318c..4673fe43 100644 --- a/docs/.vale/styles/config/vocabularies/Suga/accept.txt +++ b/docs/.vale/styles/config/vocabularies/Suga/accept.txt @@ -304,4 +304,5 @@ Reusability Pulumi SREs DevOps -cicd \ No newline at end of file +cicd +enablement \ No newline at end of file diff --git a/docs/deploy/aws.mdx b/docs/deploy/aws.mdx index 517245ea..2360336a 100644 --- a/docs/deploy/aws.mdx +++ b/docs/deploy/aws.mdx @@ -46,6 +46,6 @@ terraform init terraform apply ``` - + See the full deployment workflow diff --git a/docs/deploy/gcp.mdx b/docs/deploy/gcp.mdx index 4a4a6af3..911e68c8 100644 --- a/docs/deploy/gcp.mdx +++ b/docs/deploy/gcp.mdx @@ -44,3 +44,7 @@ Deploy: terraform init terraform apply ``` + + + See the full deployment workflow + \ No newline at end of file From b1eef9725b5378db44d177ef6816fb16ea3c39b7 Mon Sep 17 00:00:00 2001 From: Jye Cusch Date: Thu, 13 Nov 2025 11:52:18 +1100 Subject: [PATCH 16/16] docs: update overview doc sidebar titles --- docs/core/overview.mdx | 1 + docs/deploy/overview.mdx | 3 ++- docs/develop/overview.mdx | 1 + docs/docs.json | 2 +- docs/{guides.mdx => guides/overview.mdx} | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) rename docs/{guides.mdx => guides/overview.mdx} (98%) diff --git a/docs/core/overview.mdx b/docs/core/overview.mdx index 9964e4ae..88a8d88a 100644 --- a/docs/core/overview.mdx +++ b/docs/core/overview.mdx @@ -1,5 +1,6 @@ --- title: "Core Concepts Overview" +sidebarTitle: "Overview" description: "Understanding Suga's architecture and core concepts" --- diff --git a/docs/deploy/overview.mdx b/docs/deploy/overview.mdx index 3ec974cf..e26e9269 100644 --- a/docs/deploy/overview.mdx +++ b/docs/deploy/overview.mdx @@ -1,5 +1,6 @@ --- -title: "Deployment" +title: "Deployment Overview" +sidebarTitle: "Overview" description: "Understand how Suga applications are deployed to the cloud" --- diff --git a/docs/develop/overview.mdx b/docs/develop/overview.mdx index 5c57ddaf..4b162c14 100644 --- a/docs/develop/overview.mdx +++ b/docs/develop/overview.mdx @@ -1,5 +1,6 @@ --- title: "Development Overview" +sidebarTitle: "Overview" description: "Understanding Suga's resource types and how to define your application architecture" --- diff --git a/docs/docs.json b/docs/docs.json index 26249542..ae338f53 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -57,7 +57,7 @@ { "group": "Guides", "pages": [ - "guides", + "guides/overview", "guides/add-suga", "guides/static-website-hosting", "guides/personal-access-tokens", diff --git a/docs/guides.mdx b/docs/guides/overview.mdx similarity index 98% rename from docs/guides.mdx rename to docs/guides/overview.mdx index aa4fb9b8..02aa8553 100644 --- a/docs/guides.mdx +++ b/docs/guides/overview.mdx @@ -1,5 +1,6 @@ --- title: "Guides Overview" +sidebarTitle: "Overview" description: "Learn how to leverage Suga for common infrastructure patterns and workflows" ---