Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔵 F5OS Primary Key Terraform Module

Manages the system primary key (f5os_primarykey) — passphrase and salt used for at-rest secret encryption — on an F5OS platform (VELOS chassis partition or rSeries appliance), targeting the F5Networks/f5os provider ~> 1.10 (verified against v1.12.0).

Terraform Provider Module Type Resources Posture


🧩 Overview

  • 🏷️ Manages exactly one f5os_primarykey resource — a passphrase/salt pair the F5OS platform uses to derive the system's at-rest-encryption primary key.
  • 🧱 Standalone module: single keystone resource named this, no children, no for_each inside the module boundary — the provider models this resource as three flat arguments with no nested/child collection.
  • 🌐 Applies identically to a VELOS chassis partition or an rSeries appliance — the f5os_primarykey schema carries no platform-specific argument.
  • 🔒 passphrase and salt are both Required, String, Sensitive per the live schema — declared as their own dedicated sensitive = true top-level variables, never nested inside an object, never given a default.
  • ⚠️ This is a system-wide security control, not a per-tenant/per-partition/per-VLAN setting — get it right once per target platform, since it governs encryption of every secret the platform stores at rest.

💡 Why it matters: the primary key underpins at-rest encryption for every secret the F5OS platform stores — stored credentials, sensitive configuration values, and anything else the platform encrypts at rest. Rotating it is a high-impact, security-relevant operation; this module's own defaults (force_update = false, no baked-in passphrase/salt, no secret-shaped output) are deliberately conservative so that applying this module never silently rotates the key or leaks key material.


❤️ Support this project

If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:

Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!


🗺️ Where this fits

graph LR
 subgraph DOMAIN["system-identity domain (no data dependency between members)"]
 PRIMARYKEY["terraform-f5os-primarykey"]:::this
 AUTH["terraform-f5os-auth"]:::sibling
 USER["terraform-f5os-user"]:::sibling
 end
 PLATFORM["F5OS platform (VELOS chassis partition or rSeries appliance)"]:::target

 PRIMARYKEY -->|"configures primary key directly against"| PLATFORM
 AUTH -->|"configures auth directly against"| PLATFORM
 USER -->|"configures user accounts directly against"| PLATFORM

 classDef this fill:#E4002B,color:#ffffff,stroke:#8f0016,stroke-width:1px;
 classDef target fill:#1B2A4A,color:#ffffff,stroke:#0d1626,stroke-width:1px;
 classDef sibling fill:#E8E8E8,color:#1a1a1a,stroke:#b5b5b5,stroke-width:1px;
Loading

terraform-f5os-primarykey (red) has no genuine sibling family in the sense terraform-f5os-vlan has terraform-f5os-interface/terraform-f5os-lag — there is no shared keystone, no cross-module ID/name reference, and no ordering dependency between this module and terraform-f5os-auth or terraform-f5os-user. The three are grouped here only because they share a loose conceptual domain (system-level identity/security configuration) in the module catalog. Each connects independently and directly to the target F5OS platform; none owns or consumes another's output. Do not read an edge between PRIMARYKEY, AUTH, or USER into this diagram — none exists.


🧬 What this builds

graph LR
 subgraph Inputs["Inputs"]
 VAR_PASS["var.passphrase (sensitive)"]
 VAR_SALT["var.salt (sensitive)"]
 VAR_FORCE["var.force_update (default false)"]
 end

 RES["f5os_primarykey.this"]:::this

 subgraph Outputs["Outputs"]
 OUT_ID["id"]
 OUT_STATUS["status"]
 OUT_HASH["hash (sensitive)"]
 end

 VAR_PASS -->|"passphrase"| RES
 VAR_SALT -->|"salt"| RES
 VAR_FORCE -->|"force_update"| RES
 RES -->|"exposes"| OUT_ID
 RES -->|"exposes"| OUT_STATUS
 RES -->|"exposes"| OUT_HASH

 classDef this fill:#E4002B,color:#ffffff,stroke:#8f0016,stroke-width:1px;
Loading

Resource inventory

Resource Terraform address Cardinality
f5os_primarykey f5os_primarykey.this Exactly 1 per module call

