Suga helps you migrate existing applications to a cloud-agnostic architecture. With Suga, you get local development with local emulation of cloud services, the ability to deploy anywhere - AWS or GCP from the same code, and auto-generated Terraform for production-ready infrastructure. This guide walks through migrating a Go web service as an example that can be easily adapted to other languages and services.
Prerequisites: Make sure you have the Suga CLI installed. This guide assumes you have an existing application that uses cloud services. If you’re starting fresh, see the Getting Started Guide.

Initialize Suga Project

Navigate to your existing project directory and initialize Suga:
Login to Suga
suga login
Initialize Project
suga init
When prompted, provide:
  • Project name: my-app (or your preferred name)
  • Description: Brief description of your application
This creates a suga.yaml configuration file in your project root.

Configure Infrastructure

Open the Suga visual editor to design your infrastructure:
Open Suga Editor
suga edit
Build your infrastructure visually:
  1. Drag an entrypoint onto the canvas and name it ingress
  2. Add a service named app and connect the entrypoint to it
  3. Add a bucket named files and connect the service to it
  4. Configure bucket permissions to include read, write, and delete
  5. Configure the service with a command to run locally (e.g., go run main.go or npm run dev) Infrastructure Design
This generates your suga.yaml configuration:
suga.yaml
targets:
  - suga/aws@1
name: my-app
description: Your application description
services:
  app:
    container:
      docker:
        dockerfile: Dockerfile
        context: .
    dev:
      script: go run main.go
buckets:
  files:
    access:
      app:
        - all
entrypoints:
  ingress:
    routes:
      /:
        name: app
The visual editor automatically maintains valid YAML syntax and ensures proper resource relationships.

Add Container Support

Create a Dockerfile for production deployment:
Dockerfile
FROM golang:1.24-alpine as builder

WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/main .
ENTRYPOINT ["/main"]
If you already have a Dockerfile, ensure it’s referenced correctly in your suga.yaml configuration.

Generate SDK and Migrate Code

Generate the Suga SDK for your project:
Generate Go SDK
suga generate --go --go-out ./suga --go-package-name suga
Update Dependencies
go mod tidy
Now migrate your application code. Here’s a complete example showing the transformation:
main.go
package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    // Load AWS configuration
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatalf("Failed to load AWS config: %v", err)
    }

    // Create S3 client
    s3Client := s3.NewFromConfig(cfg)
    bucketName := os.Getenv("S3_BUCKET_NAME")

    router := http.NewServeMux()
    router.HandleFunc("GET /hello/{name}", func(w http.ResponseWriter, r *http.Request) {
        name := r.PathValue("name")

        // AWS S3 PutObject
        _, err := s3Client.PutObject(context.TODO(), &s3.PutObjectInput{
            Bucket: aws.String(bucketName),
            Key:    aws.String("example.txt"),
            Body:   strings.NewReader("Hello, " + name + "!"),
        })
        if err != nil {
            log.Printf("Failed to upload to S3: %v", err)
            http.Error(w, "Error uploading to S3", http.StatusInternalServerError)
            return
        }

        fmt.Fprintf(w, "Hello, %s!", name)
    })

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    log.Printf("Server starting on port %s\n", port)
    log.Fatal(http.ListenAndServe(":"+port, router))
}
Remove all cloud provider SDK dependencies after migration to avoid conflicts and reduce bundle size.

Test Locally

Start the Suga development environment:
Start Development Server
suga dev
Test your migrated application:
Test Endpoint
curl http://localhost:3000/hello/world
Expected response:
Hello, world!
Suga dev provides local emulation of cloud services. Files are stored locally during development and in real cloud storage when deployed.

Deploy to Cloud

Build your application and generate Terraform:
Build Application
suga build
Select your cloud provider and region when prompted. You’ll see:
 Terraform generated successfully
  output written to ./.suga/stacks/my-app-aws-12345

Next steps:
1. Run cd ./.suga/stacks/my-app-aws-12345 to move to the stack directory
2. Initialize the stack terraform init -upgrade
3. Optionally, preview with terraform plan
4. Deploy with terraform apply
Configure cloud provider credentials:
Configure AWS
aws configure
Deploy with Terraform:
Navigate to Stack
cd .suga/stacks/my-app-aws-*
Initialize Terraform
terraform init -upgrade
Preview Changes
terraform plan
Deploy Infrastructure
terraform apply
Type yes when prompted. After deployment completes, your application endpoints will be displayed in the output.
Your application is now cloud-agnostic. Deploy to AWS or GCP without code changes.

Next Steps

  • Add more resources like databases or queues to your suga.yaml
  • Configure environment-specific settings for staging and production
  • Explore Suga’s monitoring and observability features