Skip to content

Configuration Reference ​

Everything ServerlessInsight does is expressed through a single serverlessinsight.yml. The file is both a deployment blueprint the si CLI executes and a reviewable record of your infrastructure: you declare what you need, the CLI provisions it on the target cloud, and on subsequent deploys it diffs against the last state and only changes what actually changed.

This reference walks the file top-down: first the global skeleton (version, provider, variables, stages), then each of the five resource kinds: functions, events, databases, tables, buckets. For every resource we answer three questions: what it is, when to use it, and how each field is filled.

Use the on-page outline in the browser sidebar for quick field lookups; si validate checks every constraint below before anything is deployed.

Quick Example ​

This configuration covers what most real projects need: one HTTP function, an API gateway entry, and a pay-per-use MySQL. Read it for the overall shape; each block is explained below:

yaml
version: 0.1.0
provider:
  name: aliyun
  region: cn-hangzhou

vars:
  db_password: "${ctx.stage}-secret"

stages:
  dev:
    memory: 256
  prod:
    memory: 1024

app: my-app
service: my-app-api

tags:
  owner: geek-fun

functions:
  api_function:
    name: my-api-function
    code:
      runtime: nodejs18
      handler: index.handler
      path: artifacts/api.zip
    memory: ${stages.memory}
    timeout: 30
    environment:
      NODE_ENV: production

