Skip to content

Cloud-Init Deployment Reference

Reference documentation for deploying plexd on virtual machines using Cloud-Init. Covers the IMDS provider, metadata-related configuration fields, cloud-init templates, and Terraform examples.

IMDSProvider

IMDSProvider implements the MetadataProvider interface by reading a bootstrap token from a cloud instance metadata service (IMDS) over HTTP. It supports IMDSv2 (session-based) with automatic fallback to IMDSv1.

go
type IMDSProvider struct {
    baseURL   string
    tokenPath string
    client    *http.Client
}

Constructor

go
func NewIMDSProvider(cfg *Config, baseURL string) *IMDSProvider
ParameterTypeDescription
cfg*ConfigRegistration config (reads MetadataTokenPath, MetadataTimeout)
baseURLstringIMDS base URL (trailing slashes stripped)

ReadToken

go
func (p *IMDSProvider) ReadToken(ctx context.Context) (string, error)

Fetches {baseURL}{tokenPath} via HTTP GET. Before the GET, attempts IMDSv2 session token acquisition via PUT to /latest/api/token. If IMDSv2 is unavailable, falls back to unauthenticated IMDSv1 GET.

Request behavior:

  • IMDSv2 session: PUT {baseURL}/latest/api/token with X-aws-ec2-metadata-token-ttl-seconds: 21600
  • Method: GET
  • URL: baseURL + cfg.MetadataTokenPath
  • Auth: X-aws-ec2-metadata-token: {sessionToken} (omitted if IMDSv2 session acquisition failed)
  • Timeout: cfg.MetadataTimeout (HTTP client timeout)
  • Body limit: 513 bytes (maxTokenLength + 1) — reads one byte beyond the limit to detect oversized responses without silently truncating
  • Context: request is context-aware and cancellable

Error conditions:

ConditionError message
Request creationregistration: imds: create request: {err}
HTTP failureregistration: imds: request failed: {err}
Non-200 statusregistration: imds: unexpected status {code}
Body read failureregistration: imds: read body: {err}
Empty responseregistration: imds: empty token

Config fields (metadata)

These fields were added to registration.Config for IMDS support:

FieldTypeDefaultDescription
UseMetadataboolfalseEnable cloud metadata token source
MetadataTokenPathstring/plexd/bootstrap-tokenMetadata key path for the bootstrap token
MetadataTimeouttime.Duration2sMaximum time to wait for metadata service response

ApplyDefaults() sets MetadataTokenPath and MetadataTimeout when zero-valued. UseMetadata defaults to false and must be explicitly enabled.

Token resolution with IMDS

When UseMetadata is true and an IMDSProvider (or any MetadataProvider) is set, the metadata source is checked as the fourth priority:

  1. Direct value (Config.TokenValue)
  2. File (Config.TokenFile)
  3. Environment variable (Config.TokenEnv)
  4. Metadata service (MetadataProvider.ReadToken)

If the metadata service returns an error, the resolver falls through to the "no token found" error. Metadata errors are not propagated — they are treated as "source unavailable."

go
cfg := &registration.Config{
    DataDir:           "/var/lib/plexd",
    UseMetadata:       true,
    MetadataTokenPath: "/plexd/bootstrap-token",
    MetadataTimeout:   2 * time.Second,
}
cfg.ApplyDefaults()

provider := registration.NewIMDSProvider(cfg, "http://169.254.169.254")
resolver := registration.NewTokenResolver(cfg, provider)
result, err := resolver.Resolve(ctx)

Cloud-Init templates

user-data.yaml (full)

Location: deploy/cloud-init/user-data.yaml

Full cloud-init template that writes configuration files and installs plexd.

Template variables:

VariableRequiredDefaultDescription
PLEXD_API_URLyesControl plane API URL
PLEXD_BOOTSTRAP_TOKENyesBootstrap token for enrollment
PLEXD_VERSIONnolatestplexd version to install
PLEXD_HOSTNAMEnoHostname override
PLEXD_LOG_LEVELnoinfoLog level

Actions performed:

  1. package_update: true — updates package lists
  2. Writes /etc/plexd/config.yaml (0600) — full configuration with use_metadata: true
  3. Writes /etc/plexd/bootstrap-token (0600) — bootstrap token
  4. Runs install.sh with --token, --api-url, --version

user-data-minimal.yaml

Location: deploy/cloud-init/user-data-minimal.yaml

Minimal template that only writes the bootstrap token file. No runcmd — assumes plexd is pre-installed.

Template variables:

VariableRequiredDescription
PLEXD_BOOTSTRAP_TOKENyesBootstrap token for enrollment

Actions performed:

  1. Writes /etc/plexd/bootstrap-token (0600) — bootstrap token

Terraform examples

AWS EC2

Location: deploy/cloud-init/examples/terraform-aws.tf

Provisions an AWS EC2 instance with plexd enrollment via cloudinit_config data source.

VariableTypeDefaultDescription
plexd_api_urlstringControl plane API URL
plexd_bootstrap_tokenstringBootstrap token (sensitive)
plexd_versionstringlatestplexd version
instance_typestringt3.microEC2 instance type
ami_idstringAMI ID (must support cloud-init)
subnet_idstringSubnet ID
key_namestring""SSH key pair name (optional)

Security: Enforces IMDSv2 (http_tokens = "required").

OpenStack

Location: deploy/cloud-init/examples/terraform-openstack.tf

Provisions an OpenStack compute instance with plexd enrollment.

VariableTypeDefaultDescription
plexd_api_urlstringControl plane API URL
plexd_bootstrap_tokenstringBootstrap token (sensitive)
plexd_versionstringlatestplexd version
flavor_namestringm1.smallOpenStack flavor
image_namestringImage name (must support cloud-init)
network_namestringNetwork name
key_pairstring""SSH key pair name (optional)

Cloud provider IMDS endpoints

Reference table for common cloud provider IMDS base URLs:

ProviderBase URLAuth mechanism
AWShttp://169.254.169.254IMDSv2 session token (automatic)
GCPhttp://metadata.google.internal/computeMetadata/v1Metadata-Flavor: Google header
Azurehttp://169.254.169.254/metadata/instanceMetadata: true header
OpenStackhttp://169.254.169.254/openstack/latest/meta_data.jsonNone
DigitalOceanhttp://169.254.169.254/metadata/v1None

See also