✅ Provider / Versions

Item Value
Terraform floor >= 1.12.0
Provider pin F5Networks/f5os ~> 1.10 — verified against the live Terraform Registry listing via get_provider_capabilities; terraform init resolved v1.12.0 during authoring, which satisfies this constraint
Provider block None in this module — the caller configures provider "f5os" {} once, in the root module, targeting a single already-authenticated VELOS chassis controller or rSeries appliance
Platform context Both — VELOS chassis partition and rSeries appliance. f5os_primarykey's schema carries no partition-specific or appliance-specific argument; behavior is identical on either target

Schema notes that bite (verified against the live f5os_primarykey Argument/Attributes Reference, provider_doc_id 12473310):

  • passphrase and salt are both plain String, Sensitive with no documented minimum length, complexity, or format constraint in the fetched reference. Terraform's type system cannot catch a weak or trivially short value — terraform validate passes regardless; only the F5OS platform's own policy (if any) would reject it, and only at apply time.
  • force_update (Boolean, Optional) has no documented default in the fetched reference. This module supplies its own default of false in variables.tf as a deliberate, conservative module-specific choice — it is not a verified provider default, and is called out as such throughout this README and SCOPE.md.
  • hash, id, and status are all Read-Only (Computed) — the caller cannot set any of them; they are only populated after apply. The fetched reference documents id as "Constant for now", implying it does not vary meaningfully across invocations against the same target — treat it as an opaque, provider-assigned token rather than a value to construct or parse.
  • The fetched reference does not include an Import Usage section for this resource — unlike f5os_vlan (terraform import f5os_vlan.example 4) or f5os_tenant_image (bare image_name string), no documented terraform import syntax exists for f5os_primarykey in what was retrieved. Do not assume a bare-ID or any other import pattern for this resource without confirming directly against the provider's current documentation or terraform import -help before scripting an import.
  • No (Requires replacement) annotation is surfaced on any argument in the fetched reference — confirm actual in-place-update behavior against a real terraform plan before assuming a changed passphrase/salt updates in place rather than forcing recreation.
  • hash is not marked Sensitive in the provider's own schema, even though it is derived from the primary key's key material. This module marks the hash output sensitive = true anyway — a conservative module-specific choice layered on top of the provider's schema, not a correction of it. See "Architecture Notes."

🔑 Required F5OS User Role / Chassis Partition Access

Least-privilege role: admin, scoped to the target chassis partition (VELOS) or the appliance itself (rSeries). Rotating the system primary key changes the key used for at-rest encryption of every secret already stored on the device — a materially higher-impact operation than routine VLAN/DNS/interface configuration — and per the f5os_user resource's documented role set (role — "Specifies primary role assigned to the user (e.g., admin, operator, user)"), treats admin as the least-privilege role appropriate here. operator/user are not asserted as sufficient, since the provider's own documentation does not scope primary-key management privilege to those roles. Confirm the live RBAC role catalog and its actual privilege grants on the target platform before granting access — role-to-privilege mapping may differ per F5OS release, and this module does not invent a role name beyond admin/operator/user, the only three the provider's documentation shows as examples.

F5OS Prerequisites

  • F5OS provider F5Networks/f5os ~> 1.10; Terraform >= 1.12.0.
  • Applies to both platform contexts — VELOS chassis partition and rSeries appliance. The f5os_primarykey resource's schema carries no partition-specific or appliance-specific argument.
  • No F5OS release-specific minimum version is called out in the fetched provider documentation for f5os_primarykey itself — confirm against the target device's running F5OS release notes if a specific minimum matters for your deployment.
  • No image, VLAN, chassis partition, or tenant needs to be staged before this module — the primary key is a platform-level system setting with no dependency on any other F5OS object in this catalog.
  • passphrase and salt must already be available to the caller from an out-of-band secret manager or CI-injected sensitive variable before this module is applied — this module has no default and no way to generate or discover either value itself.
  • The single, already-authenticated f5os provider instance in scope must target the chassis partition or appliance whose primary key should be managed.

📁 Module Structure

