Skip to content

Functions ​

Functions run short request/response code without you managing servers. Package a zip, register it, allow its identity to call other Cloud services, then invoke it from Gateway, Events, or skippr-cloud functions invoke. Use this for HTTP handlers and event-driven work. Long-running VMs are not a product yet.

Status: Preview. See the API action reference for the full command list.

Before you start ​

  • Get an access token with skippr-cloud login. See Cloud User Directory.
  • Ensure your own policy allows the functions and objects actions used below.
  • Create an artifact bucket by following Objects.

1. Package and upload ​

This Node example accepts a JSON payload and returns it:

js
// index.js
exports.handler = (event) => ({
  ok: true,
  received: event
});

Package it, calculate the required lowercase SHA-256, and upload it to a function-artifacts bucket. Creating the bucket is CLI, Terraform, CDKTF TypeScript, or CDKTF Python. Uploading the zip is a data-plane call. For provider credentials and the shared cloud provider block, see Terraform and CDKTF.

bash
zip -j hello.zip index.js
export FUNCTION_SHA256="$(shasum -a 256 hello.zip | awk '{print $1}')"
bash
skippr-cloud objects create-bucket --bucket function-artifacts
skippr-cloud objects put-object --bucket function-artifacts --key hello.zip --content-type application/zip
hcl
resource "cloud_object_bucket" "artifacts" {
  bucket = "function-artifacts"
}
ts
import { CloudProvider, CloudObjectBucket } from "@skippr/provider-cloud";

const cloud = new CloudProvider(this, "cloud", { region: "eu-central-1" });

new CloudObjectBucket(this, "artifacts", {
  bucket: "function-artifacts",
  provider: cloud,
});
python
from skippr_cdktf import CloudProvider, CloudObjectBucket

cloud = CloudProvider(self, "cloud", region="eu-central-1")

CloudObjectBucket(
    self,
    "artifacts",
    bucket="function-artifacts",
    provider=cloud,
)

After the bucket exists, upload the zip with skippr-cloud objects put-object --bucket function-artifacts --key hello.zip --content-type application/zip.

2. Register ​

Register the uploaded object as a Zip function:

bash
skippr-cloud functions register-function --input - <<JSON
{
  "name": "hello",
  "packageType": "Zip",
  "runtime": "cloud.nodejs",
  "handler": "index.handler",
  "concurrencyLimit": 10,
  "timeoutSeconds": 30,
  "memoryMb": 256,
  "code": {
    "bucket": "function-artifacts",
    "key": "hello.zip",
    "sha256": "${FUNCTION_SHA256}"
  }
}
JSON
hcl
resource "cloud_function" "hello" {
  name              = "hello"
  package_type      = "Zip"
  runtime           = "cloud.nodejs"
  handler           = "index.handler"
  concurrency_limit = 10
  code_bucket       = cloud_object_bucket.artifacts.bucket
  code_key          = "hello.zip"
  code_sha256       = filebase64sha256("hello.zip")
}
ts
import { CloudFunction } from "@skippr/provider-cloud";

new CloudFunction(this, "hello", {
  name: "hello",
  packageType: "Zip",
  runtime: "cloud.nodejs",
  handler: "index.handler",
  concurrencyLimit: 10,
  codeBucket: "function-artifacts",
  codeKey: "hello.zip",
  codeSha256: process.env.FUNCTION_SHA256!,
  provider: cloud,
});
python
import os
from skippr_cdktf import CloudFunction

CloudFunction(
    self,
    "hello",
    name="hello",
    package_type="Zip",
    runtime="cloud.nodejs",
    handler="index.handler",
    concurrency_limit=10,
    code_bucket="function-artifacts",
    code_key="hello.zip",
    code_sha256=os.environ["FUNCTION_SHA256"],
    provider=cloud,
)

Registration returns status: "Active" and creates workload principal fn/hello.

3. Authorize the function ​

The function's workload principal has no Cloud API permissions until you attach a policy. This example allows it to read one table action:

