terraform-bigip-ltm-ifilemanages a singlebigip_ltm_ifileobject -- an LTM-namespace reference that binds a pre-uploaded system iFile into the LTM configuration -- on a BIG-IP TMOS >= v12.1.1 device, via theF5Networks/bigipTerraform provider~> 1.28.
- 🔗 Creates one
bigip_ltm_ifile-- the LTM-level record that makes a pre-uploaded system iFile addressable from iRules and local traffic policies. - 📄 Owns no file content itself -- the referenced system iFile (
var.file_name) must already exist, created by the siblingterraform-bigip-sys-ifilemodule or out of band. - 🏷️ Emits a
nameoutput holding the full-path identity (/Partition/name) as the practical primary cross-reference key -- sourced from the provider's computedfull_pathattribute, since (unlike most resources in this catalog) the live schema keeps the resource's ownnameargument as a bare leaf identifier, separate frompartition. - 🧵 Renders all four provider arguments (
name,file_name,partition,sub_path) directly -- the simplest possible thin renderer in the catalog, with no nested blocks and nodynamic. - 🔓
partitiondefaults to"Common"only because that is the underlying resource's own provider default, not an invented one;sub_pathdefaults tonull(no sub-path segment).
💡 Why it matters: BIG-IP iFiles are frequently used to back custom error pages, iRule-driven content templates, and policy-driven response bodies -- content that must be versioned and promoted consistently across environments. Splitting the system-level file upload (
terraform-bigip-sys-ifile) from the LTM-level reference (this module) keeps the file's own lifecycle independent from how many LTM objects reference it, and lets Terraform's implicit dependency graph enforce that the file exists before anything tries to bind it.
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!
flowchart LR
SYSIFILE["terraform-bigip-sys-ifile (sibling, upstream)"]:::sibling
IFILE["terraform-bigip-ltm-ifile (this module)"]:::this
IRULE["terraform-bigip-ltm-irule (sibling)"]:::sibling
POLICY["terraform-bigip-ltm-policy (sibling)"]:::sibling
VS["terraform-bigip-ltm-virtual-server (keystone)"]:::keystone
SYSIFILE -->|"name (full-path sys iFile)"| IFILE
IFILE -->|"name (full-path, referenced by TCL ifile command)"| IRULE
IFILE -.->|"name (full-path, referenced by policy action, optional)"| POLICY
IRULE -->|"irules list (full-path name)"| VS
POLICY -.->|"policy attachment (full-path name)"| VS
classDef this fill:#E4002B,color:#ffffff,stroke:#333333,stroke-width:1px;
classDef keystone fill:#000000,color:#ffffff,stroke:#333333,stroke-width:1px;
classDef sibling fill:#e8e8e8,color:#000000,stroke:#999999,stroke-width:1px;
This module sits between terraform-bigip-sys-ifile (the system-level file upload it consumes by
name) and the LTM objects that actually invoke the iFile at runtime -- terraform-bigip-ltm-irule
(via the TCL ifile command) and, less commonly, terraform-bigip-ltm-policy (via a policy action).
Those, in turn, feed terraform-bigip-ltm-virtual-server, the family's ultimate keystone consumer.
This module owns none of that downstream wiring -- it owns exactly the LTM iFile reference record.
flowchart LR
INNAME["var.name"]:::input
INFILE["var.file_name"]:::input
INPART["var.partition"]:::input
INSUB["var.sub_path"]:::input
RES["bigip_ltm_ifile.this"]:::resource
OUTNAME["output: name"]:::output
OUTID["output: id"]:::output
OUTFP["output: full_path"]:::output
INNAME --> RES
INFILE --> RES
INPART --> RES
INSUB --> RES
RES --> OUTNAME
RES --> OUTID
RES --> OUTFP
classDef input fill:#e8e8e8,color:#000000,stroke:#999999,stroke-width:1px;
classDef resource fill:#E4002B,color:#ffffff,stroke:#333333,stroke-width:1px;
classDef output fill:#000000,color:#ffffff,stroke:#333333,stroke-width:1px;
Resource inventory
| Resource | Count | Notes |
|---|---|---|
bigip_ltm_ifile.this |
1 | Sole keystone; no for_each children -- bigip_ltm_ifile has no companion child object in the live schema |
| Item | Value |
|---|---|
| Terraform | >= 1.12.0 |
| Provider | F5Networks/bigip ~> 1.28 |
| Provider block | None -- the caller's root module configures address/username/password (or token_value) |
| TMOS floor | >= v12.1.1 |
Schema notes that bite
name,partition, andsub_pathare all part of the object's full-path identity -- changing any one of them forces destroy/recreate, not an in-place update. There is no in-place rename or "move between partitions" operation for an LTM iFile.file_namemust already exist as a system iFile at that exact full path (e.g./Common/my-sys-ifile) before this resource applies -- the provider raises a generic iControl REST error if it does not; this module performs no Terraform-level existence pre-check.partitiondefaults to"Common"because that isbigip_ltm_ifile's own provider default -- per this module suite's partition-scope rule, this is not an invented default.sub_pathdefaults tonull, placing the object directly underpartitionwith no hierarchical sub-path segment unless the caller opts in.- The resource's own
nameargument is a bare leaf identifier (e.g.app-error-template), not a full path -- unlike most resources in this catalog. This module'snameoutput is deliberately sourced from the provider-computedfull_pathattribute (partition + sub_path + name) rather than echoing the bare argument, so it still serves as the practical full-path cross-reference key sibling modules should consume, consistent with the rest of the catalog. - The live schema documents no description for the resource's
idattribute, so whether it echoes the barenameor the full path is unconfirmed -- consume this module'snameoutput (notid) for cross-references.
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.
- The system iFile named in
file_namemust already exist on the device (created out of band or viaterraform-bigip-sys-ifile) before this module applies --bigip_ltm_ifilereferences it by full path and does not create or upload file content itself.
| File | Role |
|---|---|
providers.tf |
required_version >= 1.12.0, pinned F5Networks/bigip ~> 1.28 -- no provider {} block |
variables.tf |
name, file_name, partition, sub_path -- 1:1 mapped to the real bigip_ltm_ifile argument list |
main.tf |
Single keystone resource bigip_ltm_ifile.this -- thin, total renderer, no nested blocks |
outputs.tf |
name, id, full_path |
SCOPE.md |
Lightweight standalone scope: consumed-by-name relationships, required role, F5 prerequisites |
README.md |
This document |
# Caller's root module configures the provider once -- never inside this module.
# provider "bigip" {
# address = var.bigip_address
# username = var.bigip_username
# password = var.bigip_password
# }
module "app_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "app-error-template" # bare leaf name -- partition defaults to "Common"
file_name = module.app_error_sys_ifile.name # from terraform-bigip-sys-ifile
}Consumes
| Input | Type | Source module |
|---|---|---|
file_name |
string (full-path name, e.g. /Common/my-sys-ifile) |
terraform-bigip-sys-ifile |
Emits
| Output | Description | Consumed by |
|---|---|---|
name |
Full-path (partition + name) LTM iFile identity, e.g. /Common/ltm-app-config |
terraform-bigip-ltm-irule, terraform-bigip-ltm-policy |
id |
Provider-internal id -- not confirmed to equal the full path (the live schema documents no description for this attribute) | (rarely consumed directly; prefer name) |
full_path |
Complete full path computed by the provider (partition + sub_path + name) | (diagnostics / reporting only) |
1 · Minimal LTM iFile referencing an existing system iFile
The smallest real call -- only the two required arguments.
module "app_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "app-error-template" # bare leaf name, no leading /Partition/
file_name = "/Common/app-error-template-src"
}ℹ️
partition("Common") andsub_path(null) both fall back to the provider's own defaults -- nothing here is invented by this module.nameis deliberately bare here: unlike most resources in this catalog,bigip_ltm_ifile's live schema keepsnameandpartitionas two separate arguments, so this module'snameoutput (not thenameinput) is what carries the combined full-path identity.
2 · Consuming file_name from terraform-bigip-sys-ifile by name
module "app_error_sys_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-sys-ifile.git?ref=v1.0.0"
#... sys iFile source-path arguments
}
module "app_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "app-error-template"
file_name = module.app_error_sys_ifile.name
}💡 Sourcing
file_namefrom the sibling module'snameoutput (rather than a hand-maintained literal) lets Terraform's implicit dependency graph order the system iFile's creation ahead of this LTM iFile, per this module suite's record-ordering rule.
3 · Explicit /Common partition (same as the default, shown for clarity)
module "app_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "app-error-template"
file_name = "/Common/app-error-template-src"
partition = "Common"
}4 · Non-/Common partition
module "tenant_a_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "tenant-a-error-template"
file_name = "/Tenant-A/tenant-a-error-template-src"
partition = "Tenant-A"
}🔒 Per this module suite's partition-scope model,
partitionis a genuine per-resource input here (this object is partition-scoped) -- the caller must set it explicitly for any non-/Commonobject rather than relying on an invented default.
5 · Organizing iFiles under a sub_path
module "templates_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "ltm-error-template"
file_name = "/Common/ltm-error-template-src"
partition = "Common"
sub_path = "templates"
}ℹ️ With
sub_pathset, the object's full path becomes/Common/templates/ltm-error-templaterather than sitting directly under/Common.
6 · Partition and sub_path combined for a non-/Common tenant
module "tenant_b_templates_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "tenant-b-welcome-page"
file_name = "/Tenant-B/tenant-b-welcome-page-src"
partition = "Tenant-B"
sub_path = "templates"
}7 · Consuming file_name from terraform-bigip-sys-ifile's id output
module "maintenance_page_sys_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-sys-ifile.git?ref=v1.0.0"
#... sys iFile source-path arguments
}
module "maintenance_page_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "maintenance-page"
file_name = module.maintenance_page_sys_ifile.id
}
⚠️ Prefermodule.maintenance_page_sys_ifile.nameover.idforfile_nameunless you have independently confirmed that sibling module'sidoutput carries the full path -- this module's ownidoutput, for instance, is not confirmed to matchname/full_path(see Schema notes above).nameis the practical, catalog-wide cross-reference key per this module suite's design-decisions log.
8 · iFile backing a custom HTTP error response, consumed by an iRule
module "http_503_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "http-503-response-body"
file_name = "/Common/http-503-response-body-src"
}
module "maintenance_irule" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-irule.git?ref=v1.0.0"
name = "/Common/maintenance-503-irule"
irule = file("${path.module}/irules/maintenance-503.tcl")
# the TCL body invokes `ifile get "${module.http_503_ifile.name}"` at runtime
}💡 This module owns only the LTM iFile record; the iRule's TCL body (owned by
terraform-bigip-ltm-irule) is what actually invokes it by full-path name at runtime.
9 · iFile referenced from a local traffic policy action
module "policy_response_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "policy-custom-response"
file_name = "/Common/policy-custom-response-src"
}
module "custom_response_policy" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-policy.git?ref=v1.0.0"
#... policy rule action referencing module.policy_response_ifile.name by full path
}10 · One iFile fanned out to two iRules
module "shared_banner_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "shared-banner"
file_name = "/Common/shared-banner-src"
}
module "app1_banner_irule" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-irule.git?ref=v1.0.0"
name = "/Common/app1-banner-irule"
irule = file("${path.module}/irules/app1-banner.tcl")
}
module "app2_banner_irule" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-irule.git?ref=v1.0.0"
name = "/Common/app2-banner-irule"
irule = file("${path.module}/irules/app2-banner.tcl")
}💡 A single iFile record can be referenced by any number of iRules or policies -- this module does not tie the iFile's lifecycle to any one consumer, matching this module suite's shared-object reasoning for monitors and other frequently-reused sibling records.
11 · Multiple iFiles via root-level for_each
This module models exactly one LTM iFile per call (there is no in-module child collection to
for_each over), so a caller creating several wraps the module invocation itself at the root,
keyed on a stable identifier -- never count.
locals {
error_templates = {
"404" = { file_name = "/Common/error-404-src" }
"500" = { file_name = "/Common/error-500-src" }
"503" = { file_name = "/Common/error-503-src" }
}
}
module "error_ifiles" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
for_each = local.error_templates
name = "error-${each.key}-template"
file_name = each.value.file_name
}💡 Keying on
each.key(the stable error-code label) rather than a list index means removing the"404"entry never forces Terraform to touch the"500"/"503"entries' state.
12 · Renaming/repointing an LTM iFile (destroy/recreate awareness)
module "app_error_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "app-error-template-v2" # was "app-error-template"
file_name = "/Common/app-error-template-src"
}
⚠️ Changingname(orpartition/sub_path) is a destroy/recreate, not an in-place rename -- full-path identity is the object's real key. Update any iRule/policy still referencing the old full path in the same change, or they will fail to apply against the now-missing object.
13 · Minimal-footprint iFile for a small VE/lab deployment
module "lab_banner_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "lab-banner"
file_name = "/Common/lab-banner-src"
}ℹ️ No tuning knobs exist beyond identity and the file reference --
bigip_ltm_ifilehas no size/performance-related arguments of its own.
14 · 🏗️ End-to-end composition
The full chain this module participates in: a system iFile upload, this module's LTM-namespace reference, an iRule that invokes it, and the virtual server that ultimately serves the traffic.
module "maintenance_sys_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-sys-ifile.git?ref=v1.0.0"
#... sys iFile source-path arguments (uploaded maintenance-page content)
}
module "maintenance_ifile" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"
name = "maintenance-page"
file_name = module.maintenance_sys_ifile.name
}
module "maintenance_irule" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-irule.git?ref=v1.0.0"
name = "/Common/maintenance-irule"
irule = file("${path.module}/irules/maintenance.tcl")
# TCL body invokes `ifile get "${module.maintenance_ifile.name}"` when maintenance mode is active
}
module "app_pool" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-pool.git?ref=v1.0.0"
#... pool + members, monitors consumed by name from terraform-bigip-ltm-monitor
}
module "app_virtual_server" {
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-virtual-server.git?ref=v1.0.0"
name = "/Common/app-vs"
destination = "10.20.30.100:443" # caller supplies an explicit destination, never 0.0.0.0/0
pool_name = module.app_pool.name
irules = [module.maintenance_irule.name]
}🏗️ This is the mandatory end-to-end shape: system iFile → LTM iFile → iRule → virtual server, wired entirely by full-path
nameoutputs, matching this module suite's ordering rule (the file exists before the LTM reference, the reference exists before the iRule invoking it, and the iRule exists before the virtual server that attaches it).
Summary
| Variable | Type | Default | Required |
|---|---|---|---|
name |
string |
-- | ✅ |
file_name |
string |
-- | ✅ |
partition |
string |
"Common" |
-- |
sub_path |
string |
null |
-- |
Full variable definitions
variable "name" {
type = string
}
variable "file_name" {
type = string
}
variable "partition" {
type = string
default = "Common"
}
variable "sub_path" {
type = string
default = null
}| Field | Type | Default | Notes |
|---|---|---|---|
name |
string |
-- (required) | Bare leaf name of the LTM iFile, e.g. ltm-app-config -- do NOT prefix with /Partition/. Combined with partition (and sub_path, if set) by the provider to form the object's full-path identity; this module's name output (not this input) emits that combined form, e.g. /Common/ltm-app-config. Immutable -- changing it forces recreation. |
file_name |
string |
-- (required) | Full-path name of the pre-existing BIG-IP system iFile this LTM iFile references, e.g. /Common/my-sys-ifile. Must already exist -- source it from terraform-bigip-sys-ifile's name/id output. |
partition |
string |
"Common" |
Partition where the LTM iFile is created -- matches the underlying resource's own provider default. Immutable -- changing it forces recreation. |
sub_path |
string |
null |
Optional subdirectory within partition for hierarchical organization, e.g. "templates". null places the object directly under partition. Immutable -- changing it forces recreation. |
| Output | Description | Sensitive |
|---|---|---|
name |
Full-path name of the LTM iFile, e.g. /Common/ltm-app-config -- primary cross-reference key |
No |
id |
Provider-internal id of the LTM iFile -- not confirmed to equal the full path (live schema has no description for this attribute); prefer name for cross-references |
No |
full_path |
Complete full path of the LTM iFile as computed by the provider (partition + sub_path + name) | No |
- Total renderer, no nested blocks. All four arguments (
name,file_name,partition,sub_path) map directly ontobigip_ltm_ifile.thiswith nodynamicblocks, notry, and nofor_eachinside the module -- the simplest thin-renderer shape in the catalog, sincebigip_ltm_ifile's live schema exposes no nested or repeating structure. - No owned children. Unlike
terraform-bigip-ltm-node(a single-itemfqdndynamic block) orterraform-bigip-ltm-policy(afor_each-keyedrulecollection), this resource has nothing to model beyond its own flat argument set. - File content is out of scope. This module never creates, uploads, or owns iFile bytes --
that is
terraform-bigip-sys-ifile's responsibility. This module only creates the LTM-namespace pointer to a file that must already exist. - Full-path identity drives every immutability rule.
name,partition, andsub_pathtogether form the object's real key; changing any of them is destroy/recreate, never an in-place update -- consuming iRules/policies must be repointed at the new full path in the same change. idandfull_pathboth surface alongsidename. Per this module suite's design-decisions log,nameremains the practical cross-reference key;full_pathis retained mainly for diagnostics/reporting since it is computed identically tonamefor objects with nosub_path.
| Concern | Secure default in this module | Opt-out (caller must type extra) |
|---|---|---|
| Partition scope | partition defaults to "Common" only because that is bigip_ltm_ifile's own provider default -- not an invented default |
Caller sets partition explicitly for any non-/Common object |
| File provenance | file_name is never created or overwritten by this module -- it must reference a system iFile that already exists, sourced by name from terraform-bigip-sys-ifile rather than a hand-maintained literal |
N/A -- this module has no path to author file content itself |
| Secrets | Not applicable -- bigip_ltm_ifile carries no certificate/key/secret-shaped attribute; if the referenced file content itself is sensitive, that is terraform-bigip-sys-ifile's concern |
N/A |
| Monitor/health-check | Not applicable -- an iFile reference has no health-check concept | N/A |
| Connection limits / persistence | Not applicable -- this is not a pool or virtual-server object | N/A |
| TLS certificate validation | Not applicable -- no TLS-related attributes on this resource | N/A |
cd C:\GitHubCode\newf5modules\bigip\terraform-bigip-ltm-ifile
terraform init -backend=false
terraform validate
terraform fmt -checkPin consuming module calls to ?ref=v1.0.0 (or the current tagged release) rather than an
unpinned branch reference:
source = "git::https://github.com/microsoftexpert/terraform-bigip-ltm-ifile.git?ref=v1.0.0"This module's offline proof gate is terraform init -backend=false && terraform validate && terraform fmt -check. That gate exercises:
- Type-correctness of all four variables (
name,file_name,partition,sub_path) against their declared types. - HCL formatting.
It does not exercise: whether the system iFile named in file_name actually exists on the
target device, whether the target partition exists, or how BIG-IP itself resolves the object's
full path at apply time. Only terraform plan/apply against a real, reachable BIG-IP device --
with the caller's root module supplying a configured bigip provider -- exercises that live-device
validation.
$ terraform output
name = "/Common/app-error-template"
id = "app-error-template" # provider-internal id -- not confirmed to equal the full path
full_path = "/Common/app-error-template"
| Symptom | Cause | Fix |
|---|---|---|
terraform apply fails with a generic iControl REST error referencing file_name |
The referenced system iFile does not exist at that exact full path on the target device | Verify the system iFile exists (via terraform-bigip-sys-ifile or out of band) before applying this module |
terraform plan shows the LTM iFile will be destroyed and recreated after changing name |
BIG-IP addresses LTM objects by full path; a name change is a new object identity, not a rename | Treat name changes as destroy/recreate; update any consuming terraform-bigip-ltm-irule/terraform-bigip-ltm-policy references in the same change |
Same destroy/recreate behavior after changing partition or sub_path |
Both are part of the object's full-path identity | Expected -- there is no in-place "move between partitions" operation for an LTM iFile |
iRule referencing this iFile fails at runtime with an ifile lookup error |
The iRule's TCL body references a full path that does not match this module's name output (e.g. a stale literal instead of module.x.name) |
Wire the iRule's TCL body (or a templated value fed into it) from this module's name output rather than a hand-maintained literal |
terraform validate passes but apply fails on a fresh partition |
Target partition does not yet exist on the device | Create the partition out of band before applying this module -- it is a prerequisite, not something this module manages |
bigip_ltm_ifileArgument Reference -- F5Networks/bigip provider docsterraform-bigip-sys-ifile-- owns the system iFile content this module references by nameterraform-bigip-ltm-irule-- consumes this module'snameoutput via the TCLifilecommandterraform-bigip-ltm-policy-- consumes this module'snameoutput via a policy action- This module's
SCOPE.md-- cross-module contract