Skip to content

Deploy edge functions with the edge-functions template

Deployment

Deploy edge functions with the edge-functions template

Stand up an OpenFaaS faasd function gateway on one Quake AI instance using the validated OpenTofu template edge-functions. You apply the template, read the generated gateway credentials, invoke the starter function over the floating IP, deploy an additional function from the OpenFaaS store, add a secret and consume it from a function, schedule a periodic invocation with cron on the gateway host, and optionally point a domain for automatic TLS.

You operate the gateway yourself on a regional VM. Functions execute in that region; this is not a global edge network like Cloudflare Workers or Vercel Edge Functions.

API clientFloating IP80 / 443Gateway VMCaddy + faasdcontainerdfunctions HTTPS + basic auth
Click to zoom
What you'll build: faasd on a gateway instance with a floating IP runs containerized functions behind Caddy on ports 80 and 443

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on shared vCPU.

Starting template$14.70/mo

Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

Functions

s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

s1a.small

2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50

Compute + RAM rate basis

2 vCPU + 2 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (40 GiB)

40 GiB at $0.08/GiB/mo

$3.20

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the edge-functions template directory from the template reference page.
  • faas-cli installed on your workstation, or willingness to run faas-cli commands over SSH on the gateway host (the faasd install script places faas-cli on the instance). See OpenFaaS CLI installation.
  • A domain you can point at the gateway floating IP when you enable TLS (optional for the HTTP verification steps below).

Step 1: Apply the functions template#

Copy the template's example variables file and set key_name. Leave domain empty so Caddy serves plain HTTP on port 80 while you verify functions:

bash
cp terraform.tfvars.example terraform.tfvars
HCL
key_name = "YOUR_KEY_NAME"

Initialize, preview, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, router, security group, data volume, gateway instance, and floating IP. cloud-init installs faasd via the upstream install script, generates a gateway password on first boot, deploys the nodeinfo starter function from the OpenFaaS store, and starts Caddy as the public front door.

Record the outputs:

bash
tofu output floating_ip
tofu output private_ip
tofu output gateway_url

Wait five to eight minutes for cloud-init, faasd, and the starter function deploy to finish before you test the gateway.

Step 2: Read the gateway credentials#

faasd does not ship credentials in the repository. SSH to the gateway instance and read the credentials file cloud-init wrote on first boot:

bash
ssh ubuntu@YOUR_FLOATING_IP 'sudo cat /root/faasd-gateway-credentials'

Record the username, password, and starter_function URL. The password is also stored at /var/lib/faasd/secrets/basic-auth-password on the instance.

Step 3: Invoke the starter function over the floating IP#

From your workstation, call the starter function with basic auth:

bash
curl -s -u admin:YOUR_PASSWORD http://YOUR_FLOATING_IP/function/nodeinfo

The response should be JSON describing the gateway host (hostname, platform, CPU count, and related fields). If you get 401 Unauthorized, recheck the password from step 2. If you get 404, cloud-init may still be deploying; wait two minutes and retry.

Step 4: Deploy a function from the OpenFaaS store#

Log in to the gateway with faas-cli from your workstation (replace the gateway URL with your floating IP):

bash
export OPENFAAS_URL=http://YOUR_FLOATING_IP
faas-cli login -u admin -p YOUR_PASSWORD --gateway "$OPENFAAS_URL"

Deploy figlet from the OpenFaaS function store:

bash
faas-cli store deploy figlet --gateway "$OPENFAAS_URL"

Wait until the deploy reports success, then invoke it over the floating IP:

bash
curl -s -u admin:YOUR_PASSWORD \
  http://YOUR_FLOATING_IP/function/figlet \
  -d "edge functions"

The response body should be ASCII art spelling your input.

List deployed functions to confirm both nodeinfo and figlet are ready:

bash
faas-cli list --gateway "$OPENFAAS_URL"

Step 5: Add a secret and consume it from a function#

Create a secret that holds the string figlet should print when the scheduled job runs:

bash
echo -n "cron secret payload" | faas-cli secret create cron-payload --from-file=- --gateway "$OPENFAAS_URL"

Verify the secret exists:

bash
faas-cli secret list --gateway "$OPENFAAS_URL"

The list should include cron-payload.

On faasd, secrets are files under /var/openfaas/secrets/ inside function containers. Store functions like figlet do not mount custom secrets by default; consume the secret in the cron step by reading it on the host and passing the value as the request body:

bash
ssh ubuntu@YOUR_FLOATING_IP 'PASS=$(sudo cat /var/lib/faasd/secrets/basic-auth-password); PAYLOAD=$(sudo cat /var/lib/faasd/secrets/cron-payload); curl -s -u admin:$PASS http://127.0.0.1:8080/function/figlet -d "$PAYLOAD"'

The response should be ASCII art for cron secret payload, which confirms the secret value reached the function invocation path.

Step 6: Schedule a cron invocation on the gateway host#

faasd on a single VM does not ship a separate cron connector. Schedule periodic invocations with a root crontab entry on the gateway that reads the secret and calls figlet on localhost:

bash
ssh ubuntu@YOUR_FLOATING_IP 'sudo bash -s' <<'EOF'
PASS=$(cat /var/lib/faasd/secrets/basic-auth-password)
CRON_LINE='*/5 * * * * root PAYLOAD=$(cat /var/lib/faasd/secrets/cron-payload); curl -sf -u admin:'"$PASS"' http://127.0.0.1:8080/function/figlet -d "$PAYLOAD" >> /var/log/faasd-cron.log 2>&1'
grep -q faasd-cron.log /etc/crontab || echo "$CRON_LINE" >> /etc/crontab
EOF

Wait six minutes, then inspect the log on the gateway:

bash
ssh ubuntu@YOUR_FLOATING_IP 'sudo tail -5 /var/log/faasd-cron.log'

The log should show successful HTTP responses from repeated figlet invocations. Each line corresponds to one cron tick.

Step 7: Point a domain and enable HTTPS (optional)#

Skip this step if HTTP on the floating IP is enough for your test. To enable automatic TLS with Caddy in front of faasd:

  1. Create a DNS A record for your domain (for example functions.example.com) pointing at YOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until it resolves:
bash
dig +short functions.example.com
  1. Set domain in terraform.tfvars and re-apply:
HCL
domain = "functions.example.com"
bash
tofu apply

cloud-init switches to the HTTPS branch: Caddy terminates TLS on ports 80 and 443 and forwards to faasd on 127.0.0.1:8080. Wait three to five minutes for Caddy to obtain a Let's Encrypt certificate.

  1. Confirm HTTPS end to end:
bash
curl -s -u admin:YOUR_PASSWORD https://functions.example.com/function/figlet -d "tls ok"

The response should be ASCII art for tls ok.

Update OPENFAAS_URL and re-login if you deploy more functions over HTTPS:

bash
export OPENFAAS_URL=https://functions.example.com
faas-cli login -u admin -p YOUR_PASSWORD --gateway "$OPENFAAS_URL"

For certificate background, see How to issue and auto-renew a TLS certificate with Let's Encrypt.

What you built#

  • Applied the edge-functions template to provision a private network, gateway security group, data volume, faasd host, and floating IP
  • Invoked the starter nodeinfo function over the floating IP with gateway basic auth
  • Deployed figlet from the OpenFaaS store and invoked it over the public URL
  • Created and consumed a cron-payload secret by passing its value into a function invocation
  • Scheduled a five-minute cron job on the gateway host that invokes figlet with the secret payload

Scope of this deployment#

This gateway runs in one region on a VM you operate. It executes functions in that region on containerd via faasd. It is not a global edge network: Quake AI has no anycast, no global PoPs, and no first-party serverless edge. For geographic distribution, front workloads with a third-party CDN.

For Deno edge functions beside a self-hosted BaaS stack, see Supabase self-host and its deployment walkthrough. For WebAssembly functions on Kubernetes, see the Kubernetes cluster template.

Next steps#

Clean up#

When you no longer need the deployment, destroy the OpenTofu stack:

bash
tofu destroy

Remove any DNS A record you pointed at the gateway floating IP and delete cron entries if you added them manually on the host before destroy.

Was this page helpful?