bash
skippr-cloud auth create-policy --input - <<JSON
{
  "policyId": "hello-data",
  "policy": "permit (principal == Cloud::Principal::\"fn/hello\", action == Cloud::Action::\"tables:GetItem\", resource);",
  "attachedTo": ["workload:fn/hello"]
}
JSON

Grant only the actions the handler calls. Environment values can be plain strings or { "SecretId": "…" }; secret references are resolved at cold start under this workload identity.

4. Invoke ​

This is a complete synchronous invoke:

bash
skippr-cloud functions invoke --input - <<JSON
{
  "functionName": "hello",
  "payload": "{\"name\":\"Ada\"}"
}
JSON

The response is { "statusCode": 200, "payload": "<handler response>" }. payload is a string on both the request and response. A Gateway FUNCTION route unwraps that envelope: callers receive the payload as the HTTP body.

Zip or Image ​

ZipImage
SourceObject reference: bucket, key, sha256OCI function bundle in objects, addressed by its required sha256
RuntimeRequiredOmit it
HandlerRequiredDefined by the image
Supported Zip runtimescloud.rust, cloud.nodejs, cloud.python, cloud.goNot applicable
MaterializationVerified and extracted from objectsVerified, layer-merged, and converted to /data/code when the fleet starts

Image registration uses this shape:

json
{
  "name": "image-worker",
  "packageType": "Image",
  "image": {
    "uri": "ghcr.io/example/image-worker:1",
    "sha256": "<sha256-of-uploaded-oci-layout-tarball>"
  },
  "concurrencyLimit": 10,
  "memoryMb": 512
}

Do not include runtime for an Image function. Upload the OCI-layout function bundle to the tenant's function-images object bucket using the lowercase SHA-256 as its object key. The bundle must contain an executable /code/fn-entrypoint; that entrypoint receives the JSON invocation on stdin and returns the handler response on stdout. uri is source provenance; the uploaded bundle digest is the launch artifact identity.

Operations by task ​

Deploy and update ​

OperationUse it to
RegisterFunctionCreate or replace a function definition. Re-register keeps the existing workload identity unless you bind PrincipalId.
UpdateFunctionCodeReplace only the Zip object or Image bundle digest
UpdateFunctionConfigurationChange handler, runtime, concurrency, timeout, memory, environment, or identity. Binding a key requires PrincipalId and AccessKeyId together.
UpdateFunctionConfiguration-only alias

Invoke and trigger ​

OperationUse it to
InvokeWait for the handler response
InvokeAsyncEnqueue an invocation and receive HTTP 202
CreateEventSourceMappingPoll a queue ARN and invoke the function with each message

Only queue event-source ARNs are supported in Preview. Function URLs are coming soon.

Inspect and remove ​

OperationUse it to
GetFunctionRead one function definition and workload identity
ListFunctionsList functions with maxResults from 1 to 100
DeleteFunctionDelete the function definition

DeleteFunction requires the current revision returned by GetFunction and an idempotencyKey. Reuse both values when retrying a failed deletion; a different revision or key cannot delete a replacement function.

Limits and runtime contract ​

Limit or defaultValue
Zip compressed size50 MiB
Zip uncompressed size250 MiB
Zip entries10,000
Default concurrency10
Default timeout30 seconds
Timeout range1–900 seconds
Default memory256 MiB
Environment size32 KiB, including names and values
List page size1–100

The function artifact SHA-256 is verified before execution. Zip paths are validated during extraction. Invoke requests are limited to 16 MiB, including the JSON envelope and payload.

Errors ​

Errors use a JSON code and message.

Code or statusMeaning
ResourceNotFoundExceptionThe function does not exist
ValidationExceptionInvalid package type, runtime, artifact, fields, or queue mapping
TooManyRequestsException / 429The function cannot take this request now. Retry.
ConflictException / 409A concurrent update raced; retry the register or update
UnhandledThe runtime or handler failed
401 / 403Missing authentication or a policy denial