encore-go-infrastructure
Declare infrastructure with Encore Go.
Works with
---
name: encore-go-infrastructure
description: Declare infrastructure with Encore Go.
license: Apache-2.0
---
# Encore Go Infrastructure Declaration
## Instructions
Encore Go uses declarative infrastructure - you define resources as package-level variables and Encore handles provisioning:
- **Locally** (`encore run`) - Encore runs infrastructure in Docker (Postgres, Redis, etc.)
- **Production** - Deploy via [Encore Cloud](https://encore.dev/cloud) to your AWS/GCP, or self-host using generated infrastructure config
### Critical Rule
**All infrastructure must be declared at package level, not inside functions.**
## Databases (PostgreSQL)
```go
package user
import "encore.dev/storage/sqldb"
// CORRECT: Package level
var db = sqldb.NewDatabase("userdb", sqldb.DatabaseConfig{
Migrations: "./migrations",
})
// WRONG: Inside function
func setup() {
db := sqldb.NewDatabase("userdb", sqldb.DatabaseConfig{...})
}
```
### Migrations
Create migrations in the `migrations/` directory:
```
user/
├── user.go
├── db.go
└── migrations/
├── 1_create_users.up.sql
└── 2_add_email_index.up.sql
```
Migration naming: `{number}_{description}.up.sql`
## Pub/Sub
### Topics
```go
package events
import "encore.dev/pubsub"
type OrderCreatedEvent struct {
OrderID string `json:"order_id"`
UserID string `json:"user_id"`
Total int `json:"total"`
}
// Package level declaration
var OrderCreated = pubsub.NewTopic[*OrderCreatedEvent]("order-created", pubsub.TopicConfig{
DeliveryGuarantee: pubsub.AtLeastOnce,
})
```
### Publishing
```go
msgID, err := events.OrderCreated.Publish(ctx, &events.OrderCreatedEvent{
OrderID: "123",
UserID: "user-456",
Total: 9999,
})
```
### Subscriptions
```go
package notifications
import (
"context"
"myapp/events"
"encore.dev/pubsub"
)
var _ = pubsub.NewSubscription(events.OrderCreated, "send-confirmation-email",
pubsub.SubscriptionConfig[*events.OrderCreatedEvent]{
Handler: sendConfirmationEmail,
},
)
func sendConfirmationEmail(ctx context.Context, event *events.OrderCreatedEvent) error {
// Send email...
return nil
}
```
### Topic References
Pass topic access to library code while maintaining static analysis:
```go
// Create a reference with publish permission
ref := pubsub.TopicRef[pubsub.Publisher[*OrderCreatedEvent]](OrderCreated)
// Use the reference in library code
func publishEvent(ref pubsub.Publisher[*OrderCreatedEvent], event *OrderCreatedEvent) error {
_, err := ref.Publish(ctx, event)
return err
}
```
## Cron Jobs
```go
package cleanup
import (
"context"
"encore.dev/cron"
)
// The cron job declaration
var _ = cron.NewJob("cleanup-sessions", cron.JobConfig{
Title: "Clean up expired sessions",
Schedule: "0 * * * *", // Every hour
Endpoint: CleanupExpiredSessions,
})
//encore:api private
func CleanupExpiredSessions(ctx context.Context) error {
// Cleanup logic
return nil
}
```
### Schedule Formats
| Format | Example | Description |
|--------|---------|-------------|
| Cron expression | `"0 9 * * 1"` | 9am every Monday |
| Every interval | `"every 1h"` | Every hour |
| Every interval | `"every 30m"` | Every 30 minutes |
## Object Storage
```go
package uploads
import "encore.dev/storage/objects"
// Package level
var Uploads = objects.NewBucket("user-uploads", objects.BucketConfig{})
// Public bucket
var PublicAssets = objects.NewBucket("public-assets", objects.BucketConfig{
Public: true,
})
```
### Operations
```go
// Upload (streaming pattern)
writer := Uploads.Upload(ctx, "path/to/file.jpg")
_, err := io.Copy(writer, dataReader)
if err != nil {
writer.Abort()
return err
}
err = writer.Close()
// Download
reader := Uploads.Download(ctx, "path/to/file.jpg")
if err := reader.Err(); err != nil {
return err
}
defer reader.Close()
data, _ := io.ReadAll(reader)
// Check existence
exists, err := Uploads.Exists(ctx, "path/to/file.jpg")
// Get attributes (size, content type, ETag)
attrs, err := Uploads.Attrs(ctx, "path/to/file.jpg")
// List objects
for err, entry := range Uploads.List(ctx, &objects.Query{}) {
if err != nil {
return err
}
fmt.Println(entry.Key, entry.Size)
}
// Delete
err := Uploads.Remove(ctx, "path/to/file.jpg")
// Public URL (only for public buckets)
url := PublicAssets.PublicURL("image.jpg")
```
### Signed URLs
Generate temporary URLs for upload/download without exposing your bucket:
```go
import "time"
// Signed upload URL (expires in 2 hours)
url, err := Uploads.SignedUploadURL(ctx, "user-uploads/avatar.jpg",
objects.WithTTL(time.Duration(7200)*time.Second))
// Signed download URL
url, err := Uploads.SignedDownloadURL(ctx, "documents/report.pdf",
objects.WithTTL(time.Duration(7200)*time.Second))
```
### Bucket References
Pass bucket access with specific permissions to library code:
```go
// Create a reference with download permission only
ref := objects.BucketRef[objects.Downloader](Uploads)
// Create a reference with multiple permissions
type myPerms interface {
objects.Downloader
objects.Uploader
}
ref := objects.BucketRef[myPerms](Uploads)
// Permission types: Downloader, Uploader, Lister, Attrser, Remover,
// SignedDownloader, SignedUploader, ReadWriter
```
## Secrets
```go
package email
var secrets struct {
SendGridAPIKey string
SMTPPassword string
}
func sendEmail() error {
apiKey := secrets.SendGridAPIKey
// Use the secret...
}
```
Set secrets via CLI:
```bash
encore secret set --type prod SendGridAPIKey
```
## Config Values
```go
package myservice
import "encore.dev/config"
var cfg struct {
MaxRetries config.Int
BaseURL config.String
Debug config.Bool
}
func doSomething() {
if cfg.Debug() {
log.Println("Debug mode enabled")
}
}
```
## Guidelines
- Infrastructure declarations MUST be at package level
- Use descriptive names for resources
- Keep migrations sequential and numbered
- Subscription handlers must be idempotent (at-least-once delivery)
- Secrets are accessed by calling them as functions
- Cron endpoints should be `private` (internal only)
- Each service typically has its own databaseMore DevOps & Infrastructure skills
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
appinsights-instrumentation
microsoft/azure-skills
Guidance for instrumenting webapps with Azure Application Insights. Provides telemetry patterns, SDK setup, and configuration references. WHEN: how to instrument app, App Insights SDK, telemetry patterns, what is App Insights, Application Insights guidance, instrumentation examples, APM best practices.
azure-storage
microsoft/azure-skills
Azure Storage Services including Blob Storage, File Shares, Queue Storage, Table Storage, and Data Lake. Answers questions about storage access tiers (hot, cool, cold, archive), when to use each tier, and tier comparison. Provides object storage, SMB file shares, async messaging, NoSQL key-value, and big data analytics. Includes lifecycle management. USE FOR: blob storage, file shares, queue storage, table storage, data lake, upload files, download blobs, storage accounts, access tiers, storage tiers, hot cool cold archive, storage tier comparison, when to use storage tiers, lifecycle management, Azure Storage concepts. DO NOT USE FOR: SQL databases, Cosmos DB (use azure-prepare), messaging with Event Hubs or Service Bus (use azure-messaging).

