Table of Contents
Patch Envelopes
A Patch Envelope is a bundle of files, configuration, scripts, or binary data that ZEDEDA Cloud can deliver to a running application instance without rebooting the VM or recreating the image. It is the mechanism for updating config, rotating certificates, pushing new scripts, or changing application parameters at runtime across a fleet of edge nodes.
Think of it as a live config injection channel – you change the envelope in ZEDEDA Cloud, the app picks it up at its next poll without any restart or downtime.
What a Patch Envelope Actually Is
A patch envelope is not a volume mount and not a filesystem change pushed by the controller. It is a collection of base64-encoded binary blobs (artifacts) that EVE-OS exposes to the app through a local metadata server running at the link-local address 169.254.169.254. The app is responsible for fetching its own artifacts by calling the metadata server API.
This is an important distinction:
- The controller delivers the envelope metadata to EVE-OS at the next heartbeat
- EVE-OS makes the artifacts available via the metadata server HTTP endpoint
- The app itself must call the metadata server to discover and download its artifacts
- Nothing is written to the app's filesystem automatically – the app owns the pull and placement logic
This design means the app must be written (or configured) to poll the metadata server. A vanilla Ubuntu VM with no custom startup script will not automatically receive patch envelope files.
Constraints
- Maximum envelope size: 5 MB total across all artifacts
- An app instance can have only one envelope attached at a time
- An envelope can be attached to many app instances (one-to-many)
- An envelope belongs to one project only
- The app must be connected to a local network instance – the metadata server is only reachable from within a local (switch) network instance, not from a direct (passthrough) NIC
- Encrypted artifacts are supported (introduced in EVE-OS 14.5 LTS) for secure passing of credentials and secrets
Artifact Types
| Type | How it works | Best for |
|---|---|---|
| Inline | Data pasted directly into ZEDEDA Cloud as base64. Stored in the ZEDEDA controller. | Small config files, environment variables, short scripts, certificates under 5 MB |
| External (Binary Artifact) | A binary artifact already uploaded to a datastore, referenced by the envelope. | Larger files, pre-compiled binaries, firmware blobs |
Both types can coexist in the same envelope.
How the App Receives Patch Envelope Data
EVE-OS runs a metadata server reachable at 169.254.169.254 from inside any app connected to a local network instance. Patch envelope endpoints:
Step 1 – Discover available envelopes:
curl http://169.254.169.254/eve/v1/patch/description.json
Response:
[
{
"PatchId": "699fbdb2-e455-448f-84f5-68e547ec1305",
"Version": "1",
"BinaryBlobs": [
{
"file-name": "app.conf",
"file-sha": "a3f1...",
"file-meta-data": "YXJ0aWZhY3QgbWV0YWRhdGE=",
"url": "http://169.254.169.254/eve/v1/patch/download/699fbdb2.../app.conf"
},
{
"file-name": "update.sh",
"file-sha": "c9b2...",
"file-meta-data": "YXJ0aWZhY3QgbWV0YWRhdGE=",
"url": "http://169.254.169.254/eve/v1/patch/download/699fbdb2.../update.sh"
}
]
}
]
Step 2 – Download a specific artifact:
curl http://169.254.169.254/eve/v1/patch/download/699fbdb2-e455-448f-84f5-68e547ec1305/app.conf \ -o /etc/myapp/app.conf
The app checks file-sha against the downloaded file for integrity verification. The file-meta-data field is a base64-encoded string of any custom metadata you attached to the artifact – useful for versioning or targeting logic.
Step 3 – Act on the file:
The app applies the config, runs the script, installs the certificate, or does whatever makes sense for the workload. This is entirely app-side logic.
Typical App-Side Pattern
A well-designed edge app that supports patch envelopes typically runs a polling loop:
#!/bin/sh METADATA_URL="http://169.254.169.254/eve/v1/patch/description.json" KNOWN_VERSION=""
while true; do ENVELOPE=$(curl -sf $METADATA_URL) VERSION=$(echo $ENVELOPE | jq -r '.[0].Version')
if [ "$VERSION" != "$KNOWN_VERSION" ]; then
echo "New patch envelope version: $VERSION"
FILE_URL=$(echo $ENVELOPE | jq -r '.[0].BinaryBlobs[0].url')
curl -sf $FILE_URL -o /etc/myapp/app.conf
# reload config, signal the process, etc.
kill -HUP $(cat /var/run/myapp.pid)
KNOWN_VERSION=$VERSION
fi
sleep 30 done
This pattern: poll description.json every 30 seconds, compare the version, download and apply if changed, signal the app to reload. No restart, no downtime.
Terraform Examples
Creating a Patch Envelope (inline artifact)
An envelope with a config file delivered as an inline base64 artifact:
resource "zedcloud_patch_envelope" "app_config_pe" {
name = "myapp-config-v1"
title = "MyApp Config Patch Envelope v1"
description = "Runtime config for myapp -- updated without restart"
project_id = zedcloud_project.demo_project.id
activate = true
artifacts {
artifact_name = "app.conf"
binary_blob = base64encode(file("${path.module}/files/app.conf"))
file_meta_data = base64encode("version=1;type=config")
}
}
Notes:
activate = truemakes the envelope live immediately on applybinary_blobmust be base64 encoded – Terraform'sbase64encode()function handles thisfile_meta_datais optional custom metadata, also base64 encodedartifact_namebecomes the filename in the metadata server response
Multiple Artifacts in One Envelope
An envelope with both a config file and a shell script:
resource "zedcloud_patch_envelope" "myapp_full_pe" {
name = "myapp-full-patch-v2"
title = "MyApp Full Patch v2"
project_id = zedcloud_project.demo_project.id
activate = true
artifacts {
artifact_name = "app.conf"
binary_blob = base64encode(file("${path.module}/files/app.conf"))
file_meta_data = base64encode("type=config")
}
artifacts {
artifact_name = "update.sh"
binary_blob = base64encode(file("${path.module}/files/update.sh"))
file_meta_data = base64encode("type=script")
}
}
Attaching the Envelope to an App Bundle
The patch envelope is referenced in the app bundle definition, not the app instance. All instances of that bundle automatically inherit the envelope.
resource "zedcloud_application" "myapp" {
name = "myapp"
title = "MyApp"
project_id = zedcloud_project.demo_project.id
drives {
image_id = zedcloud_image.demo_atl_ub_image_1.id
maxsize = 20480
target = "Disk"
drvtype = "HDD"
}
resources {
name_of_virtual_machine = "myapp"
cpus = 2
memory = 2048
}
interfaces {
netadapter = "eth0"
network_id = zedcloud_network_instance.local_net.id
default_net_instance = true
}
# Attach the patch envelope patch_envelope_id = zedcloud_patch_envelope.myapp_full_pe.id }
The app must be on a local network instance (network_id pointing to a local switch NI). A direct/passthrough NIC does not expose the metadata server.
Updating the Envelope (new version)
To push a config change, create a new envelope resource or update the existing one. When activate = true and you run terraform apply, EVE-OS receives the updated artifact list at the next heartbeat and makes the new version available at the metadata server endpoint. The version number in the description.json response increments, and any app polling the endpoint will detect the change.
resource "zedcloud_patch_envelope" "app_config_pe" {
name = "myapp-config-v1"
title = "MyApp Config Patch Envelope v1"
project_id = zedcloud_project.demo_project.id
activate = true
artifacts {
artifact_name = "app.conf"
binary_blob = base64encode(file("${path.module}/files/app.conf"))
file_meta_data = base64encode("version=2;type=config")
}
}
ZEDUI Walkthrough
Create the Envelope
- Navigate to Library > Patch Envelopes
- Click the + icon
- Fill in Name (permanent), Title, Description, Project
- Set Activate Patch to on if you want it live immediately
- Click Next to the Artifacts section
- Click + to add an artifact:
- Inline: paste base64-encoded data directly
- External: select a Binary Artifact from your Library
- Add more artifacts as needed
- Click Add
To get the base64 of a file for inline upload:
cat app.conf | base64
Attach to an App Instance
- Navigate to Edge App Instances
- Select the target instance
- Click the … (More Actions) menu
- Click Attach Patch Envelope
- Select the envelope from the list
- Confirm
To detach: same path, click Detach Patch Envelope.
ZCLI
# Create a patch envelope with an inline artifact zcli patch-envelope create myapp-config-v1 \ --title="MyApp Config v1" \ --project=demo-project \ --activate=true
# Attach to an app instance zcli edge-app-instance attach-patch-envelope MY-APP-INSTANCE \ --patch-envelope=myapp-config-v1
API
# Create envelope
POST /v1/patchenvelopes
{
"name": "myapp-config-v1",
"title": "MyApp Config v1",
"projectId": "<project_id>",
"activate": true,
"artifacts": [
{
"artifactName": "app.conf",
"binaryBlob": "<base64_encoded_content>",
"fileMetaData": "<base64_encoded_metadata>"
}
]
}
# Attach to an app instance
PATCH /v1/appinstances/{app_instance_id}
{
"patchEnvelopeId": "<envelope_id>"
}
Use Cases
| Use Case | What Goes in the Envelope | How the App Uses It |
|---|---|---|
| Config file rotation | Updated app.conf or settings.yaml | App polls metadata server, detects version change, writes file, sends SIGHUP |
| Certificate rotation | New TLS cert and key PEM files | App detects new cert, writes to /etc/ssl/, reloads web server |
| Feature flags | JSON file with feature flag toggles | App reads on startup and on change without restart |
| Script execution | Shell script or Python script | App downloads, chmod +x, executes – handles patching its own dependencies |
| Container credentials | Registry auth token (encrypted artifact) | Docker Compose runtime reads credential for next pull |
| Edge AI model update | New model weights file (up to 5 MB) | Inference app detects new model, hot-swaps without restarting |