terraform-f5os-primarykey/
├── providers.tf # required_version, F5Networks/f5os ~> 1.10 — no provider {} block
├── variables.tf # var.passphrase (sensitive), var.salt (sensitive), var.force_update — 1:1 mapped to the real f5os_primarykey schema
├── main.tf # f5os_primarykey.this — the module's single keystone resource
├── outputs.tf # id, status, hash (sensitive)
├── SCOPE.md # lightweight standalone contract — RBAC, prerequisites, emits, gotchas
└── README.md # this file — worked example configurations live in 📚 Example Library below

No separate examples/ directory ships with this module — every worked configuration is captured inline in the 📚 Example Library below, using the module's real variable names.


⚙️ Quick Start

# The caller configures the provider once, elsewhere in the root module:
# provider "f5os" {
# host = var.f5os_host
# username = var.f5os_username
# password = var.f5os_password
# }

module "system_primary_key" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase # sourced out of band — see "Design Principles"
  salt       = var.f5os_primarykey_salt       # sourced out of band — see "Design Principles"
}

🔌 Cross-Module Contract

Consumes

Input Type Source module
— — None. This is a leaf module in the F5OS catalog; it has no upstream dependency on another terraform-f5os-* module's output.

Emits

Output Description Consumed by
id Terraform resource ID for the primary key — constant for now, per the provider's own schema note Not typically referenced by sibling modules — informational/state-tracking use
status Status of the primary-key operation as returned by the F5OS platform (e.g. "COMPLETE") Informational — useful for a root-module readiness check
hash Hash of the primary key as returned by the F5OS system (sensitive = true, -specific conservative marking) Not typically referenced by sibling modules — informational/audit use only, must be handled as sensitive wherever consumed

passphrase and salt are never emitted as outputs — see "Architecture Notes."


📚 Example Library

1 · Minimal primary key

The smallest real call — both required secrets set, force_update left at its default (false).

module "primary_key_minimal" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

💡 Neither var.f5os_primarykey_passphrase nor var.f5os_primarykey_salt should ever be a literal in a committed file — see Example 3 for out-of-band sourcing.

2 · Explicit force_update rotation
module "primary_key_forced_rotation" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase   = var.f5os_primarykey_passphrase
  salt         = var.f5os_primarykey_salt
  force_update = true
}

⚠️ force_update = true is a deliberate, disruptive opt-in — it forces the primary-key update on the device. Coordinate with Compliance/Risk before applying this against a production system already holding encrypted secrets.

3 · Sourcing passphrase/salt from environment variables
module "primary_key_env_sourced" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  # passphrase / salt deliberately not set here — export them out of band:
  # $ $env:TF_VAR_passphrase = (secret manager lookup)
  # $ $env:TF_VAR_salt = (secret manager lookup)
  # $ terraform apply
  passphrase = var.passphrase
  salt       = var.salt
}

🔒 Never write passphrase/salt directly in a .tf/.tfvars file committed to source control. TF_VAR_passphrase/TF_VAR_salt (or an HCP Terraform / CI-injected sensitive variable) keeps the plaintext out of the repository entirely.

4 · Rotating an existing primary key
module "primary_key_rotate" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase   = var.f5os_primarykey_new_passphrase
  salt         = var.f5os_primarykey_new_salt
  force_update = true
}

⚠️ This is a high-impact operation: it changes the key used for at-rest encryption on the target platform. See "Architecture Notes" for the operational implication before wiring this into any unattended pipeline.

5 · VELOS chassis partition target context

The module call itself is identical to the rSeries case — only the caller's provider "f5os" {} block (outside this module) changes to point at the VELOS chassis controller partition's management endpoint.

# provider "f5os" {
# host = var.velos_partition_mgmt_ip
# username = var.f5os_username
# password = var.f5os_password
# }

module "primary_key_velos" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}
6 · rSeries appliance target context
# provider "f5os" {
# host = var.rseries_appliance_mgmt_ip
# username = var.f5os_username
# password = var.f5os_password
# }

module "primary_key_rseries" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

