A Datastore tells ZEDEDA Cloud where to find image binaries and container images. ZEDEDA Cloud itself does not store image data — it only stores the metadata (location, credentials, path) and passes the download instruction to EVE-OS. The edge node connects directly to the datastore to pull images at deployment time.
Datastores can be hosted anywhere: public cloud storage, private on-prem file servers, public container registries, or local HTTP servers on the same LAN as the edge node.
There are two top-level categories that determine what kind of content a datastore holds:
| Category | Used For | Examples |
|---|---|---|
| File Storage | VM disk images, raw binaries, EVE-OS firmware, OCI tarballs | HTTP, HTTPS, S3, Azure Blob, SFTP |
| Container Registry | OCI container images pulled by tag or digest | Docker Hub, Azure ACR, GCP GCR, GitHub GHCR, private registry |
| Type | ds_type value | FQDN Format | Auth | Use Case |
|---|---|---|---|---|
| HTTP | DATASTORE_TYPE_HTTP | http://<ip-or-host>:<port> | None | Local lab server, air-gapped LAN, MinIO on HTTP |
| HTTPS | DATASTORE_TYPE_HTTPS | https://<host> | Optional client cert | Secured internal file server |
| Amazon S3 | DATASTORE_TYPE_AWSS3 | https://s3.<region>.amazonaws.com | Access Key ID + Secret | AWS-hosted VM images |
| Azure Blob Storage | DATASTORE_TYPE_AZUREBLOB | https://<account>.blob.core.windows.net | Storage Account Name + Key | Azure-hosted VM images |
| SFTP | DATASTORE_TYPE_SFTP | <ip>:<port> (e.g. 192.168.1.10:22) | Username + Password | On-prem secure file transfer |
| Registry | ds_type value | FQDN | Username | Password |
|---|---|---|---|---|
| Docker Hub | DATASTORE_TYPE_CONTAINERREGISTRY | docker://docker.io | Docker Hub username | Docker Hub password or access token |
| Azure ACR | DATASTORE_TYPE_CONTAINERREGISTRY | docker://<registry>.azurecr.io | _token (literal string) | AD or service principal password |
| GCP GCR | DATASTORE_TYPE_CONTAINERREGISTRY | docker://gcr.io | _token (literal string) | GCP auth token from console |
| GitHub GHCR | DATASTORE_TYPE_CONTAINERREGISTRY | docker://ghcr.io | GitHub username | GitHub personal access token |
| Private Registry | DATASTORE_TYPE_CONTAINERREGISTRY | docker://<your-registry-host> | Registry username | Registry password |
For GitHub personal tokens, the following scopes are required: write:packages, read:packages, delete:packages, and repo if the repository is private.
A plain HTTP server on the local network — typical for lab environments, air-gapped sites, or a local MinIO/Nginx instance serving qcow2 images.
resource "zedcloud_datastore" "demo_atl_ds" {
ds_fqdn = "http://192.168.0.101:1080"
ds_type = "DATASTORE_TYPE_HTTP"
name = "TF-ATL-ZED-DEMO-DS"
title = "TF-ATL-ZED-DEMO-DS"
ds_path = ""
project_access_list = []
}
Notes:
ds_path can be left empty if images sit at the root of the server, or set to a subfolder path (e.g., “images/vms”)project_access_list = [] means the datastore is accessible to all projects in the enterprise; add project UUIDs to restrict accessImages stored in an Azure Blob container. The FQDN is the storage account endpoint; the path is the container name.
resource "zedcloud_datastore" "demo_az_blob_ds" {
name = "TF-ZED-DEMO-AZ-DS"
title = "TF-ZED-DEMO-AZ-DS"
api_key = var.azure_blob_api_username # Storage Account Name
ds_fqdn = var.azure_blob_url # https://<account>.blob.core.windows.net
secret {
api_passwd = var.azure_blob_password # Storage Account Key (key1 or key2)
}
ds_type = var.datastore_type # "DATASTORE_TYPE_AZUREBLOB"
ds_path = var.azure_ds_path # Container name, e.g. "qcow2images"
}
How to find these values in the Azure portal:
api_key) and one of the Keys (this is api_passwd)ds_path)https://<storage-account-name>.blob.core.windows.netFor pulling OCI container images from Docker Hub. No credentials required for public images; add them for private repos or to avoid rate limiting.
resource "zedcloud_datastore" "demo_docker_hub" {
ds_fqdn = "docker://docker.io"
ds_type = "DATASTORE_TYPE_CONTAINERREGISTRY"
name = "TF-ZED-DEMO-DOCKER-HUB"
title = "TF-ZED-DEMO-DOCKER-HUB"
project_access_list = []
}
For authenticated (private repos or rate-limit avoidance):
resource "zedcloud_datastore" "demo_docker_hub_auth" {
ds_fqdn = "docker://docker.io"
ds_type = "DATASTORE_TYPE_CONTAINERREGISTRY"
name = "TF-ZED-DEMO-DOCKER-HUB-AUTH"
title = "TF-ZED-DEMO-DOCKER-HUB-AUTH"
api_key = var.dockerhub_username
secret {
api_passwd = var.dockerhub_token # use an access token, not your password
}
project_access_list = []
}
resource "zedcloud_datastore" "demo_s3_ds" {
name = "TF-ZED-DEMO-S3-DS"
title = "TF-ZED-DEMO-S3-DS"
ds_fqdn = "https://s3.us-east-1.amazonaws.com"
ds_type = "DATASTORE_TYPE_AWSS3"
ds_path = "my-bucket-name/images" # bucket/prefix
api_key = var.aws_access_key_id
secret {
api_passwd = var.aws_secret_access_key
}
}
For pulling container images from a private Azure Container Registry:
resource "zedcloud_datastore" "demo_acr_ds" {
name = "TF-ZED-DEMO-ACR"
title = "TF-ZED-DEMO-ACR"
ds_fqdn = "docker://myregistry.azurecr.io"
ds_type = "DATASTORE_TYPE_CONTAINERREGISTRY"
api_key = "_token" # literal string — always "_token" for Azure ACR
secret {
api_passwd = var.acr_service_principal_password
}
project_access_list = []
}
| Field | HTTP | HTTPS | S3 | Azure Blob | SFTP | Container Registry |
|---|---|---|---|---|---|---|
| FQDN | http://ip:port | https://host | https://s3.region.amazonaws.com | https://account.blob.core.windows.net | ip:port | docker://registry-host |
| Path | image subfolder | image subfolder | bucket/prefix | container name | remote path | not used |
| Region | — | — | e.g. us-east-1 | — | — | — |
| Access Key / Username | — | — | IAM Access Key ID | Storage Account Name | SFTP username | registry username |
| Secret / Password | — | optional cert | IAM Secret Key | Storage Account Key | SFTP password | registry password or token |
# HTTP (local) zcli datastore create TF-ATL-ZED-DEMO-DS \ --dstype=HTTP \ --fqdn=http://192.168.0.101:1080 # Azure Blob zcli datastore create TF-ZED-DEMO-AZ-DS \ --dstype=AZUREBLOB \ --fqdn=https://zededacentral.blob.core.windows.net \ --dpath=qcow2images \ --apikey=<storage-account-name> \ --apipass=<storage-account-key> # Docker Hub zcli datastore create TF-ZED-DEMO-DOCKER-HUB \ --dstype=CONTAINERREGISTRY \ --fqdn=docker://docker.io # AWS S3 zcli datastore create TF-ZED-DEMO-S3-DS \ --dstype=AWSS3 \ --fqdn=https://s3.us-east-1.amazonaws.com \ --dpath=my-bucket/images \ --apikey=AKIAIOSFODNN7EXAMPLE \ --apipass=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
POST /v1/datastores
{
"name": "TF-ATL-ZED-DEMO-DS",
"title": "TF-ATL-ZED-DEMO-DS",
"dType": "DATASTORE_TYPE_HTTP",
"fqdn": "http://192.168.0.101:1080",
"dPath": ""
}
POST /v1/datastores
{
"name": "TF-ZED-DEMO-AZ-DS",
"dType": "DATASTORE_TYPE_AZUREBLOB",
"fqdn": "https://zededacentral.blob.core.windows.net",
"dPath": "qcow2images",
"apiKey": "<storage-account-name>",
"password": "<storage-account-key>"
}
POST /v1/datastores
{
"name": "TF-ZED-DEMO-DOCKER-HUB",
"dType": "DATASTORE_TYPE_CONTAINERREGISTRY",
"fqdn": "docker://docker.io"
}
The datastore record is never pushed to the edge node directly at creation time. The node only interacts with it when an image referencing the datastore is assigned to an app instance:
For sites with limited or no internet connectivity, ZEDEDA supports a primary/secondary datastore pattern via Edge Sync:
This allows images to be pre-staged on local storage before nodes are shipped to low-bandwidth or disconnected sites.
The project_access_list field controls which projects can reference this datastore:
[] (empty list) — datastore is accessible to all projects in the enterprise[“<project-uuid-1>”, “<project-uuid-2>”] — restricts access to only those projectsThis is useful in multi-tenant or MSP scenarios where different customers' datastores must be isolated.