Verda Instance Builder
Type: verda-instance
Artifact BuilderId: verda.instance
The verda-instance builder creates a Verda instance, waits for it to become reachable, and runs standard Packer provisioners over SSH.
By default the artifact is the created instance. With artifact_type = "os_volume", the builder shuts down the instance, clones its OS volume, and returns the cloned volume artifact. The returned OS volume ID can be used later as the Verda instance image value in Terraform or another API client.
A successful instance artifact remains live until Packer destroys it. Set keep_instance = true to prevent artifact destruction and failed-build cleanup from deleting the build instance. OS volume builds delete their temporary instance after capture unless keep_instance is enabled.
Configuration Reference
Required
-
client_id(string) - Verda client ID. It can also be set with VERDA_CLIENT_ID. -
client_secret(string) - Verda client secret. It can also be set with VERDA_CLIENT_SECRET. -
instance_type(string) - Verda instance type to create. -
image(string) - Image name, image ID, or OS volume ID to boot from. -
hostname(string) - Hostname for the created instance.
Optional
-
base_url(string) - Verda API base URL. Leave unset for the production API. -
debug(bool) - Enable verbose Verda SDK logging. -
description(string) - Description for the created instance. Defaults to a Packer build description based on the hostname. -
location_code(string) - Verda location code for the instance. Defaults to FIN-03. -
contract(string) - Instance contract. Defaults to PAY_AS_YOU_GO, or SPOT when is_spot is true. -
pricing(string) - Optional pricing value passed to the Verda API. -
is_spot(bool) - Request a spot instance. When true, the default contract is SPOT. -
coupon(string) - Optional coupon value passed to the Verda API. -
ssh_key_ids([]string) - Existing Verda SSH key IDs to add to the instance. -
temporary_ssh_key_name(string) - Name for the temporary Verda SSH key created from Packer’s generated public key. -
skip_temporary_ssh_key(bool) - Disable temporary Verda SSH key creation. When true with SSH, provide ssh_key_ids and a matching SSH credential. -
startup_script_id(string) - Existing Verda startup script ID to attach to the instance. -
startup_script(string) - Startup script content to create before launching the instance. -
startup_script_name(string) - Name for a startup script created from startup_script. -
delete_startup_script(bool) - Delete a startup script created from startup_script during cleanup. -
existing_volume_ids([]string) - Existing non-OS volume IDs to attach to the instance. -
os_volume_name(string) - Name for the instance OS volume. -
os_volume_size(int) - Size, in GiB, for the instance OS volume. -
os_volume_spot_behavior(string) - Spot discontinuation behavior for the instance OS volume. -
volume([]Volume) - Additional data volumes to create with the instance. -
artifact_type(string) - Artifact to return from the build. Valid values are instance and os_volume. Defaults to instance. -
clone_os_volume(*bool) - Clone the source OS volume when artifact_type is os_volume. Defaults to true. -
artifact_volume_name(string) - Name for each cloned OS volume artifact. -
artifact_volume_location_code(string) - Deprecated: use artifact_volume_location_codes. Target location for a cloned OS volume artifact. -
artifact_volume_location_codes([]string) - Target locations for cloned OS volume artifacts. The first location is primary; the effective locations also include the source location exactly once. -
skip_shutdown_before_artifact(bool) - Skip shutting down the instance before creating an OS volume artifact. -
keep_instance(bool) - Keep the build instance during failed-build cleanup and when Packer destroys the returned instance artifact. -
delete_permanently(bool) - Permanently delete resources during cleanup instead of moving them to a recoverable state. -
volume_ids_to_delete([]string) - Volume IDs to delete when the instance is deleted. -
poll_interval(duration stringex: “1h5m2s”) - Interval between Verda instance status checks. Defaults to 15s. -
instance_timeout(duration stringex: “1h5m2s”) - Timeout for the instance to become reachable. Defaults to 30m. -
api_timeout(duration stringex: “1h5m2s”) - HTTP client timeout for Verda API calls. Defaults to 10m. allowed_ssh_statuses([]string) - Instance statuses that are acceptable for SSH connection attempts. Defaults to running.
Additional Volume Blocks
Use volume blocks to create additional non-OS data volumes with the instance.
Required volume fields:
-
name(string) - Name for the additional volume. -
size(int) - Size, in GiB, for the additional volume. -
type(string) - Volume type.
Optional volume fields:
-
location_code(string) - Verda location code for the additional volume. Defaults to the instance location when unset. -
on_spot_discontinue(string) - Spot discontinuation behavior for the additional volume.
Communicator Config
This builder supports the ssh and none communicators. SSH is the default and uses root as the default username.
Most SSH options below are inherited from Packer’s standard SSH communicator. The Verda-specific SSH settings are ssh_key_ids, temporary_ssh_key_name, and skip_temporary_ssh_key. By default the builder generates a temporary Packer key pair, creates a temporary Verda SSH key from its public key, passes that key ID when creating the build instance, and deletes the Verda key during cleanup.
-
communicator(string) - Packer currently supports three kinds of communicators:-
none- No communicator will be used. If this is set, most provisioners also can’t be used. -
ssh- An SSH connection will be established to the machine. This is usually the default. -
winrm- A WinRM connection will be established.
In addition to the above, some builders have custom communicators they can use. For example, the Docker builder has a “docker” communicator that uses
docker execanddocker cpto execute scripts and copy files. -
-
pause_before_connecting(duration string | ex: “1h5m2s”) - We recommend that you enable SSH or WinRM as the very last step in your guest’s bootstrap script, but sometimes you may have a race condition where you need Packer to wait before attempting to connect to your guest.If you end up in this situation, you can use the template option
pause_before_connecting. By default, there is no pause. For example if you setpause_before_connectingto10mPacker will check whether it can connect, as normal. But once a connection attempt is successful, it will disconnect and then wait 10 minutes before connecting to the guest and beginning provisioning.
-
temporary_key_pair_type(string) -dsaecdsaed25519rsa( the default )Specifies the type of key to create. The possible values are ‘dsa’, ‘ecdsa’, ‘ed25519’, or ‘rsa’.
NOTE: DSA is deprecated and no longer recognized as secure, please consider other alternatives like RSA or ED25519.
-
temporary_key_pair_bits(int) - Specifies the number of bits in the key to create. For RSA keys, the minimum size is 1024 bits and the default is 4096 bits. Generally, 3072 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, bits determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. Ed25519 keys have a fixed length and bits will be ignored.NOTE: DSA is deprecated and no longer recognized as secure as specified by FIPS 186-5, please consider other alternatives like RSA or ED25519.
-
ssh_host(string) - The address to SSH to. This usually is automatically configured by the builder. -
ssh_port(int) - The port to connect to SSH. This defaults to22. -
ssh_username(string) - The username to connect to SSH with. Required if using SSH. -
ssh_password(string) - A plaintext password to use to authenticate with SSH. -
ssh_ciphers([]string) - This overrides the value of ciphers supported by default by Golang. The default value is [ “[email protected]”, “[email protected]”, “aes128-ctr”, “aes192-ctr”, “aes256-ctr”, ]Valid options for ciphers include: “aes128-ctr”, “aes192-ctr”, “aes256-ctr”, “[email protected]”, “[email protected]”, “arcfour256”, “arcfour128”, “arcfour”, “aes128-cbc”, “3des-cbc”,
-
ssh_clear_authorized_keys(bool) - If true, Packer will attempt to remove its temporary key from~/.ssh/authorized_keysand/root/.ssh/authorized_keys. This is a mostly cosmetic option, since Packer will delete the temporary private key from the host system regardless of whether this is set to true (unless the user has set the-debugflag). Defaults to “false”; currently only works on guests withsedinstalled. -
ssh_key_exchange_algorithms([]string) - If set, Packer will override the value of key exchange (kex) algorithms supported by default by Golang. Acceptable values include: “[email protected]”, “ecdh-sha2-nistp256”, “ecdh-sha2-nistp384”, “ecdh-sha2-nistp521”, “diffie-hellman-group14-sha1”, and “diffie-hellman-group1-sha1”. -
ssh_certificate_file(string) - Path to user certificate used to authenticate with SSH. The~can be used in path and will be expanded to the home directory of current user. -
ssh_pty(bool) - Iftrue, a PTY will be requested for the SSH connection. This defaults tofalse. -
ssh_timeout(duration string | ex: “1h5m2s”) - The time to wait for SSH to become available. Packer uses this to determine when the machine has booted so this is usually quite long. Example value:10m. This defaults to5m, unlessssh_handshake_attemptsis set. -
ssh_disable_agent_forwarding(bool) - If true, SSH agent forwarding will be disabled. Defaults tofalse. -
ssh_handshake_attempts(int) - The number of handshakes to attempt with SSH once it can connect. This defaults to10, unless assh_timeoutis set. -
ssh_bastion_host(string) - A bastion host to use for the actual SSH connection. -
ssh_bastion_port(int) - The port of the bastion host. Defaults to22. -
ssh_bastion_agent_auth(bool) - Iftrue, the local SSH agent will be used to authenticate with the bastion host. Defaults tofalse. -
ssh_bastion_username(string) - The username to connect to the bastion host. -
ssh_bastion_password(string) - The password to use to authenticate with the bastion host. -
ssh_bastion_interactive(bool) - Iftrue, the keyboard-interactive used to authenticate with bastion host. -
ssh_bastion_private_key_file(string) - Path to a PEM encoded private key file to use to authenticate with the bastion host. The~can be used in path and will be expanded to the home directory of current user. -
ssh_bastion_certificate_file(string) - Path to user certificate used to authenticate with bastion host. The~can be used in path and will be expanded to the home directory of current user. -
ssh_file_transfer_method(string) -scporsftp- How to transfer files, Secure copy (default) or SSH File Transfer Protocol.NOTE: Guests using Windows with Win32-OpenSSH v9.1.0.0p1-Beta, scp (the default protocol for copying data) returns a a non-zero error code since the MOTW cannot be set, which cause any file transfer to fail. As a workaround you can override the transfer protocol with SFTP instead
ssh_file_transfer_method = "sftp". -
ssh_proxy_host(string) - A SOCKS proxy host to use for SSH connection -
ssh_proxy_port(int) - A port of the SOCKS proxy. Defaults to1080. -
ssh_proxy_username(string) - The optional username to authenticate with the proxy server. -
ssh_proxy_password(string) - The optional password to use to authenticate with the proxy server. -
ssh_keep_alive_interval(duration string | ex: “1h5m2s”) - How often to send “keep alive” messages to the server. Set to a negative value (-1s) to disable. Example value:10s. Defaults to5s. -
ssh_read_write_timeout(duration string | ex: “1h5m2s”) - The amount of time to wait for a remote command to end. This might be useful if, for example, packer hangs on a connection after a reboot. Example:5m. Disabled by default. -
ssh_remote_tunnels([]string) - Remote tunnels forward a port from your local machine to the instance. Format: [“REMOTE_PORT:LOCAL_HOST:LOCAL_PORT”] Example: “9090:localhost:80” forwards localhost:9090 on your machine to port 80 on the instance. -
ssh_local_tunnels([]string) - Local tunnels forward a port from the instance to your local machine. Format: [“LOCAL_PORT:REMOTE_HOST:REMOTE_PORT”] Example: “8080:localhost:3000” allows the instance to access your local machine’s port 3000 via localhost:8080.
ssh_private_key_file(string) - Path to a PEM encoded private key file to use to authenticate with SSH. The~can be used in path and will be expanded to the home directory of current user.
Basic Example
packer {
required_plugins {
verda = {
version = ">= 0.1.0"
source = "github.com/thevilledev/verda"
}
}
}
source "verda-instance" "ubuntu" {
instance_type = "1L40S.20V"
location_code = "FIN-03"
image = "ubuntu-24.04"
hostname = "packer-verda-example"
ssh_username = "root"
}
build {
sources = ["source.verda-instance.ubuntu"]
provisioner "shell" {
inline = [
"cloud-init status --wait || true",
"uname -a",
]
}
}
Spot Builds
Set is_spot = true to create the Packer build instance as Verda spot capacity. This defaults contract to SPOT. Setting contract = "SPOT" is also accepted and sends the same spot request to Verda. Configurations that set is_spot = true with a non-SPOT contract are rejected during packer validate.
source "verda-instance" "ubuntu_spot" {
instance_type = "1L40S.20V"
location_code = "FIN-03"
image = "ubuntu-24.04"
hostname = "packer-verda-spot-example"
is_spot = true
ssh_username = "root"
}
Spot builds can also set discontinuation behavior for volumes created with the instance. Use os_volume_spot_behavior for the OS volume and on_spot_discontinue inside each volume block. Valid values are keep_detached, move_to_trash, and delete_permanently.
OS Volume Artifacts
Set artifact_type = "os_volume" to return a cloned OS volume instead of the instance. The effective artifact locations are the configured artifact_volume_location_codes followed by the source instance location when it was not already listed, compared case-insensitively. The first configured location is the primary artifact ID, while console output and generated data expose every location and volume ID.
Verda does not support cloning an attached OS volume directly across datacenters. The builder first creates the source-location artifact, waits for it to become detached, and uses that artifact as the source for the remaining locations. The source-location artifact is included once in the effective artifact set.
Instances booted later from an existing OS volume cannot rely on Verda ssh_key_ids injection. Bake durable login keys into the guest during the Packer build, and enable ssh_clear_authorized_keys so Packer’s temporary build key is removed before the volume is captured.
variable "authorized_keys_file" {
type = string
description = "Path to an authorized_keys-format file to bake into the OS volume."
}
source "verda-instance" "ubuntu_volume" {
instance_type = "1A6000.10V"
location_code = "FIN-01"
image = "ubuntu-24.04"
hostname = "packer-verda-volume"
ssh_username = "root"
ssh_clear_authorized_keys = true
artifact_type = "os_volume"
artifact_volume_name = "packer-verda-volume-root"
artifact_volume_location_codes = ["FIN-01", "FIN-03"]
}
build {
sources = ["source.verda-instance.ubuntu_volume"]
provisioner "file" {
source = var.authorized_keys_file
destination = "/tmp/verda_authorized_keys"
}
provisioner "shell" {
inline = [
"cloud-init status --wait || true",
"install -d -m 0700 /root/.ssh",
"touch /root/.ssh/authorized_keys",
"chmod 0600 /root/.ssh/authorized_keys",
"while IFS= read -r key; do [ -n \"$key\" ] || continue; grep -qxF \"$key\" /root/.ssh/authorized_keys || printf '%s\\n' \"$key\" >> /root/.ssh/authorized_keys; done < /tmp/verda_authorized_keys",
"chown root:root /root/.ssh /root/.ssh/authorized_keys",
"rm -f /tmp/verda_authorized_keys",
]
}
}
Persisting volume IDs
The Packer artifact ID is singular, so use a manifest post-processor to persist the complete multi-location mapping. Manifest custom data values are strings; encode the list and map as JSON.
post-processor "manifest" {
output = "packer-manifest.json"
custom_data = {
VolumeID = build.VolumeID
SourceOSVolumeID = build.SourceOSVolumeID
VolumeIDs = jsonencode(build.VolumeIDs)
VolumeIDsByLocation = jsonencode(build.VolumeIDsByLocation)
}
}
Packer appends repeated runs to the manifest. For a single-build workflow, inspect the latest entry:
jq '.builds[-1].custom_data.VolumeIDsByLocation | fromjson' packer-manifest.json
Terraform Handoff
Use the Packer OS volume artifact ID, or a clone of it, as the Terraform verda_instance.image value. Do not pass it through existing_volumes; that field attaches additional non-OS volumes. Do not rely on ssh_key_ids here when booting from an existing OS volume; the keys must already be present in the guest image, or installed by a boot script that runs inside the guest.
For multiple locations, select the volume ID matching each instance location. The manifest stores the map as a JSON string inside its JSON document, so decode both layers. For multiple instances in the same location, clone that location’s Packer artifact once per instance before passing each clone ID as image.
locals {
packer_manifest = jsondecode(file("${path.module}/packer-manifest.json"))
packer_build = local.packer_manifest.builds[length(local.packer_manifest.builds) - 1]
os_volume_ids_by_location = jsondecode(
local.packer_build.custom_data.VolumeIDsByLocation
)
}
resource "verda_instance" "app" {
instance_type = "1B200.30V"
image = local.os_volume_ids_by_location["FIN-03"]
hostname = "app-01"
description = "App server from Packer OS volume"
location = "FIN-03"
ssh_key_ids = []
}
Verda volumes do not expose tags, labels, or arbitrary metadata through the public API, Terraform provider, or Go SDK. Put release identifiers in the volume name or track them in external inventory.