terraform-bigip-ltm-persistence-profile-cookiemanages a singlebigip_ltm_persistence_profile_cookieresource against theF5Networks/bigipTerraform provider~> 1.28(TMOS>= v12.1.1).
- Configures a BIG-IP LTM cookie persistence profile (
bigip_ltm_persistence_profile_cookie) — the object a virtual server references to keep a client's requests pinned to the same pool member by inserting, rewriting, or hashing an HTTP cookie. - Exposes the full 1:1 provider argument set (17 scalar arguments) with no house-invented renames —
field names, optionality, and types mirror the live provider schema exactly, including
app_service, an argument present in the live schema but missing from the rendered Terraform Registry Argument Reference page (see "Schema notes that bite" below). - Emits
name(full path) andidfor consumption byterraform-bigip-ltm-virtual-server's persistence-profile input, or by anotherterraform-bigip-ltm-persistence-profile-cookieinstance'sdefaults_from.
💡 Why it matters: Cookie persistence is what lets a stateful application (shopping cart, authenticated session, in-memory session data on one specific app server) survive across multiple requests from the same client without requiring shared session storage on the backend. Because this profile is referenced by full path from every virtual server that uses it, one profile instance is frequently shared across many applications — get the cookie name, expiration, and encryption policy right once, and every consuming virtual server inherits them consistently.
If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:
- ⭐ Star this repository to help others discover this Terraform module.
- 🤝 Connect with me on LinkedIn: linkedin.com/in/microsoftexpert
- ☕ Buy me a coffee: buymeacoffee.com/microsoftexpert
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!
graph LR
COOKIE["terraform-bigip-ltm-persistence-profile-cookie"]:::this
VS["terraform-bigip-ltm-virtual-server"]:::keystone
SRCADDR["terraform-bigip-ltm-persistence-profile-srcaddr"]:::sibling
DSTADDR["terraform-bigip-ltm-persistence-profile-dstaddr"]:::sibling
SSLP["terraform-bigip-ltm-persistence-profile-ssl"]:::sibling
HTTP["terraform-bigip-ltm-profile-http"]:::sibling
CSSL["terraform-bigip-ltm-profile-client-ssl"]:::sibling
MON["terraform-bigip-ltm-monitor"]:::sibling
POOL["terraform-bigip-ltm-pool"]:::sibling
COMMON["/Common/cookie built-in profile"]:::external
COOKIE -->|"persistence-profile full-path reference"| VS
SRCADDR -->|"persistence-profile full-path reference"| VS
DSTADDR -->|"persistence-profile full-path reference"| VS
SSLP -->|"persistence-profile full-path reference"| VS
HTTP -->|"profile_names full-path reference"| VS
CSSL -->|"profile_names full-path reference"| VS
MON -->|"monitors full-path reference"| POOL
POOL -->|"pool full-path reference"| VS
COMMON -->|"defaults_from optional inheritance"| COOKIE
classDef this fill:#E4002B,color:#ffffff,stroke:#333333;
classDef keystone fill:#000000,color:#ffffff,stroke:#333333;
classDef sibling fill:#D9D9D9,color:#000000,stroke:#333333;
classDef external fill:#EFEFEF,color:#000000,stroke:#333333,stroke-dasharray: 3 3;
This module (terraform-bigip-ltm-persistence-profile-cookie, red) sits alongside the rest of the LTM
Persistence Profiles family (_srcaddr, _dstaddr, _ssl) as a sibling input consumed by
full-path name into terraform-bigip-ltm-virtual-server (black), the same way an HTTP or
client-SSL profile is consumed. defaults_from optionally points at either BIG-IP's built-in
/Common/cookie profile or another instance of this same module.
graph TD
subgraph Inputs["Inputs"]
NAME["var.name required"]
DEFAULTS["var.defaults_from required"]
CORE["core cookie and match settings 12 scalar vars"]
SECRET["var.cookie_encryption_passphrase sensitive"]
APPSVC["var.app_service optional"]
end
RES["bigip_ltm_persistence_profile_cookie.this"]:::keystone
NAME --> RES
DEFAULTS --> RES
CORE --> RES
SECRET -->|"lifecycle ignore_changes"| RES
APPSVC --> RES
RES --> OUT_NAME["output: name"]
RES --> OUT_ID["output: id"]
classDef keystone fill:#000000,color:#ffffff,stroke:#333333;
Resource inventory
| Resource / block | Count | Notes |
|---|---|---|
bigip_ltm_persistence_profile_cookie.this |
1 (keystone) | The cookie persistence profile itself — the module's only Terraform resource. |
lifecycle.ignore_changes |
1 static block | Pinned to [cookie_encryption_passphrase] — suppresses the perpetual diff BIG-IP's server-side re-encryption of this field would otherwise produce on every plan. |
No for_each-keyed child collections and no dynamic blocks exist: every argument on
bigip_ltm_persistence_profile_cookie is a flat scalar in the live provider schema, so main.tf is
a single resource block, not a composite renderer.
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
| Provider | F5Networks/bigip ~> 1.28 — re-verify this pin against the current Terraform Registry listing before each new module wave |
| Provider block | None — the caller's root module configures address/username/password/token_value |
| BIG-IP / TMOS floor | >= v12.1.1 (provider floor; no AWAF/ASM version gate applies to this resource family) |
Schema notes that bite
nameis the full path (/Partition/name) and is the effective primary key — renaming it or moving it between partitions is a destroy/recreate operation, not an in-place update.app_serviceis present in the live provider schema but absent from the rendered Terraform Registry Argument Reference page for this resource — added here from the schema fallback, described consistently with the same attribute onterraform-bigip-ltm-profile-httpandterraform-bigip-net-ike-peer.- The rendered doc's
namedescription ("Name of the virtual address") is a copy/paste artifact from an unrelated resource's doc page — the live schema's own description ("Name of the persistence profile") is used in this module instead. - The rendered doc's
timeoutentry is prefixed "(enabled or disabled)" even though the field is a numeric second count (the doc's own Example Usage setstimeout = 3600, and the live schema types itnumber) — that parenthetical is a copy/paste artifact from the surrounding enabled/disabled fields; this module typestimeoutasnumber. cookie_encryption_passphraseis re-encrypted server-side and always returns a different value than what was set —main.tfcarries a staticlifecycle { ignore_changes = [cookie_encryption_passphrase] }to suppress the resulting perpetual diff, matching the provider's own documented Example Usage for this resource.method's accepted values are not a verifiable closed set — the provider documents a default of"insert"but never enumerates a complete allow-list in either the rendered doc or the live schema, so this module deliberately does not enforce avalidation{}block against it.- Every other optional field (
match_across_pools,match_across_services,match_across_virtuals,mirror,override_conn_limit,timeout,always_send,cookie_name,expiration,hash_length,hash_offset) is Optional+Computed with no literal provider-side default documented anywhere — leftnullin this module so thedefaults_fromparent profile's own value applies, rather than this module inventing a value the provider itself does not commit to.
Manager role scoped to the target partition is sufficient; Administrator is not required for this application-layer LTM object.
- iControl REST enabled and reachable on the target device.
- TMOS
>= v12.1.1(provider floor). - Target partition must already exist — this module never creates a partition.
- The parent cookie persistence profile named in
defaults_from(e.g./Common/cookie) must already exist on the device before this module applies.
terraform-bigip-ltm-persistence-profile-cookie/
├── providers.tf # Terraform + F5Networks/bigip ~> 1.28 requirement — no provider {} block
├── variables.tf # 1:1-mapped bigip_ltm_persistence_profile_cookie input schema
├── main.tf # bigip_ltm_persistence_profile_cookie.this + lifecycle.ignore_changes
├── outputs.tf # name (first), id
├── SCOPE.md # cross-module contract (this module's consumes/emits + role/prereqs)
└── README.md # this file
# Root module — caller configures the provider; never inside this module.
provider "bigip" {
address = var.bigip_address
username = var.bigip_username
password = var.bigip_password
}
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/my-cookie-persistence"
defaults_from = "/Common/cookie"
}name and defaults_from are the only two required inputs — every other field defers to the
defaults_from parent profile's own value when left unset.
Consumes
| Input | Type | Source module |
|---|---|---|
defaults_from |
string (full path) |
Another terraform-bigip-ltm-persistence-profile-cookie instance, or BIG-IP's built-in /Common/cookie |
cookie_encryption_passphrase (optional, sensitive) |
string |
Out-of-band secret store (Terraform Cloud/Vault-sourced variable) — never a sibling module output |
Emits
| Output | Description | Consumed by |
|---|---|---|
name |
Full-path name (/Partition/name) of the cookie persistence profile — the practical cross-reference key |
terraform-bigip-ltm-virtual-server's persistence-profile input |
id |
Provider-internal id — identical value to name for this resource (no separate numeric id) |
Rarely consumed directly; diagnostics only |
1 · Minimal profile inheriting from the built-in parent
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app01-cookie-persistence"
defaults_from = "/Common/cookie"
}ℹ️ Every field besides
name/defaults_fromis leftnull(the module default), so the/Common/cookieparent profile's own values apply.
2 · Named cookie with an explicit expiration
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app01-session-cookie"
defaults_from = "/Common/cookie"
cookie_name = "APP01SESSIONID"
expiration = "1:0:0:0"
}💡
expirationuses BIG-IP'sDAY:HOUR:MIN:SECONDSformat —"1:0:0:0"is one day.
3 · Explicit insert-mode cookie processing
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app02-cookie-persistence"
defaults_from = "/Common/cookie"
method = "insert"
}ℹ️
methodhas novalidation{}allow-list in this module — the provider's own documentation does not enumerate a complete, verifiable accepted-value set. Pass the literal value your BIG-IP version expects.
4 · Encrypted cookie with an out-of-band passphrase
variable "cookie_persistence_passphrase" {
type = string
sensitive = true
}
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app03-encrypted-cookie-persistence"
defaults_from = "/Common/cookie"
cookie_encryption = "required"
cookie_encryption_passphrase = var.cookie_persistence_passphrase
}🔒
cookie_encryption_passphrasemust come from an out-of-band secret store (Terraform Cloud workspace variable, Vault-sourced input) — never a literal in version control. Expect the plan to otherwise show a perpetual diff on this field;main.tf'slifecycle.ignore_changessuppresses it.
5 · Preferred (not mandatory) cookie encryption
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app04-cookie-persistence"
defaults_from = "/Common/cookie"
cookie_encryption = "preferred"
}6 · Matching persistence across every pool behind a virtual server
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/multi-pool-cookie-persistence"
defaults_from = "/Common/cookie"
match_across_pools = "enabled"
}
⚠️ Enablingmatch_across_poolschanges failover behavior for persisted clients — confirm the application team expects a client's session to follow it across pools before enabling.
7 · Mirroring persistence records to the HA peer
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/ha-mirrored-cookie-persistence"
defaults_from = "/Common/cookie"
mirror = "enabled"
}8 · Overriding pool member connection limits for persisted clients
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/burst-tolerant-cookie-persistence"
defaults_from = "/Common/cookie"
override_conn_limit = "enabled"
}
⚠️ Enablingoverride_conn_limitallows a persisted client to exceed a pool member's configuredconnection_limit— treat as a deliberate capacity decision, not a default to enable casually (this module suite's "Persistence / connection limits" secure-default guidance).
9 · Custom timeout and always-send cookie behavior
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app05-cookie-persistence"
defaults_from = "/Common/cookie"
timeout = 3600
always_send = "enabled"
}ℹ️
timeoutis typednumberin this module (seconds) — the rendered Terraform Registry doc page mislabels this field as "(enabled or disabled)"; see "Schema notes that bite" above.
10 · Hashing the cookie value
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/hashed-cookie-persistence"
defaults_from = "/Common/cookie"
hash_length = 8
hash_offset = 0
}11 · HttpOnly cookie to block client-side script access
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/httponly-cookie-persistence"
defaults_from = "/Common/cookie"
httponly = "enabled"
}12 · Matching persistence across services and virtuals sharing a destination
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/shared-destination-cookie-persistence"
defaults_from = "/Common/cookie"
match_across_services = "enabled"
match_across_virtuals = "enabled"
}13 · iApp-managed profile via app_service
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/iapp-managed-cookie-persistence"
defaults_from = "/Common/cookie"
app_service = "/Common/my-iapp.app/my-iapp"
}ℹ️
app_serviceis present in the live provider schema but omitted from the rendered Terraform Registry Argument Reference for this resource — see "Schema notes that bite" above.
14 · Partition-scoped profile for a dedicated tenant
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Tenant-A/tenant-a-cookie-persistence"
defaults_from = "/Common/cookie"
}ℹ️ Partition is encoded in
name's full path (/Tenant-A/...) — house convention, not a provider requirement. The target partition (/Tenant-A) must already exist before this module runs.
15 · 🏗️ End-to-end composition — cookie persistence + HTTP profile + pool + virtual server
module "http_monitor" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-monitor.git?ref=v1.0.0"
name = "/Common/app01-http-monitor"
#... monitor-specific arguments
}
module "http_profile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-profile-http.git?ref=v1.0.0"
name = "/Common/app01-http"
}
module "cookie_persistence" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"
name = "/Common/app01-cookie-persistence"
defaults_from = "/Common/cookie"
cookie_name = "APP01SESSIONID"
expiration = "1:0:0:0"
}
module "app01_pool" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-pool.git?ref=v1.0.0"
name = "/Common/app01-pool"
monitors = [module.http_monitor.name]
members = {
"10.10.1.11:8080" = { address = "10.10.1.11", port = 8080 }
"10.10.1.12:8080" = { address = "10.10.1.12", port = 8080 }
}
}
module "app01_virtual_server" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-virtual-server.git?ref=v1.0.0"
name = "/Common/app01-vs"
destination = "10.20.30.40"
port = 443
pool = module.app01_pool.name
profile_names = [module.http_profile.name]
persistence_profile = module.cookie_persistence.name
}💡 Record ordering matters here purely through Terraform's own dependency graph: the monitor is referenced by name into the pool, and the pool, HTTP profile, and cookie persistence profile are all referenced by name into the virtual server — Terraform resolves the apply order automatically because each reference is a real
module.<x>.nameexpression, not a hardcoded string repeated across modules.
Grouped summary
| Name | Type | Default | Required |
|---|---|---|---|
name |
string |
— | yes |
defaults_from |
string |
— | yes |
match_across_pools |
string (enum) |
null (provider-computed) |
no |
match_across_services |
string (enum) |
null (provider-computed) |
no |
match_across_virtuals |
string (enum) |
null (provider-computed) |
no |
mirror |
string (enum) |
null (provider-computed) |
no |
override_conn_limit |
string (enum) |
null (provider-computed) |
no |
timeout |
number |
null (provider-computed) |
no |
always_send |
string (enum) |
null (provider-computed) |
no |
method |
string |
null (provider-computed; documented default "insert") |
no |
cookie_name |
string |
null (provider-computed) |
no |
cookie_encryption |
string (enum) |
null (provider-computed) |
no |
cookie_encryption_passphrase |
string, sensitive |
null |
no |
expiration |
string |
null (provider-computed) |
no |
hash_length |
number |
null (provider-computed) |
no |
hash_offset |
number |
null (provider-computed) |
no |
httponly |
string (enum) |
null (provider-computed) |
no |
app_service |
string |
null |
no |
Full variable declarations (closed-enum validation{} blocks)
variable "match_across_pools" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.match_across_pools)
}
variable "match_across_services" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.match_across_services)
}
variable "match_across_virtuals" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.match_across_virtuals)
}
variable "mirror" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.mirror)
}
variable "override_conn_limit" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.override_conn_limit)
}
variable "always_send" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.always_send)
}
variable "cookie_encryption" {
type = string
default = null
# validation: contains(["required", "preferred", "disabled"], var.cookie_encryption)
}
variable "httponly" {
type = string
default = null
# validation: contains(["enabled", "disabled"], var.httponly)
}method intentionally carries no validation{} block — the provider documents a default of
"insert" but never enumerates a complete, verifiable closed set of accepted values. All other
scalar fields (timeout, cookie_name, cookie_encryption_passphrase [sensitive], expiration,
hash_length, hash_offset, app_service) are plain typed string/number variables with no
enum constraint.
| Output | Description | Sensitive |
|---|---|---|
name |
Full-path name of the cookie persistence profile, e.g. /Common/my-cookie-persistence. Consumed by full-path name from terraform-bigip-ltm-virtual-server. |
no |
id |
Provider-internal id of the cookie persistence profile — the same full-path value as name (no separate numeric identifier). |
no |
No output is sensitive = true — the only sensitive input, cookie_encryption_passphrase, is
never echoed back through an output.
- Flat keystone, no children, no
dynamicblocks. Every argument onbigip_ltm_persistence_profile_cookieis a flat scalar in the live provider schema —main.tfis a single resource block plus one staticlifecycleblock, with nofor_eachand nodynamic {}rendering. lifecycle.ignore_changesoncookie_encryption_passphraseis load-bearing. Because BIG-IP re-encrypts this value server-side and always returns something different than what was set, omitting theignore_changesentry would produce a perpetual diff on everyterraform planeven when the caller-supplied passphrase hasn't changed.methodhas no closed-set enforcement by design, not by omission. Unlikecookie_encryption,httponly, or the fourmatch_across_*/mirror/override_conn_limitfields — all of which document a genuinely complete enum —method's only documented value is its default ("insert"), with no enumerated alternative set. Adding avalidation{}allow-list here would risk rejecting a legitimate device-accepted value this module's authoring pass didn't discover.- Full-path identity drives ordering. This module's
nameoutput is consumed byterraform-bigip-ltm-virtual-server's persistence-profile input and by any otherterraform-bigip-ltm-persistence-profile-cookieinstance'sdefaults_from— Terraform's own dependency graph (viamodule.<this>.namereferences) enforces that this profile is created before anything that references it, with no explicitdepends_onneeded. - No
for_eachkey-stability concern here. Because there are no child collections, the key-stability rules that matter for composite modules (e.g. keying pool members byip:port) do not apply to this module.
| Concern | Secure default in this module | Opt-out (caller must type extra) |
|---|---|---|
| Persistence / connection limits | override_conn_limit defaults to null (provider-computed, i.e. inherits from defaults_from) rather than this module inventing an "enabled" default that would let persisted clients exceed a pool member's connection_limit |
Caller explicitly sets override_conn_limit = "enabled" to accept that risk |
| Secrets | cookie_encryption_passphrase is sensitive = true and carries no literal default — it must be sourced from an out-of-band secret store, never hardcoded in a .tfvars file |
N/A — this is a hard rule, not a toggle |
| Partition scope | No implicit partition default is invented; the module never defaults or infers a partition — partition is whatever the caller encodes in name's full path |
Caller sets a non-/Common full path in name explicitly for any tenant-scoped object |
| Cookie encryption policy | cookie_encryption defaults to null (provider-computed, deferring to defaults_from) rather than this module silently forcing "required" or "disabled" |
Caller explicitly sets cookie_encryption = "required" or "preferred" to opt into encryption |
Concerns from this module suite's house-wide secure-by-default table that do not apply to this resource
(TLS certificate validation, virtual-server destination, AS3/DO declarations, monitor/health-check
requirements) are omitted above — bigip_ltm_persistence_profile_cookie exposes none of those
arguments.
cd C:\GitHubCode\newf5modules\bigip\terraform-bigip-ltm-persistence-profile-cookie
terraform init -backend=false
terraform validate
terraform fmt -checkPin consumption at ?ref=v1.0.0 in every caller until a new tagged release is validated:
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-persistence-profile-cookie.git?ref=v1.0.0"Offline proof gate (what this repo's CI can verify without a live BIG-IP):
terraform init -backend=false— resolves theF5Networks/bigip ~> 1.28provider requirement.terraform validate— confirms the eight closed-enumvalidation{}blocks (match_across_pools,match_across_services,match_across_virtuals,mirror,override_conn_limit,always_send,cookie_encryption,httponly) compile and reject out-of-set literals at plan time.terraform fmt -check— confirms canonical formatting.
What only terraform plan/apply against a real device exercises:
- Whether the target partition in
name's full path actually exists on the device. - Whether
defaults_fromresolves to a parent profile that already exists on the device. - The device's own computed defaults for every field left
nullin this module (e.g.timeout,cookie_name,expiration) — these are provider/device behavior, not somethingvalidatecan confirm offline. - The
cookie_encryption_passphraseserver-side re-encryption behavior thatlifecycle.ignore_changessuppresses. - Whether an unvalidated
methodliteral (e.g. a typo) is actually accepted by the target BIG-IP version — this module does not enforce an allow-list onmethod.
$ terraform apply
Terraform will perform the following actions:
# module.cookie_persistence.bigip_ltm_persistence_profile_cookie.this will be created
+ resource "bigip_ltm_persistence_profile_cookie" "this" {
+ name = "/Common/app01-cookie-persistence"
+ defaults_from = "/Common/cookie"
+ cookie_name = "APP01SESSIONID"
+ expiration = "1:0:0:0"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
id = "/Common/app01-cookie-persistence"
name = "/Common/app01-cookie-persistence"
| Symptom | Cause | Fix |
|---|---|---|
terraform plan shows cookie_encryption_passphrase changing on every run despite no source change |
Known provider write-only/re-encryption field idempotency quirk | Expected behavior; lifecycle.ignore_changes in main.tf already suppresses this — confirm the actual device-side value out of band rather than trusting the plan diff |
| Apply fails with a partition-not-found style error | Target partition in name's full path (e.g. /Tenant-A/...) does not exist yet |
Create the partition first (via terraform-bigip-partition or an out-of-band step) — this module never creates one |
Apply fails because defaults_from cannot be resolved |
The parent cookie persistence profile named in defaults_from (e.g. /Common/cookie) does not exist on the device |
Confirm the parent profile exists, or reference another terraform-bigip-ltm-persistence-profile-cookie instance's name output instead of a raw string |
terraform validate fails on match_across_pools, mirror, cookie_encryption, httponly, or similar |
Value outside this module's closed-enum validation{} list |
Use one of the documented enabled/disabled (or cookie_encryption's required/preferred/disabled) values |
BIG-IP rejects the applied method value at apply time even though terraform validate passed |
This module does not enforce a closed set on method — the provider itself has no complete documented enum |
Re-check clouddocs.f5.com or the device's own accepted values for the target TMOS version; correct the literal and re-apply |
connection refused on port 443 during terraform apply |
Target is a single-NIC BIG-IP in a public cloud (AWS/Azure/GCP) reachable only on a non-443 management port | Set port (or BIGIP_PORT) on the provider block in the root module — not a concern of this module |
Virtual server doesn't pick up a persistence-behavior change after terraform apply here |
The consuming terraform-bigip-ltm-virtual-server call was not re-applied, or references a different full-path name |
Confirm the virtual server's persistence-profile input contains this module's exact name output and re-apply that module |
F5Networks/bigipprovider registry docs —bigip_ltm_persistence_profile_cookieresource (registry.terraform.io).- clouddocs.f5.com — LTM cookie persistence profile concepts (insert/rewrite/hash modes, encryption policy).
- This module's
SCOPE.md— cross-module contract, required role, and prerequisites. - Sibling:
terraform-bigip-ltm-virtual-server— consumes this module'snameoutput via its persistence-profile input. - Sibling family:
terraform-bigip-ltm-persistence-profile-srcaddr,terraform-bigip-ltm-persistence-profile-dstaddr,terraform-bigip-ltm-persistence-profile-ssl.