💡 f5os_primarykey behaves identically on VELOS and rSeries — there is no platform-context branch inside this module.

7 · Consuming the status output for a readiness check
module "primary_key" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

output "primary_key_status" {
  description = "Readiness signal a downstream pipeline stage can check before proceeding."
  value       = module.primary_key.status
}

ℹ️ status is not sensitive — it is safe to surface in plan/apply output and CI logs, unlike hash.

8 · Referencing the sensitive hash output downstream
module "primary_key" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

# Illustrative — pass module.primary_key.hash into a downstream sensitive-typed variable only,
# never into a non-sensitive output or a resource argument that Terraform would render in plan
# output. Terraform's sensitivity propagation keeps it redacted as long as every consumer along
# the chain preserves sensitivity.

🔒 Never re-declare an output that re-exposes hash as non-sensitive further down the chain — that would defeat the redaction this module deliberately applies.

9 · Omitting force_update (relies on the default)
module "primary_key_default_force_update" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
  # force_update intentionally omitted — defaults to false per this module's variables.tf
}

💡 This module's false default is a module-specific conservative choice, not a value confirmed in the provider's own documentation — see "Schema notes that bite."

10 · Short/weak passphrase (failure mode, documented deliberately)
module "primary_key_weak" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = "a"
  salt       = "b"
}

⚠️ This passes terraform validate — the schema types both fields as plain string with no documented length/complexity constraint. If the F5OS platform enforces its own passphrase/salt policy, it will only surface as an apply-time failure against a real chassis/appliance, not a plan-time diagnostic. Never use trivial values in practice; source strong, randomly generated values from a secret manager.

11 · Sourcing from an external secret manager (illustrative pattern)
# Illustrative only — this module does not depend on any specific secret-manager provider.
# Wire whichever secret manager your environment uses into these two variables; do not
# hardcode the resolved values anywhere in checked-in configuration.

module "primary_key_from_secret_manager" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase # populated from your secret manager at plan/apply time
  salt       = var.f5os_primarykey_salt       # populated from your secret manager at plan/apply time
}

ℹ️ This module intentionally has no built-in secret-manager integration — it only accepts already -resolved string values, keeping it provider-agnostic on the secrets-sourcing side.

12 · Externalizing force_update via terraform.tfvars

force_update is not secret-shaped, so — unlike passphrase/salt — it is safe to externalize via a checked-in .tfvars file.

# primarykey.auto.tfvars
force_update = false
# main.tf (caller)
module "primary_key_from_tfvars" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase   = var.f5os_primarykey_passphrase # still sourced out of band — never in.tfvars
  salt         = var.f5os_primarykey_salt       # still sourced out of band — never in.tfvars
  force_update = var.force_update
}
13 · Per-environment invocations via Terraform workspaces

Each F5OS target (a VELOS chassis partition or an rSeries appliance) has exactly one primary key — there is no genuine for_each-able collection of primary keys within a single target the way terraform-f5os-vlan has many VLANs. Managing several independent targets is a root-module concern, typically one Terraform workspace (or one pipeline stage) per target, each with its own provider-instance configuration and its own passphrase/salt pair.

# workspace: association-fi-velos-partition-a
module "primary_key" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

ℹ️ Do not attempt to fan this module out across multiple targets with a single for_each — per this module suite's design conventions, multi-target fan-out is a root-module/pipeline concern, never handled inside a reusable module.

🏗️ 14 · End-to-end composition — primary key established before secret-bearing configuration

The primary key governs at-rest encryption for everything the platform stores as a secret. This example shows the recommended bootstrap ordering on a fresh F5OS target: establish the primary key first, then apply the modules that stage or configure secret-bearing objects (a tenant image transfer that may use remote_password, and a tenant deployment). There is no schema-level attribute one of these modules could reference from terraform-f5os-primarykey — the ordering relationship is operational, not a Terraform attribute reference — so it is expressed with an explicit depends_on at the root module rather than a fabricated data dependency.

module "primary_key" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-primarykey.git?ref=v1.0.0"

  passphrase = var.f5os_primarykey_passphrase
  salt       = var.f5os_primarykey_salt
}

