stackfile

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package stackfile implements doze-aws's declarative resource file: a stack.yaml a team commits to their repo so `doze-aws apply stack.yaml` (or `doze-aws --stack stack.yaml`) stands the whole local stack up.

Design choices, deliberately:

  • Resources are named by map key and wired by NAME, not ARN — inside one local account/region names are unambiguous, and the file reads like the console.
  • Apply is CONVERGENT: create what's missing, update what's cheap to update, and never touch values a human may have changed (secrets and parameters keep their live value unless `force: true`).
  • Dependency order is fixed by phase (queues before the topics that subscribe to them, functions before the rules that target them, bucket notifications last) so references always resolve.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(s *Stack) ([]byte, error)

Marshal renders a Stack back to YAML (used by export).

Types

type Action

type Action struct {
	Op       string // created | updated | skipped
	Resource string // e.g. "queue/orders"
	Detail   string
}

Action is one thing Apply did (or decided not to do).

type Bucket

type Bucket struct {
	Versioning bool              `yaml:"versioning,omitempty"`
	ObjectLock bool              `yaml:"object_lock,omitempty"`
	Notify     []Notify          `yaml:"notify,omitempty"`
	CORS       []CORSRule        `yaml:"cors,omitempty"`
	Lifecycle  []LifecycleRule   `yaml:"lifecycle,omitempty"`
	Website    *Website          `yaml:"website,omitempty"`
	Tags       map[string]string `yaml:"tags,omitempty"`
}

type CORSRule

type CORSRule struct {
	Origins []string `yaml:"origins"`
	Methods []string `yaml:"methods"`
	Headers []string `yaml:"headers,omitempty"`
	Expose  []string `yaml:"expose,omitempty"`
	MaxAge  int      `yaml:"max_age,omitempty"`
}

CORSRule mirrors one S3 CORSRule; preflight evaluation is real locally.

type Dest

type Dest struct {
	Queue  string `yaml:"queue,omitempty"`
	Topic  string `yaml:"topic,omitempty"`
	Lambda string `yaml:"lambda,omitempty"`
}

Dest names exactly one destination kind.

type Doc

type Doc struct {
	JSON string
}

Doc is a JSON document that may be written as inline YAML or a JSON string.

func (Doc) IsZero

func (d Doc) IsZero() bool

func (Doc) MarshalYAML

func (d Doc) MarshalYAML() (any, error)

func (*Doc) UnmarshalYAML

func (d *Doc) UnmarshalYAML(n *yaml.Node) error

type Function

type Function struct {
	Runtime   string            `yaml:"runtime,omitempty"`
	Handler   string            `yaml:"handler,omitempty"`
	Code      string            `yaml:"code,omitempty"` // local path (the _local_ extension)
	Command   []string          `yaml:"command,omitempty"`
	Env       map[string]string `yaml:"env,omitempty"`
	Timeout   int               `yaml:"timeout,omitempty"`
	Memory    int               `yaml:"memory,omitempty"`
	DLQ       *Dest             `yaml:"dlq,omitempty"`     // DeadLetterConfig: where exhausted async invokes land
	Retries   *int              `yaml:"retries,omitempty"` // async MaximumRetryAttempts (0–2, default 2)
	OnSuccess *Dest             `yaml:"on_success,omitempty"`
	OnFailure *Dest             `yaml:"on_failure,omitempty"`
	Triggers  []Trigger         `yaml:"triggers,omitempty"`
	Tags      map[string]string `yaml:"tags,omitempty"`
}

type GSI

type GSI struct {
	Key        string   `yaml:"key"`                  // same shorthand as Table.Key
	Projection string   `yaml:"projection,omitempty"` // ALL (default) | KEYS_ONLY | INCLUDE
	Include    []string `yaml:"include,omitempty"`    // non-key attributes, with projection: INCLUDE
}

type Key

type Key struct {
	Spec        string            `yaml:"spec,omitempty"`  // default SYMMETRIC_DEFAULT
	Usage       string            `yaml:"usage,omitempty"` // ENCRYPT_DECRYPT | SIGN_VERIFY | GENERATE_VERIFY_MAC (default per spec)
	Description string            `yaml:"description,omitempty"`
	Rotation    bool              `yaml:"rotation,omitempty"`
	Tags        map[string]string `yaml:"tags,omitempty"`
}