events:
  api_gateway:
    name: my-api-gateway
    type: API_GATEWAY
    triggers:
      - method: GET
        path: /api/*
        backend: api_function

databases:
  main_db:
    name: main-db
    type: RDS_MYSQL_SERVERLESS
    version: MYSQL_8.0
    cu:
      min: 0
      max: 8
    security:
      basic_auth:
        master_user: dbadmin
        password: "${vars.db_password}"

Division of labor in this file: provider decides which cloud and region everything lands in; vars and stages pull environment-specific values out of resource definitions; functions + events form the classic "function + HTTP entry" server shape; databases declares the data layer the functions depend on. app and service prefix every cloud resource name; they identify the whole stack.

Core Configuration ​

version ​

The version of the config format itself, not your app's version. The CLI uses it to decide how to parse the file; fields may be incompatible across major versions.

yaml
version: 0.1.0

Valid values: 0.0.0, 0.0.1, 0.1.0. New projects should use 0.1.0.

provider ​

Declares the target cloud and region. Every resource in the file is created in this region; deploying to multiple regions means maintaining multiple configs.

yaml
provider:
  name: aliyun
  region: cn-hangzhou
FieldTypeRequiredDescription
namestring✅aliyun / tencent / volcengine / huawei / aws
regionstring✅Deployment region

Providers you can actually deploy to today are aliyun, tencent, and volcengine; huawei and aws exist in the enum only and are not yet deployable (Huawei can currently only generate Terraform templates, and deploy throws).

Per-platform capability matrix. The same config lands as different cloud services per platform, so check what your target platform supports before writing config:

Resource typeAliyunTencent CloudVolcengine
FunctionsFC3SCFVeFaaS
Object storageOSSCOSTOS
API gateway / eventsAPI Gatewayno standalone gateway (function URL)API Gateway
DatabasesRDS Serverless, ES ServerlessTDSQL-C Serverless, ES Serverless—
Table storageTableStore——
CDNyes (OSS + APIGW)nono
Custom domainsyesyes (DNSPod)APIGW domains only

Command support differences:

CommandAliyunTencent CloudVolcengine
validate✅✅✅
plan✅✅❌
deploy / destroy✅✅✅
local✅ (local emulation)❌❌
show✅✅✅

Regions and credentials (switch via the platform selector at the top of the page):

Regions are strictly validated, only these are accepted: cn-qingdao cn-beijing cn-zhangjiakou cn-huhehaote cn-wulanchabu cn-hangzhou cn-shanghai cn-shenzhen cn-heyuan cn-guangzhou cn-chengdu cn-hongkong ap-southeast-1/3/5/6/7 ap-northeast-1/2 eu-central-1 eu-west-1 us-east-1 us-west-1 na-south-1 me-east-1 me-central-1. Default cn-hangzhou; precedence SI_REGION > ALIYUN_REGION > provider.region.

Credential environment variables (both alias groups are equivalent):

VariableDescription
ALIYUN_ACCESS_KEY_ID or ALIBABA_CLOUD_ACCESS_KEY_IDAccessKey ID
ALIYUN_ACCESS_KEY_SECRET or ALIBABA_CLOUD_ACCESS_KEY_SECRETAccessKey Secret
ALIYUN_SECURITY_TOKEN or ALIBABA_CLOUD_SECURITY_TOKENSTS session token (optional)

Regions are free-form text (e.g. ap-guangzhou, ap-shanghai, ap-beijing) and are not enum-validated.

VariableDescription
TENCENTCLOUD_SECRET_IDSecretId
TENCENTCLOUD_SECRET_KEYSecretKey
TENCENTCLOUD_SECURITY_TOKENsession token (optional)

Recommended regions: cn-beijing, cn-shanghai, cn-guangzhou, ap-southeast-1; default cn-beijing (not strictly validated).

Credential environment variables (multiple equivalent aliases):

VariableDescription
VOLCENGINE_ACCESS_KEY_ID or VOLCENGINE_ACCESS_KEY or VOLCSTACK_ACCESS_KEY_IDAccessKey ID
VOLCENGINE_ACCESS_KEY_SECRET or VOLCENGINE_SECRET_KEY or VOLCSTACK_SECRET_ACCESS_KEYAccessKey Secret
VOLCENGINE_SESSION_TOKEN or VOLCSTACK_SESSION_TOKENsession token (optional)

The CLI flags -k/--accessKeyId, -x/--accessKeySecret, -n/--securityToken override environment variables on every platform.

vars ​

The global variable area. Pull values that change (passwords, domains, sizes) out of resource definitions into one place. Referenced as ${vars.name}.

yaml
vars:
  db_host: db.example.com
  memory_size: 512

Values can be overridden at deploy time with -p, which is how secrets stay out of the file:

bash
si deploy --stage prod -p db_password=xxxx

stages ​

Per-environment configuration. Each stage is a set of overrides; the same resource definitions pick up different memory, domains, or regions per environment. Select with --stage / -s; default is used when omitted.

yaml
stages:
  dev:
    memory: 256
  prod:
    memory: 1024

Reference the current stage's values with ${stages.field}:

yaml
functions:
  api_function:
    memory: ${stages.memory}

${ctx.stage} is a built-in context variable holding the current stage name, handy for environment-suffixed resource names like user-api-${ctx.stage}.

app ​

The application name is the top-level namespace that identifies your project. It must be a static string: it participates in all cloud resource naming, and the CLI must resolve it before any variable interpolation.

yaml
app: my-app

Naming rules: starts with a lowercase letter, contains only lowercase letters, digits, and -.

service ​

The service name. Where app answers "which project", service answers "which independently deployable unit of it". It prefixes resource IDs and names, so keep it short. Also must be a static string.

yaml
service: my-app-api

service is not the same as the CLI's <stackName>: service lives in the config and drives naming; stackName is given at deploy time and locates the state file.

tags ​

Resource tags. The CLI attaches these key-values to every cloud resource it creates, for cost allocation and resource search.

yaml
tags:
  owner: geek-fun
  environment: ${ctx.stage}

backend ​

The state backend. si deploy relies on a state file recording what the last deployment created, enabling incremental updates and resource teardown. By default ServerlessInsight uses its managed SaaS state backend (authenticate via si login or SI_API_KEY); teams that self-manage can switch to object storage:

yaml
backend:
  state_manager:
    type: BUCKET_STORE
    bucket: my-state-bucket
    key: si-state/
FieldTypeRequiredDescription
state_manager.typestring❌LOCAL (local file) or BUCKET_STORE (object storage); omitted = managed SaaS
state_manager.bucketstring⚠️required when BUCKET_STORE
state_manager.keystring❌state file path

Resource Types ​

functions ​

Functions are the core resource. The config key (e.g. hello_world_fn) is the reference name; fields like events.triggers.backend point at functions by it. The inner name is the actual cloud function name and is required.

A function has one of two deployment shapes, mutually exclusive: a code package (code) or a container image (container). Most business logic uses code; custom runtimes, native libraries, or long-running processes call for container.

yaml
functions:
  hello_world_fn:
    name: hello-world-fn
    code:
      runtime: nodejs18
      handler: index.handler
      path: artifacts/hello-world-api.zip
    memory: 512
    timeout: 10
    environment:
      NODE_ENV: prod

Top-level fields:

FieldTypeRequiredDescription
namestring✅cloud function name
codeobject⚠️code package deployment (either this or container)
containerobject⚠️container image deployment (either this or code)
memorynumber❌memory (MB), default 128
timeoutnumber❌timeout (seconds), default 3
gpustring❌GPU spec, see below
logboolean❌enable logging
environmentobject❌environment variables; values are string / number / boolean
networkobject❌VPC networking
iamobject❌execution role and grants
triggersobject❌function-level triggers (HTTP)
domainobject❌function-level custom domain
storageobject❌disk and NAS mounts

code and container are mutually exclusive; providing both is not a supported combination.

code - Code Deployment ​

yaml
code:
  runtime: nodejs18
  handler: index.handler
  path: artifacts/hello-world-api.zip

runtime selects the execution environment on the cloud, handler is the entry in file.exportedFunction form, and path points at the build artifact (relative to project root, usually under artifacts/).

Runtime values (switch per platform; validate / plan checks against the chosen provider):

Aliyun FC: nodejs20 nodejs18 nodejs16 nodejs14 nodejs12 nodejs10, python3.12 python3.10 python3.9 python3.6, java11 java8, php7.2, go1, dotnet_core3.1

Tencent Cloud SCF: nodejs18 nodejs16 nodejs14 nodejs12 nodejs10, python3.10 python3.9 python3.7 python3.6, java8, php8.0 php7.4 php7.2 php5.6, go1

Volcengine veFaaS: golang/v1 native/v1 nativejava8/v1 node14/v1 node20/v1 nodeprime14/v1 python3.12/v1 python3.9/v1 native-python3.12/v1 native-node20/v1

The config always uses the standard identifiers (e.g. nodejs18); the CLI maps them to each cloud's native runtime at build time (e.g. Tencent's Nodejs18.15). Volcengine is the exception and uses its native identifiers directly. After switching platforms, re-check runtime against the list above.

container - Container Deployment ​

yaml
container:
  image: registry.cn-hangzhou.aliyuncs.com/my-repo/my-image:latest
  port: 9000
  cmd: ["node", "server.js"]
FieldTypeRequiredDescription
imagestring✅image address (must be pullable by the provider)
portnumber✅HTTP port your service listens on inside the container
cmdstring[]❌override the image's default entry command

In container mode there is no handler; the platform forwards requests to the HTTP service listening on port inside your container.

gpu ​

GPU spec enum (Aliyun):

TESLA_8 TESLA_12 TESLA_16 AMPERE_8 AMPERE_12 AMPERE_16 AMPERE_24 ADA_48

The number is VRAM in GB. GPU instances usually need a higher memory to match.

log ​

A boolean. When enabled, invocation logs flow into the provider's log service (e.g. Aliyun SLS).

yaml
log: true

network ​

Attaching a function to a private network is what lets it reach databases, caches, and other VPC-internal endpoints. All three sub-fields are required when network is present:

yaml
network:
  vpc_id: vpc-xxxxx
  subnet_ids:
    - vsw-xxxxx
    - vsw-yyyyy
  security_group:
    name: my-sg
    ingress:
      - TCP:10.0.0.0/8:443
    egress:
      - UDP:0.0.0.0/0:ALL
FieldTypeRequiredDescription
vpc_idstring✅VPC ID
subnet_idsstring[]✅vSwitch (subnet) IDs
security_groupobject✅see below
security_group.namestring✅security group name
security_group.ingressstring[]✅inbound rules
security_group.egressstring[]❌outbound rules

Rule format is protocol:CIDR:port where port is ALL, a single port (443), or a range (80/90), e.g. TCP:10.0.0.0/8:443.

iam ​

Configures the function's execution role. The simple form references an existing RAM role ARN; for fine-grained grants, use the object form:

yaml
# Form 1: reference an existing role
iam:
  role: acs:ram::1234567890:role/my-role

# Form 2: declare the role and its grants
iam:
  role:
    name: my-fn-role
    managed_policies:
      - AliyunOSSReadOnlyAccess
    statements:
      - effect: Allow
        action:
          - oss:GetObject
        resource:
          - my-bucket/*

Each statements item requires effect (Allow / Deny), action, and resource (string or array); sid is optional.

triggers - Function-level HTTP Trigger ​

Attaches an HTTP trigger directly to the function (no API gateway). Tencent Cloud functions expose their HTTP entry this way:

yaml
triggers:
  http:
    auth_type: public
    access:
      - public
FieldTypeRequiredDescription
auth_typestring✅public (anonymous public access) or iam (signature-authenticated)
accessstring[]❌network access types: public / internal, at least one

Function-level HTTP triggers fit simple cases; for path routing, custom domains, and rate limiting, use events (API gateway) instead.

domain - Function-level Custom Domain ​

yaml
domain:
  domain_name: api.example.com
  certificate_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  protocol: HTTPS
FieldTypeRequiredDescription
domain_namestring✅custom domain (registered and pointed at the provider)
certificate_idstring❌uploaded SSL certificate ID
protocolstring❌HTTP or HTTPS

storage - Disk and NAS ​

yaml
storage:
  disk: 512
  nas:
    - mount_path: /mnt/nas
      storage_class: STANDARD_CAPACITY
FieldTypeRequiredDescription
disknumber❌temporary disk size (MB)
nasobject[]❌NAS mount list
nas[].mount_pathstring✅in-container mount path
nas[].storage_classstring✅STANDARD_CAPACITY / STANDARD_PERFORMANCE / EXTREME_STANDARD / EXTREME_ADVANCE

events ​

The events resource currently has exactly one shape: an API gateway (type: API_GATEWAY). It solves the "many functions, many routes" traffic-entry problem: the gateway dispatches requests to different functions by path and method, and carries a shared domain and certificate.

Choosing between functions.triggers.http and events: a single function with a fixed path is simpler with a function-level trigger; a set of endpoints needing routing and one shared domain belongs in events.

yaml
events:
  gateway_event:
    name: insight-poc-gateway
    type: API_GATEWAY
    triggers:
      - method: GET
        path: /api/*
        backend: hello_world_fn
    domain:
      domain_name: api.example.com
      certificate_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      protocol: HTTPS
FieldTypeRequiredDescription
namestring✅gateway name
typestring✅API_GATEWAY only
triggersobject[]✅routing rules
logboolean❌enable gateway logging
networkobject❌the VPC the gateway lives in
domainobject❌custom domain and certificate

⚠️ Tencent Cloud does not support events (API gateway resources). Expose function HTTP entries via functions.triggers.http; the system creates an SCF function URL trigger rather than a standalone gateway.

Custom domains are limited to the API gateway scenario (function-level domain is not available yet); certificate handling matches Aliyun.

triggers - Routing Rules ​

yaml
triggers:
  - method: GET
    path: /api/*
    backend: hello_world_fn
FieldTypeRequiredDescription
methodstring✅GET / POST / PUT / DELETE / ANY
pathstring✅must start with /; * wildcard supported
backendstring✅target function's reference name (the key under functions, not its name)

Legacy event types (type: HTTP, type: Timer, type: sqs) have been removed from the schema and fail validate. Timer and messaging triggers are not yet supported.

domain - Gateway Custom Domain ​

yaml
domain:
  domain_name: api.example.com
  protocol: HTTPS
  certificate_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  www_bind_apex: false
FieldTypeRequiredDescription
domain_namestring✅custom domain
protocolstring / string[]❌HTTP, HTTPS, or an array of both, e.g. ['HTTP', 'HTTPS']
certificate_idstring⚠️certificate ID (one of three forms, see below)
certificate_body + certificate_private_keystring⚠️certificate content + private key (one of three forms)
www_bind_apexboolean❌also bind the www subdomain
cdnobject / boolean❌CDN acceleration, see below

The three certificate forms are mutually exclusive: either certificate_id, or certificate_body + certificate_private_key together, never a mix.

cdn configuration ​

Or simply cdn: true for defaults:

yaml
cdn:
  enabled: true
  cdn_type: web
  scope: domestic
  cache_ttl: 3600
  origin_protocol: follow
  force_redirect_https: true
FieldTypeDescription
enabledbooleanenable CDN
cdn_typestringweb / download / video
scopestringdomestic / overseas / global
cache_ttlnumbercache duration (seconds)
ignore_query_stringbooleanexclude query strings from cache keys
origin_protocolstringorigin protocol: http / https / follow
compressionbooleansmart compression
force_redirect_httpsbooleanforce HTTPS redirect

databases ​

The databases resource declares the data layer your functions depend on. ServerlessInsight provisions the instance, wires the network, and sets credentials; your function just needs the connection string. Supported: Aliyun RDS / Elasticsearch Serverless and Tencent TDSQL-C:

yaml
databases:
  main_db:
    name: main-db
    type: RDS_MYSQL_SERVERLESS
    version: MYSQL_8.0
    cu:
      min: 0
      max: 8
    security:
      basic_auth:
        master_user: dbadmin
        password: "${vars.db_password}"

cu.min/max is the point of serverless databases: scale to 0 CU with no traffic (no compute cost) and burst to max under load. Always inject the password via ${vars.*} or -p, never commit it in plain text.

Type and version values:

FieldValues
typeELASTICSEARCH_SERVERLESS RDS_MYSQL_SERVERLESS RDS_PGSQL_SERVERLESS RDS_MSSQL_SERVERLESS TDSQL_C_SERVERLESS
versionMYSQL_5.7 MYSQL_8.0 MYSQL_HA_5.7 MYSQL_HA_8.0, PGSQL_14 PGSQL_15 PGSQL_16 PGSQL_HA_14 PGSQL_HA_15 PGSQL_HA_16, MSSQL_HA_2016 MSSQL_HA_2017 MSSQL_HA_2019, ES_SEARCH_7.10 ES_TIME_SERIES_7.10

The _HA_ variants are high-availability (primary-standby); prefer them in production.

Remaining fields:

FieldTypeDescription
cuobjectelastic compute unit range: min / max
storageobjectstorage capacity range: min / max (GB, integers)
security.basic_auth.master_userstringadmin username
security.basic_auth.passwordstringadmin password (inject via variable)
networkobjectaccess network, see below

network fields:

yaml
network:
  type: PRIVATE
  vpc_id: vpc-xxxxx
  subnet_id: vsw-xxxxx
  public: false
  ingress_rules:
    - TCP:10.0.0.0/8:3306
FieldTypeDescription
typestringPUBLIC (direct public access) or PRIVATE (VPC-internal)
vpc_id / subnet_idstringVPC and vSwitch for private access (note: a single subnet_id)
publicbooleanadditionally expose public access
ingress_rulesstring[]access rules, same format as security group rules

Supports RDS Serverless (MySQL / PostgreSQL / SQL Server) and Elasticsearch Serverless, plus table storage (tables).

Supports TDSQL-C Serverless and Elasticsearch Serverless; pick TDSQL_C_SERVERLESS and ELASTICSEARCH_SERVERLESS respectively.

databases and tables are not supported yet; manage databases through your existing cloud resources and simply omit these sections from the config.

tables ​

Table storage fits low-latency reads/writes over massive semi-structured data (user profiles, sessions, IoT time series). Currently supported only on Aliyun TableStore. Every table belongs to an instance (collection, a required string); the instance is TableStore's billing and network unit.

yaml
tables:
  sessions:
    collection: my-instance
    name: session-table
    type: TABLE_STORE_H
    desc: user session table
    key_schema:
      - name: user_id
        type: HASH
      - name: session_id
        type: RANGE
    attributes:
      - name: user_id
        type: STRING
      - name: session_id
        type: STRING
      - name: payload
        type: BINARY
    throughput:
      reserved:
        read: 100
        write: 100

Primary key design is the single most important decision here: the HASH key decides which shard a row lands on, so pick a high-cardinality field (like user_id) to avoid hot spots; the RANGE key sorts rows within a shard and suits range queries.

FieldTypeRequiredDescription
collectionstring✅owning instance name
namestring✅table name
typestring✅TABLE_STORE_C (capacity, pay-per-use, write-heavy) / TABLE_STORE_H (high-performance, reserved capacity, low latency)
descstring❌description, max 256 chars
key_schemaobject[]✅primary keys, see below
attributesobject[]✅attribute columns, see below
throughputobject❌reserved / on-demand read-write CU
networkobject❌access network

key_schema / attributes:

FieldTypeDescription
namestringkey / attribute name
typestringkey type: HASH (partition) or RANGE (sort); attribute types: STRING INTEGER DOUBLE BOOLEAN BINARY

Every key in key_schema must have its type declared in attributes; schema validation rejects keys without types.

throughput (capacity-type tables usually need no reservation):

FieldDescription
reserved.read / reserved.writereserved read / write CU
on_demand.read / on_demand.writeon-demand read / write CU caps

network: type (PUBLIC / PRIVATE, required), vpc_id, ingress_rules[].

buckets ​

Object storage buckets serve three typical purposes: hosting static assets and frontend builds, storing function code packages and artifacts, and archiving logs and backups. Bucket names are globally unique, so prefix them with your project:

yaml
buckets:
  assets:
    name: my-app-assets
    storage:
      class: STANDARD
    versioning:
      status: Enabled
    security:
      acl: PRIVATE
      sse_algorithm: KMS
    domain:
      domain_name: static.example.com
      certificate_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      protocol: HTTPS
FieldTypeRequiredDescription
namestring✅bucket name (globally unique, a-zA-Z0-9-_)
storageobject❌class required: storage class (provider-passthrough, e.g. STANDARD / IA / ARCHIVE)
versioningobject❌status required: versioning (provider-passthrough; Aliyun uses Enabled / Suspended)
securityobject❌ACL and encryption, see below
domainobject❌custom domain (recommended, see below)
websiteobject❌static website hosting, see below
iamobject❌bucket resource policy

security:

FieldTypeDescription
aclstringPRIVATE (default) / PUBLIC_READ / PUBLIC_READ_WRITE
force_deletebooleanallow destroy to delete non-empty buckets (default false; a non-empty bucket fails teardown by design)
sse_algorithmstringserver-side encryption: AES256 / KMS
sse_kms_master_key_idstringKMS key ID (used with sse_algorithm: KMS)

domain - custom domain (recommended): a plain string or an object. The object form adds certificates and CDN:

yaml
domain: cdn.example.com        # shorthand

domain:                        # full form
  domain_name: static.example.com
  protocol: HTTPS
  certificate_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  www_bind_apex: true
  accelerate: true             # OSS transfer acceleration
  cdn:
    enabled: true
    cdn_type: web
    scope: domestic
    cache_ttl: 3600
    origin_protocol: follow
    force_redirect_https: true

Certificate rules match events.domain: certificate_id and (certificate_body + certificate_private_key) are mutually exclusive. The cdn object is the same as the events cdn.

website - static website hosting:

yaml
website:
  code: dist/
  index: index.html
FieldTypeRequiredDescription
codestring✅website build output / code package path
indexstring❌default index page (index.html)
domainstring / object❌⚠️ deprecated: use the top-level domain field

Public access requires security.acl: PUBLIC_READ; website only handles hosting behavior; domains and certificates go through the top-level domain.

iam - bucket resource policy: cross-account or anonymous access control; statement structure mirrors function iam.statements (effect / action / resource required):

yaml
iam:
  resource:
    statements:
      - effect: Allow
        action:
          - oss:GetObject
        resource:
          - my-app-assets/*

Variable References ​

Anything that varies across environments should go through variables instead of copy-pasted configs. The three forms have distinct jobs:

yaml
# ${vars.*} — team-defined variables, overridable via -p
vars:
  db_password: change-me

# ${stages.*} — values defined in the current stage
stages:
  dev:
    memory: 256

# ${ctx.*} — CLI runtime context
# ctx.stage is the stage being deployed
yaml
functions:
  api_function:
    memory: ${stages.memory}          # stages.<current>.memory
    environment:
      DB_PASSWORD: ${vars.db_password} # vars.db_password
      STAGE: ${ctx.stage}              # dev / prod / ...

app and service do not support variables: they participate in state-file resolution and must be literals before interpolation happens.

Local Development ​

si local runs the defined functions in local processes, using your real handler code behind a local HTTP server that simulates cloud behavior, so you can iterate without redeploying (currently Aliyun functions only):

bash
si local --stage dev
  • Local server listens on port 4567, routing requests per your events rules
  • --watch is on by default; saving code hot-reloads
  • --debug enables debug mode and IDE breakpoints

Best Practices ​

Isolate environments with stages, not file copies. When dev and prod differ only in parameters, one config + ${stages.*} is the cheapest thing to maintain; split files only when the structure itself diverges.

Inject secrets, don't commit them. Keep non-sensitive defaults in vars; pass passwords with -p key=value at deploy time or wire them from your CI's secret manager.

Put the environment in function names. Suffix resource names with ${ctx.stage} (e.g. user-api-${ctx.stage}) so parallel environments are instantly identifiable and never collide.

Let destroy fail loudly. Buckets refuse to delete while non-empty (force_delete: false); that guard is protection, not friction. Enable it only for genuinely disposable scratch resources.

Validate before deploying. si validate checks runtimes, enums, and required fields per provider; catching errors before any cloud resource is created is always cheaper than rolling back a failed deploy.

FAQ ​

Q: Why is API_GATEWAY the only event type? ​

The schema currently implements only API gateway events. Timer and messaging triggers are not in the schema yet, so writing type: Timer fails validate by design, not by bug. For simple HTTP, use functions.triggers.http meanwhile.

Q: Why can't app / service use variables? ​

Both fields participate in state-file resolution and resource naming; the CLI must know them as literals before interpolation. Every other field (name, environment, ...) may reference variables freely.

Q: Deployment fails with "runtime not supported"? ​

runtime is validated per provider: Aliyun uses identifiers like nodejs18, Volcengine uses suffixed ones like node20/v1. Check the runtime table above and the provider page.

Q: How do I update a deployed function? ​

Repackage and run si deploy again. The CLI diffs against the state file and only changes what actually changed.

Q: How do I delete all resources? ​

bash
si destroy --stage dev

Destroy tears down resources recorded in the state file. Non-empty buckets fail teardown; after confirming, you can temporarily set security.force_delete: true.