module "vlan_app_data" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"

  vlan = {
    vlan_id = 500
    name    = "vlan500-app-data"
  }

  depends_on = [module.primary_key]
}

module "bigip_image" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-tenant-image.git?ref=v1.0.0"

  tenant_image = {
    image_name  = "BIGIP-17.1.0-0.0.16.ALL-F5OS.qcow2.zip.bundle"
    remote_host = "images.internal.example.com"
    remote_path = "v17.1.0/daily/current/VM"
    local_path  = "images"
    protocol    = "https"
  }

  depends_on = [module.primary_key]
}

module "tenant_appA" {
  source = "git::https://github.com/microsoftexpert/terraform-f5os-tenant.git?ref=v1.0.0"

  # Illustrative — consult terraform-f5os-tenant's own README for its full variable schema.
  # image_name = module.bigip_image.image_name
  # vlans = [module.vlan_app_data.vlan_id]

  depends_on = [module.primary_key]
}

💡 Why it matters: this module has no genuine sibling family and no natural cross-module attribute reference — its relationship to the rest of the catalog is purely ordering-based ("set the primary key before anything that depends on at-rest encryption of secrets"), which is exactly why the family DAG above shows no edges between terraform-f5os-primarykey and its loosely-grouped system-identity siblings. Use depends_on, never an invented output reference, to express this kind of operational-only ordering.


📥 Inputs

Name Type Required Sensitive Description
passphrase string Yes Yes Passphrase for generating the F5OS system primary key. No default — always caller-supplied, sourced out of band.
salt string Yes Yes Salt for generating the F5OS system primary key. No default — always caller-supplied, sourced out of band.
force_update bool No No Forces an update of the primary key on the F5OS device. Defaults to false — a module-specific conservative choice; the provider itself documents no default.
Full variable declarations
variable "passphrase" {
  type      = string
  sensitive = true
}

variable "salt" {
  type      = string
  sensitive = true
}

variable "force_update" {
  type    = bool
  default = false
}

No object wrapper is used here — see "Architecture Notes" for why these three arguments are declared as flat top-level variables rather than a single nested type, mirroring terraform-f5os-partition-change-password's precedent for the same reasoning.


🧾 Outputs

Output Description Sensitive
id Terraform resource ID for the primary key — constant for now, per the provider's own schema note No
status Status of the primary-key operation as returned by the F5OS platform (e.g. "COMPLETE") No
hash Hash of the primary key as returned by the F5OS system Yes (-specific conservative marking)

passphrase and salt are never emitted as outputs, even marked sensitive = true.


🧠 Architecture Notes

  • Single keystone resource, no for_each. f5os_primarykey's schema exposes no nested/child collection and represents a singleton setting per target platform — there is no genuine child, and no genuine multiplicity, to iterate over.
  • Three flat top-level variables, not one object. Terraform's sensitive = true flag applies at the whole-variable level, not to individual attributes inside an object type. Wrapping passphrase, salt, and force_update in one object would force marking the entire object sensitive, hiding force_update from plan output unnecessarily. Since the provider's own schema for this resource is genuinely flat (no nested block), keeping the module's variables flat as well is also the more accurate 1:1 mapping per this module suite's rule against inventing nested grouping the provider doesn't have — this mirrors terraform-f5os-partition-change-password's precedent for the same reasoning.
  • No try(x, null) needed. passphrase and salt are Required with no provider-side default. force_update is Optional per the schema, but this module gives it an explicit module-specific default (false) in variables.tf rather than leaving it null, so it always carries a concrete value in main.tf too.
  • force_update's false default is module-specific, not a verified provider default. The fetched schema documents no default for this argument. Defaulting to false follows this module suite's secure-by-default posture — "the empty call must produce the safe resource" — treating a forced primary-key update as something the caller must explicitly opt into.
  • hash is conservatively marked sensitive at the module boundary, even though the provider's own schema does not mark it Sensitive. It is derived from the system's at-rest-encryption key material, so this module errs toward redaction rather than assuming a one-way hash is safe to surface in plan/apply output or CI logs.
  • No VELOS-vs-rSeries branching. Unlike f5os_partition (VELOS-only) or f5os_partition_change_password (VELOS-only), f5os_primarykey behaves identically on both platform contexts — there is nothing in this module's main.tf that varies by target.
  • No drift detection on the key material. The provider exposes no readable "current passphrase/salt" attribute, so terraform plan cannot detect an out-of-band primary-key change made directly on the platform — a stale value in state/config only surfaces at apply time, if at all.
  • Ordering is operational, not attribute-based. This module has no natural cross-module attribute reference to any sibling — its relationship to the rest of the catalog (e.g., "set the primary key before deploying anything secret-bearing") is expressed via depends_on in the composing root module, never a fabricated output reference. See Example 14.