type LSI

type LSI struct {
	Key        string   `yaml:"key"` // the sort key, "attr:TYPE"
	Projection string   `yaml:"projection,omitempty"`
	Include    []string `yaml:"include,omitempty"`
}

LSI declares a local secondary index: the table's partition key plus this sort key.

type LifecycleRule

type LifecycleRule struct {
	Prefix          string `yaml:"prefix,omitempty"`
	ExpireDays      int    `yaml:"expire_days,omitempty"`
	NoncurrentDays  int    `yaml:"noncurrent_days,omitempty"`
	AbortUploadDays int    `yaml:"abort_uploads_days,omitempty"`
}

LifecycleRule covers the expiry rules the local janitor actually enforces: current-version expiry, noncurrent-version expiry, and stale-multipart abort.

type Notify

type Notify struct {
	Events []string `yaml:"events,omitempty"` // default ["s3:ObjectCreated:*"]
	Prefix string   `yaml:"prefix,omitempty"`
	Suffix string   `yaml:"suffix,omitempty"`
	Queue  string   `yaml:"queue,omitempty"`
	Topic  string   `yaml:"topic,omitempty"`
	Lambda string   `yaml:"lambda,omitempty"`
}

Notify wires bucket events to exactly one destination kind.

type Parameter

type Parameter struct {
	Value       string            `yaml:"value,omitempty"`
	Type        string            `yaml:"type,omitempty"` // String | SecureString | StringList
	Description string            `yaml:"description,omitempty"`
	Force       bool              `yaml:"force,omitempty"`
	Tags        map[string]string `yaml:"tags,omitempty"`
}

Parameter accepts a scalar shorthand:

parameters:
  /app/db/host: localhost

func (*Parameter) UnmarshalYAML

func (p *Parameter) UnmarshalYAML(n *yaml.Node) error

type Queue

type Queue struct {
	FIFO         bool              `yaml:"fifo,omitempty"`
	ContentDedup bool              `yaml:"content_dedup,omitempty"`
	DLQ          string            `yaml:"dlq,omitempty"` // "auto" or a queue name
	MaxReceives  int               `yaml:"max_receives,omitempty"`
	Visibility   int               `yaml:"visibility,omitempty"`
	Delay        int               `yaml:"delay,omitempty"`
	Retention    int               `yaml:"retention,omitempty"`
	ReceiveWait  int               `yaml:"receive_wait,omitempty"` // long-poll default, seconds
	MaxSize      int               `yaml:"max_size,omitempty"`     // MaximumMessageSize, bytes
	Tags         map[string]string `yaml:"tags,omitempty"`
}

type Report

type Report struct {
	Actions []Action
}

Report is the full apply outcome.

func Apply

func Apply(ctx context.Context, gateway http.Handler, s *Stack) (*Report, error)

Apply converges the running stack toward the file: resources are created if missing and cheaply updated if present; nothing is ever deleted. Phases run in dependency order so references by name always resolve.

func (*Report) Counts

func (r *Report) Counts() (created, updated, skipped int)

Counts summarizes the report as created/updated/skipped.

type Rule

type Rule struct {
	Bus      string   `yaml:"bus,omitempty"` // default "default"
	Pattern  Doc      `yaml:"pattern,omitempty"`
	Schedule string   `yaml:"schedule,omitempty"`
	Enabled  *bool    `yaml:"enabled,omitempty"` // default true; false stores the rule DISABLED
	Targets  []Target `yaml:"targets,omitempty"`
}

type Secret

type Secret struct {
	Value       string            `yaml:"value,omitempty"`
	Binary      string            `yaml:"binary,omitempty"` // base64 SecretBinary (instead of value)
	Description string            `yaml:"description,omitempty"`
	Force       bool              `yaml:"force,omitempty"` // overwrite a live value on apply
	Tags        map[string]string `yaml:"tags,omitempty"`
}

type Stack

