Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔴 F5 BIG-IP LTM iFile Terraform Module

terraform-bigip-ltm-ifile manages a single bigip_ltm_ifile object -- 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 the F5Networks/bigip Terraform provider ~> 1.28.

Terraform Provider Module Version Module Type Resources Posture


🧩 Overview

  • 🔗 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 sibling terraform-bigip-sys-ifile module or out of band.
  • 🏷️ Emits a name output holding the full-path identity (/Partition/name) as the practical primary cross-reference key -- sourced from the provider's computed full_path attribute, since (unlike most resources in this catalog) the live schema keeps the resource's own name argument as a bare leaf identifier, separate from partition.
  • 🧵 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 no dynamic.
  • 🔓 partition defaults to "Common" only because that is the underlying resource's own provider default, not an invented one; sub_path defaults to null (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.


❤️ 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

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;
Loading

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.


🧬 What this builds

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;
Loading

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

✅ Provider / Versions

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, and sub_path are 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_name must 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.
  • partition defaults to "Common" because that is bigip_ltm_ifile's own provider default -- per this module suite's partition-scope rule, this is not an invented default.
  • sub_path defaults to null, placing the object directly under partition with no hierarchical sub-path segment unless the caller opts in.
  • The resource's own name argument is a bare leaf identifier (e.g. app-error-template), not a full path -- unlike most resources in this catalog. This module's name output is deliberately sourced from the provider-computed full_path attribute (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 id attribute, so whether it echoes the bare name or the full path is unconfirmed -- consume this module's name output (not id) for cross-references.

🔑 Required BIG-IP User Role / Partition Access

Manager role scoped to the target partition is sufficient; Administrator is not required for this application-layer LTM object.


F5 BIG-IP Prerequisites

  • 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_name must already exist on the device (created out of band or via terraform-bigip-sys-ifile) before this module applies -- bigip_ltm_ifile references it by full path and does not create or upload file content itself.

📁 Module Structure

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

⚙️ Quick Start

# 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
}

🔌 Cross-Module Contract

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)

📚 Example Library

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") and sub_path (null) both fall back to the provider's own defaults -- nothing here is invented by this module. name is deliberately bare here: unlike most resources in this catalog, bigip_ltm_ifile's live schema keeps name and partition as two separate arguments, so this module's name output (not the name input) 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_name from the sibling module's name output (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, partition is a genuine per-resource input here (this object is partition-scoped) -- the caller must set it explicitly for any non-/Common object 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_path set, the object's full path becomes /Common/templates/ltm-error-template rather 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
}

⚠️ Prefer module.maintenance_page_sys_ifile.name over .id for file_name unless you have independently confirmed that sibling module's id output carries the full path -- this module's own id output, for instance, is not confirmed to match name/full_path (see Schema notes above). name is 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"
}

⚠️ Changing name (or partition/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_ifile has 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 name outputs, 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).


📥 Inputs

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.

🧾 Outputs

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

🧠 Architecture Notes

  • Total renderer, no nested blocks. All four arguments (name, file_name, partition, sub_path) map directly onto bigip_ltm_ifile.this with no dynamic blocks, no try, and no for_each inside the module -- the simplest thin-renderer shape in the catalog, since bigip_ltm_ifile's live schema exposes no nested or repeating structure.
  • No owned children. Unlike terraform-bigip-ltm-node (a single-item fqdn dynamic block) or terraform-bigip-ltm-policy (a for_each-keyed rule collection), 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, and sub_path together 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.
  • id and full_path both surface alongside name. Per this module suite's design-decisions log, name remains the practical cross-reference key; full_path is retained mainly for diagnostics/reporting since it is computed identically to name for objects with no sub_path.

🧱 Design Principles

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

🚀 Runbook

cd C:\GitHubCode\newf5modules\bigip\terraform-bigip-ltm-ifile
terraform init -backend=false
terraform validate
terraform fmt -check

Pin 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"

🧪 Testing

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.


💬 Example Output

$ 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"

🔍 Troubleshooting

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

🔗 Related Docs

  • bigip_ltm_ifile Argument Reference -- F5Networks/bigip provider docs
  • terraform-bigip-sys-ifile -- owns the system iFile content this module references by name
  • terraform-bigip-ltm-irule -- consumes this module's name output via the TCL ifile command
  • terraform-bigip-ltm-policy -- consumes this module's name output via a policy action
  • This module's SCOPE.md -- cross-module contract

Releases

Packages

Contributors

Languages