🧱 Design Principles

Concern Secure default Opt-out (caller must type extra)
Primary-key passphrase/salt No default value ever — always required, explicit, sensitive = true inputs sourced out of band. This is the headline secure-by-default concern for this module, directly extending this module suite's "Remote image transfer credentials" convention to primary-key material N/A — hard rule, not a toggle; the caller must source both from a secret manager or CI-injected sensitive variable on every apply
force_update Defaults to false — a module-specific conservative choice (the provider documents no default) so applying this module never implicitly forces a disruptive primary-key regeneration Caller explicitly sets force_update = true, understanding it forces the operation on the device
hash output Treated as secret-shaped (sensitive = true) even though the provider's schema does not mark it Sensitive — conservative, since it is derived from at-rest-encryption key material N/A — this module does not offer an unredacted variant
passphrase/salt outputs Never emitted at all, even sensitive-marked — neither value should persist in any state-derived output beyond what the provider itself already stores in resource state N/A — hard rule

🚀 Runbook

cd C:\GitHubCode\newf5modules\f5os\terraform-f5os-primarykey
terraform init -backend=false
terraform validate
terraform fmt -check
Remove-Item -Recurse -Force.terraform,.terraform.lock.hcl -ErrorAction SilentlyContinue

Pin every consumer to a specific release: ?ref=v1.0.0.


🧪 Testing

This is a plan-only proof gate — it never touches a real chassis or appliance.

Check Catches Does not catch
terraform validate Missing passphrase/salt, wrong type on any field, malformed HCL A weak/trivial passphrase or salt value; a platform-side passphrase/salt policy rejection; RBAC/permission failures
terraform fmt -check Formatting drift from canonical style Anything semantic
terraform plan (human-run, against real infra) The above gaps — a real F5OS structured error surfaces at plan/apply time —

💬 Example Output

$ terraform output
id = "<provider-assigned, constant per the schema note — exact literal not confirmed in the fetched reference>"
status = "COMPLETE"
hash = <sensitive>

🔍 Troubleshooting

Symptom Cause Fix
apply rejects passphrase/salt despite validate passing The F5OS platform enforces its own passphrase/salt policy (length/complexity) that Terraform's type system cannot check Supply a stronger value; consult the target platform's own documentation for any policy it enforces
Rotation apply appears to succeed but the device still uses the old key force_update left at its default false and the provider treated the change as a no-op Set force_update = true explicitly for a deliberate rotation (see Example 2/4)
passphrase/salt visibly appear in a plan/apply log Set as a plaintext literal instead of a sensitive-sourced variable Source both from TF_VAR_passphrase/TF_VAR_salt, a secret manager, or an HCP Terraform sensitive variable — never a literal in .tf/.tfvars (see Example 3)
Permission denied / RBAC error at apply The authenticated user's role lacks primary-key management privilege on the target chassis partition or appliance Grant at least the admin role scoped to that partition/appliance
init cannot resolve provider version ~> 1.10 no longer matches the current Terraform Registry listing Re-verify the pin against the registry and update providers.tf
terraform import fails or behaves unexpectedly No documented import syntax was found for f5os_primarykey in the fetched provider reference Confirm the current import syntax directly against the provider's live documentation before scripting an import

🔗 Related Docs


💙 "Infrastructure as Code should be standardized, consistent, and secure."

Releases

Packages

Contributors

Languages