type Stack struct {
	// Vars feed ${var:name} references; `doze-aws apply --var name=value`
	// overrides them. Values may themselves use ${env:...}.
	Vars       map[string]string    `yaml:"vars,omitempty"`
	Queues     map[string]Queue     `yaml:"queues,omitempty"`
	Topics     map[string]Topic     `yaml:"topics,omitempty"`
	Buckets    map[string]Bucket    `yaml:"buckets,omitempty"`
	Tables     map[string]Table     `yaml:"tables,omitempty"`
	Functions  map[string]Function  `yaml:"functions,omitempty"`
	Rules      map[string]Rule      `yaml:"rules,omitempty"`
	Keys       map[string]Key       `yaml:"keys,omitempty"`
	Secrets    map[string]Secret    `yaml:"secrets,omitempty"`
	Parameters map[string]Parameter `yaml:"parameters,omitempty"`
}

Stack is the parsed stack.yaml.

func Export

func Export(ctx context.Context, gateway http.Handler) (*Stack, error)

Export reads the running stack and renders it as a Stack — the inverse of Apply, so a team can click a stack together in the console and commit the file. Secret and SecureString values are deliberately NOT exported; the header comment in Marshal explains the blank.

func Parse

func Parse(data []byte) (*Stack, error)

Parse decodes and validates a stack.yaml, resolving ${env:...} and ${var:...} references first.

func ParseWithVars

func ParseWithVars(data []byte, overrides map[string]string) (*Stack, error)

ParseWithVars is Parse with --var overrides for ${var:...} references.

type Subscription

type Subscription struct {
	Queue  string `yaml:"queue,omitempty"`
	Lambda string `yaml:"lambda,omitempty"`
	HTTP   string `yaml:"http,omitempty"`
	Filter Doc    `yaml:"filter,omitempty"` // SNS filter policy (inline YAML or JSON string)
	Raw    bool   `yaml:"raw,omitempty"`    // raw message delivery
}

Subscription names exactly one endpoint kind.

type Table

type Table struct {
	Key                string            `yaml:"key"` // "pk:S" or "pk:S sk:N"
	TTL                string            `yaml:"ttl,omitempty"`
	GSIs               map[string]GSI    `yaml:"gsis,omitempty"`
	LSIs               map[string]LSI    `yaml:"lsis,omitempty"`
	DeletionProtection *bool             `yaml:"deletion_protection,omitempty"`
	Tags               map[string]string `yaml:"tags,omitempty"`
}

type Target

type Target struct {
	Queue  string `yaml:"queue,omitempty"`
	Topic  string `yaml:"topic,omitempty"`
	Lambda string `yaml:"lambda,omitempty"`

	Input     Doc               `yaml:"input,omitempty"`      // literal event to deliver instead
	InputPath string            `yaml:"input_path,omitempty"` // JSONPath into the event, e.g. $.detail
	Template  string            `yaml:"template,omitempty"`   // InputTransformer template with <name> slots
	Paths     map[string]string `yaml:"paths,omitempty"`      // InputTransformer name → JSONPath
}

Target is one rule target: the "queue:orders" / "topic:t" / "lambda:fn" scalar shorthand, or a mapping that adds input shaping:

targets:
  - queue: audit
  - lambda: resize
    input_path: $.detail
  - topic: alerts
    template: '{"msg": <msg>}'
    paths: {msg: $.detail.message}

func (Target) MarshalYAML

func (t Target) MarshalYAML() (any, error)

func (*Target) UnmarshalYAML

func (t *Target) UnmarshalYAML(n *yaml.Node) error

type Topic

type Topic struct {
	Subscriptions []Subscription    `yaml:"subscriptions,omitempty"`
	Tags          map[string]string `yaml:"tags,omitempty"`
}

type Trigger

type Trigger struct {
	Queue   string `yaml:"queue"`
	Batch   int    `yaml:"batch,omitempty"`
	Enabled *bool  `yaml:"enabled,omitempty"` // default true; false parks the poller
}

type Website

type Website struct {
	Index string `yaml:"index,omitempty"` // IndexDocument suffix, e.g. index.html
	Error string `yaml:"error,omitempty"` // ErrorDocument key, e.g. 404.html
}

Website enables bucket-website index/error document serving.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL