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 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.
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. |
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.
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.
OPTIONAL: At this stage, if
terraform apply
failed with an error, it is likely a syntax error in the configuration. Fix any errors.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
.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.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.11
- Terraform installed
To build locally
git clone https://github.com/F5Networks/terraform-provider-bigip.git
cd terraform-provider-bigip
export GOFLAGS=-mod=vendor
go build
- Move the binary to the current working directory where Terraform config files are located.
What’s Next?