Configuring 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 only using JSON when the configuration is generated by a machine. F5 recommends using a standalone machine or VM where Terraform is installed for configuration. If you need to use Terraform Cloud, you should set up a proper RBAC to protect the BIG-IP credentials.

Below is an example of the entire configuration. Each section is described below the example. Save the contents to 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 to create a policy on the BIG-IP system

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

resource "bigip_ltm_policy" "test-policy" {
    name = "my_policy"
    strategy = "first-match"
    requires = ["http"]
    published_copy = "Drafts/my_policy"
    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: the resource type and the 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.

Parameter Options Description/Notes
name Required Describes the name of the policy.
strategy Optional This value specifies the match strategy.
requires Optional This value specifies the protocol.
published_copy Optional This value determines if you want to publish the policy else it will be deployed 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.

Initializating

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 that will be 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:

root@terraforn-ubuntu3:~/go/src/github.com/terraform-providers/terraform-provider-bigip# terraform init

 Initializing the backend...

 Initializing provider plugins...

 Terraform has been successfully initialized!

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

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 above. 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.

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

The output below 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, it shows the attributes that will be set. When the value displayed is (known after apply), it means that the value won’t be known until the resource is created.

root@terraforn-ubuntu3:~/go/src/github.com/terraform-providers/terraform-provider-bigip# 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 = "my_policy"
 + published_copy = "Drafts/my_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=my_policy]

 Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
 root@terraforn-ubuntu3:~/go/src/github.com/terraform-providers/terraform-provider-bigip#

If terraform apply failed with an error, read the error message and fix the error that occurred. At this stage, it is likely to be a syntax error in the configuration.

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 here with no changes made to your infrastructure. If the plan looks acceptable, so type yes at the confirmation prompt to proceed.

You can now verify the new policy created by Terraform in BIG-IP.

Terraform also wrote some 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. This file must be saved and distributed to anyone who will run Terraform. It is generally recommended to setup remote state when working with Terraform, to share the state automatically, but this is not necessary for simple situations like this Getting Started guide.

You can inspect the current state using terraform show:

root@terraforn-ubuntu3:~/go/src/github.com/terraform-providers/terraform-provider-bigip# terraform show
 # bigip_ltm_policy.test-policy:
 resource "bigip_ltm_policy" "test-policy" {
 controls = [
 "forwarding",
 ]
 id = "my_policy"
 name = "my_policy"
 published_copy = "Drafts/my_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
 }
 root@terraforn-ubuntu3:~/go/src/github.com/terraform-providers/terraform-provider-bigip#