Last updated on: 2023-10-18 04:01:19.

F5 Resources for Terraform Overview

Install and use Terraform for building, changing, and versioning F5 BIG-IP and F5OS infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

Configuration files describe the Terraform components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans that you can apply.

Use the following Provider resources to create, edit, update, and delete configuration objects:

Install Terraform

  1. To install Terraform, find and download the appropriate package for your system. Terraform is packaged as a zip archive. Use the SHA256 checksums for Terraform 0.12.9 and verify the checksums signature file which has been signed using HashiCorp’s GPG key before opening the zip file to ensure you are not using a maliciously modified version of Terraform.
  2. After downloading Terraform, unzip the package. Terraform runs as a single binary named terraform. Any other files in the package can be safely removed and Terraform will still function.
  3. Make sure that the terraform binary is available on the PATH.

Verifying the Installation

After installing Terraform, verify the installation worked by opening a new terminal session and running the terraform command.

You will see help output like this:

$ terraform
Usage: terraform [--version] [--help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
# ...

If you get an error that terraform could not be found, your PATH environment variable was not set up properly. Ensure that your PATH variable contains the directory where Terraform was installed.

Now you can build infrastructure on the F5 BIG-IP system (for example, policy configuration) using Terraform resources.

Configure Terraform

The set of files used to describe infrastructure in Terraform is known as a Terraform configuration. To read about the syntax of the configuration files, see this documentation.

F5 recommends the following:

  • Only using JSON when the configuration is generated by a machine.
  • Using a standalone machine or VM where Terraform is installed for configuration.
  • If using Terraform Cloud, set up a proper RBAC to protect the F5 BIG-IP credentials.

The following example presents the entire configuration with descriptions for each section. Save the example contents in a file named, bigip_ltm_policy.tf.

Important

Verify that there are no other *.tf files in your directory, since Terraform loads all of them.

Sample Terraform resource

The following sample demonstrates creating a policy on the F5 BIG-IP system:

provider "bigip" {
    address = "x.x.x.x"
    username = "xxxx"
    password = "xxxx"
}

resource "bigip_ltm_policy" "test-policy" {
    name = "/Common/test-policy"
    strategy = "first-match"
    requires = ["http"]
    controls = ["forwarding"]
    rule {
        name = "rule6"
        action {
            tm_name = "20"
            forward = true
            pool = "/Common/mypool"
        }
    }
    depends_on = [bigip_ltm_pool.mypool]
}

resource "bigip_ltm_pool" "mypool" {
    name = "/Common/mypool"
    monitors = ["/Common/http"]
    allow_nat = "yes"
    allow_snat = "yes"
    load_balancing_mode = "round-robin"
}

The provider block is used to configure the named provider, in this case “bigip”. A provider is responsible for creating and managing resources. Multiple provider blocks can exist, if a Terraform configuration is composed of multiple providers, which is a common situation.

The resource block defines a resource that exists within the infrastructure. The resource block has two strings before opening the block:

  • Resource type
  • Resource name

In this example, the resource type is bigip_ltm_policy and the name is test-policy. The prefix of the type, maps to the provider. In this case bigip_ltm_policy automatically tells Terraform that it is managed by the bigip provider.

Argument reference

The following table provides parameter descriptions for the bigip_ltm_policy resource:

Parameter Options Description/Notes
name Required Describes the name of the policy.
strategy Optional This value specifies the match strategy.
description Optional Descriptive text that identifies the LTM policy.
requires Optional This value specifies the protocol.
published_copy Optional Currently, the resource automatically publishes the policy. Previously, this value determined whether to publish the policy, otherwise deploy it in Drafts mode.
controls Optional This value specifies the controls.
rule Optional Use this policy to apply rules.
tm_name Required If Rule is used, then you need to provide the tm_name. It can be any value.
forward Optional This action sets forwarding.
pool Optional This action will direct the stream to this pool.
connection Optional This action is set to true by default. You must explicitly set to false for actions with which it conflicts.

SSL key certificate

Provides details about bigip_ssl_key_cert resource and imports SSL certificate and key on BIG-IP LTM. Import the certificate and the key from files on the local disk, in PEM format.

hcl
resource "bigip_ssl_key_cert" "testkeycert" {
  partition   = "Common"
  key_name    = "ssl-test-key"
  key_content = file("key.pem")
  cert_name    = "ssl-test-cert"
  cert_content = file("certificate.pem")
}

Parameter reference

The following table provides argument and attribute descriptions for the bigip_ssl_key_cert resource:

Parameter Options Description/Notes
key_name Required Argument string type naming the SSL key that you want imported onto the BIG-IP.
key_content Required Argument with the content of the SSL key on local disk. The path of SSL key is provided to the Terraform file function.
cert_name Required Argument string type, name the SSL certificate you want imported onto the BIG-IP.
cert_content Required Argument with the content of the certificate on local disk. The path of SSL certificate is provided to the Terraform file function.
partition Optional Argument string type identifying the partition on to the SSL certificate and the key you want imported.
passphrase Optional Argument string type identifying the passphrase on the SSL key.
cert_monitoring_type Optional Argument string specifying the type of monitoring used.
issuer_cert Optional Argument string specifying the issuer certificate.
cert_ocsp Optional Argument string specifying the online certificate status protocol (OCSP) responder coming from the issuer.
id Required Attribute exported identifier of the resource.
key_full_path Required Attribute exported full path of the SSL key on the BIG-IP.
cert_full_path Required Attribute exported full path of the SSL certificate on the BIG-IP.

Initializing

The first command to run for a new configuration, or after checking out an existing configuration from version control, is terraform init, which initializes local settings and data used by subsequent commands.

Terraform uses a plugin-based architecture to support available infrastructure and service providers. As of Terraform version 0.10.0, each “Provider” is its own encapsulated binary distributed separately from Terraform itself. The terraform init command will automatically download and install any Provider binary for the providers in use within the configuration, which in this case is just the BIG-IP provider:

$ terraform init

 Initializing the backend...

 Initializing provider plugins...

 Terraform has been successfully initialized!

You can begin working with Terraform. To see changes that are required for your infrastructure, run the command terraform plan. All Terraform commands will now execute.

If you ever set or change resources or the backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so (if necessary).

Applying changes

The commands shown in this guide apply to Terraform 0.11 and later. To see the execution plan before applying it, you must run the terraform plan command in versions earlier than Terraform 0.11. Use terraform version to confirm your running version.

  1. In the same directory as the bigip_ltm_policy.tf file you created, run terraform apply.

    The following output shows the execution plan and describes which actions Terraform will take in order to change real infrastructure to match the configuration. The output format is similar to the diff format generated by tools such as Git. The output has a + next to bigip_ltm_policy.test-policy, meaning that Terraform will create this resource. Beneath that, the output displays the attributes to be set. When the value displayed is (known after apply), it means that you will not know the value until the resource is created.

    $ terraform apply
    
    An execution plan has been generated and is shown below.
    Resource actions are indicated with the following symbols:
    + create
    
    Terraform will perform the following actions:
    
      # bigip_ltm_policy.test-policy will be created
      + resource "bigip_ltm_policy" "test-policy" {
          + controls = [
              + "forwarding",
            ]
          + id = (known after apply)
          + name = "/Common/test-policy"
          + requires = [
              + "http",
            ]
          + strategy = "first-match"
    
          + rule {
              + name = "rule6"
    
              + action {
                  + app_service = (known after apply)
                  + application = (known after apply)
                  + asm = (known after apply)
                  + avr = (known after apply)
                  + cache = (known after apply)
                  + carp = (known after apply)
                  + category = (known after apply)
                  + classify = (known after apply)
                  + clone_pool = (known after apply)
                  + code = (known after apply)
                  + compress = (known after apply)
                  + content = (known after apply)
                  + cookie_hash = (known after apply)
                  + cookie_insert = (known after apply)
                  + cookie_passive = (known after apply)
                  + cookie_rewrite = (known after apply)
                  + decompress = (known after apply)
                  + defer = (known after apply)
                  + destination_address = (known after apply)
                  + disable = (known after apply)
                  + domain = (known after apply)
                  + enable = (known after apply)
                  + expiry = (known after apply)
                  + expiry_secs = (known after apply)
                  + expression = (known after apply)
                  + extension = (known after apply)
                  + facility = (known after apply)
                  + forward = true
                  + from_profile = (known after apply)
                  + hash = (known after apply)
                  + host = (known after apply)
                  + http = (known after apply)
                  + http_basic_auth = (known after apply)
                  + http_cookie = (known after apply)
                  + http_header = (known after apply)
                  + http_referer = (known after apply)
                  + http_reply = (known after apply)
                  + http_set_cookie = (known after apply)
                  + http_uri = (known after apply)
                  + ifile = (known after apply)
                  + insert = (known after apply)
                  + internal_virtual = (known after apply)
                  + ip_address = (known after apply)
                  + key = (known after apply)
                  + l7dos = (known after apply)
                  + length = (known after apply)
                  + location = (known after apply)
                  + log = (known after apply)
                  + ltm_policy = (known after apply)
                  + member = (known after apply)
                  + message = (known after apply)
                  + netmask = (known after apply)
                  + nexthop = (known after apply)
                  + node = (known after apply)
                  + offset = (known after apply)
                  + path = (known after apply)
                  + pem = (known after apply)
                  + persist = (known after apply)
                  + pin = (known after apply)
                  + policy = (known after apply)
                  + pool = "/Common/mypool"
                  + port = (known after apply)
                  + priority = (known after apply)
                  + profile = (known after apply)
                  + protocol = (known after apply)
                  + query_string = (known after apply)
                  + rateclass = (known after apply)
                  + redirect = (known after apply)
                  + remove = (known after apply)
                  + replace = (known after apply)
                  + request = (known after apply)
                  + request_adapt = (known after apply)
                  + reset = (known after apply)
                  + response = (known after apply)
                  + response_adapt = (known after apply)
                  + scheme = (known after apply)
                  + script = (known after apply)
                  + select = (known after apply)
                  + server_ssl = (known after apply)
                  + set_variable = (known after apply)
                  + snat = (known after apply)
                  + snatpool = (known after apply)
                  + source_address = (known after apply)
                  + ssl_client_hello = (known after apply)
                  + ssl_server_handshake = (known after apply)
                  + ssl_server_hello = (known after apply)
                  + ssl_session_id = (known after apply)
                  + status = (known after apply)
                  + tcl = (known after apply)
                  + tcp_nagle = (known after apply)
                  + text = (known after apply)
                  + timeout = (known after apply)
                  + tm_name = "20"
                  + uie = (known after apply)
                  + universal = (known after apply)
                  + value = (known after apply)
                  + virtual = (known after apply)
                  + vlan = (known after apply)
                  + vlan_id = (known after apply)
                  + wam = (known after apply)
                  + write = (known after apply)
             }
          }
      }
    
    # bigip_ltm_pool.mypool will be created
    + resource "bigip_ltm_pool" "mypool" {
    + allow_nat = "yes"
    + allow_snat = "yes"
    + id = (known after apply)
    + load_balancing_mode = "round-robin"
    + monitors = [
    + "/Common/http",
    ]
    + name = "/Common/mypool"
    + reselect_tries = (known after apply)
    + service_down_action = (known after apply)
    + slow_ramp_time = (known after apply)
    }
    
    Plan: 2 to add, 0 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    bigip_ltm_pool.mypool: Creating...
    bigip_ltm_pool.mypool: Creation complete after 0s [id=/Common/mypool]
    bigip_ltm_policy.test-policy: Creating...
    bigip_ltm_policy.test-policy: Creation complete after 0s [id=test-policy]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
  2. OPTIONAL: At this stage, if terraform apply failed with an error, it is likely a syntax error in the configuration. Fix any errors.

  3. If the plan was created successfully, Terraform will now pause and wait for approval before proceeding. If anything in the plan seems incorrect or dangerous, it is safe to exit at this step with no changes made to your infrastructure. If the plan looks acceptable, at the confirmation prompt to proceed, type yes.

  4. Verify the new policy created by Terraform in BIG-IP.

    Terraform also writes data into the terraform.tfstate file. This state file is important; it keeps track of the IDs of created resources so that Terraform knows what it is managing. You must save this file and distribute it to anyone running Terraform. F5 recommends that you setup remote state when working with Terraform. Doing so shares the state automatically; however, this is NOT required for simple situations like in this Configuration Guide.

  5. Inspect the current state using, terraform show:

    $ terraform show
    # bigip_ltm_policy.test-policy:
    resource "bigip_ltm_policy" "test-policy" {
        controls = [
            "forwarding",
        ]
        id = "test-policy"
        name = "/common/test-policy"
        requires = [
            "http",
        ]
        strategy = "/Common/first-match"
    
        rule {
            name = "rule6"
    
            action {
                 asm = false
                 avr = false
                 cache = false
                 carp = false
                 classify = false
                 code = 0
                 compress = false
                 cookie_hash = false
                 cookie_insert = false
                 cookie_passive = false
                 cookie_rewrite = false
                 decompress = false
                 defer = false
                 destination_address = false
                 disable = false
                 enable = false
                 expiry_secs = 0
                 forward = true
                 hash = false
                 http = false
                 http_basic_auth = false
                 http_cookie = false
                 http_header = false
                 http_host = false
                 http_referer = false
                 http_reply = false
                 http_set_cookie = false
                 http_uri = false
                 insert = false
                 l7dos = false
                 length = 0
                 log = false
                 ltm_policy = false
                 offset = 0
                 pem = false
                 persist = false
                 pin = false
                 pool = "/Common/mypool"
                 port = 0
                 redirect = false
                 remove = false
                 replace = false
                 request = false
                 request_adapt = false
                 reset = false
                 response = false
                 response_adapt = false
                 select = false
                 server_ssl = false
                 set_variable = false
                 source_address = false
                 ssl_client_hello = false
                 ssl_server_handshake = false
                 ssl_server_hello = false
                 ssl_session_id = false
                 status = 0
                 tcl = false
                 tcp_nagle = false
                 timeout = 0
                 tm_name = "20"
                 uie = false
                 universal = false
                 vlan_id = 0
                 wam = false
                 write = false
            }
        }
    }
    
    # bigip_ltm_pool.mypool:
    resource "bigip_ltm_pool" "mypool" {
        allow_nat = "yes"
        allow_snat = "yes"
        id = "/Common/mypool"
        load_balancing_mode = "round-robin"
        monitors = [
            "/Common/http",
        ]
        name = "/Common/mypool"
        reselect_tries = 0
        service_down_action = "none"
        slow_ramp_time = 0
    }
    

Generating a BIG-IP Provider binary

Do the following to build a Terraform BIG-IP provider binary:

Prerequisites:

  • Go 1.19
  • Terraform installed

To build locally

  1. git clone https://github.com/F5Networks/terraform-provider-bigip.git
  2. cd terraform-provider-bigip
  3. export GOFLAGS=-mod=vendor
  4. go build
  5. Move the binary to the current working directory where Terraform config files are located.

Get support

F5 provides support for the F5 BIG-IP Provider Modules for Terraform. For more information, see this page.

The community also provides informal support through a number of channels.

File an issue

To access community support, open an issue on the following:

When communicating with F5 on the Issues tab, use the GitHub user interface, rather than email.

F5 employees are members of this community and typically monitor the channel Monday-Friday 9-5 PST. They will offer best-effort assistance.

See the Slack Channel Statement for guidelines on using this channel.

Exposing confidential information

When submitting a request for help or feedback, NEVER do the following:

  • Enter any private or personally identifying information about you, your network, organization, etc.
  • Enter any passwords/credentials, logs, IP addresses, or servers/server ports.
  • Expect that an F5 employee will immediately respond. Employees offer best-effort assistance, but there may be times when responses are delayed.

If you need more in-depth technical assistance, contact F5 Support.

What’s Next?