[T&C] Getting started with Thunder ADC configuration using Terraform
In this article, we will see how you can use the Infrastructure as Code (IaC) tool Terraform to configure the Thunder ADC.
The current configuration of the Thunder ADC is as follows:
vThunder#sh runn !64-bit Advanced Core OS (ACOS) version 5.2.1-p2, build 117 (Jul-10-2021,17:40) ! ip dns primary 8.8.8.8 ! timezone America/Los_Angeles ! ntp server time.google.com prefer ! interface management ip address 10.64.4.134 255.255.255.0 ip default-gateway 10.64.4.1 ! interface ethernet 1 enable ip address 100.64.1.253 255.255.255.0 ! interface ethernet 2 enable ip address 100.64.100.253 255.255.255.0 ! ! ip route 0.0.0.0 /0 100.64.100.254 ! sflow setting local-collection ! sflow collector ip 127.0.0.1 6343 ! ! end !Current config commit point for partition 0 is 0 & config mode is classical-mode
As one can see, currently there is no SLB configuration on the Thunder device. We will use Terraform to add SLB configuration to this Thunder device.
Prerequisite
First, download and install Terraform as outlined at:
Here, we are using the following Terraform version:
~$ terraform -v Terraform v1.1.7 on linux_amd64
Create Terraform configuration file
Now, create a directory, say a10, and within it, a .tf file (e.g. vthunder.tf):
~/a10$ cat vthunder.tf terraform { required_providers { thunder = { source = "a10networks/thunder" version = "1.0.0" } } } variable "thunder_username" { description = "Thunder device username" type = string sensitive = true } variable "thunder_password" { description = "Thunder device password" type = string sensitive = true } provider "thunder" { # Configuration options address = "10.64.4.134" username = var.thunder_username password = var.thunder_password } resource "thunder_server" "rs1" { name = "RS1" host = "100.64.100.10" port_list { port_number = 80 protocol = "tcp" } } resource "thunder_server" "rs2" { name = "RS2" host = "100.64.100.11" port_list { port_number = 80 protocol = "tcp" } } resource "thunder_service_group" "sg-web" { name = "SG-WEB" protocol="TCP" member_list { name=thunder_server.rs1.name port=80 } member_list { name=thunder_server.rs2.name port=80 } } resource "thunder_virtual_server" "ws-vip" { name = "ws-vip" ip_address = "100.64.1.250" port_list { port_number = 80 protocol = "http" service_group = thunder_service_group.sg-web.name } } ~/a10$
The section:
terraform { required_providers { thunder = { source = "a10networks/thunder" version = "1.0.0" } } }
specifies the provider to be downloaded and installed, in this case, A10's Terraform provider.
The section:
variable "thunder_username" { description = "Thunder device username" type = string sensitive = true } variable "thunder_password" { description = "Thunder device password" type = string sensitive = true } provider "thunder" { # Configuration options address = "10.64.4.134" username = var.thunder_username password = var.thunder_password }
specifies the connection details for the Thunder device. Update the IP address (e.g. 10.64.4.134) based on your own setup.
The section:
resource "thunder_server" "rs1" { name = "RS1" host = "100.64.100.10" port_list { port_number = 80 protocol = "tcp" } } resource "thunder_server" "rs2" { name = "RS2" host = "100.64.100.11" port_list { port_number = 80 protocol = "tcp" } } resource "thunder_service_group" "sg-web" { name = "SG-WEB" protocol="TCP" member_list { name=thunder_server.rs1.name port=80 } member_list { name=thunder_server.rs2.name port=80 } } resource "thunder_virtual_server" "ws-vip" { name = "ws-vip" ip_address = "100.64.1.250" port_list { port_number = 80 protocol = "http" service_group = thunder_service_group.sg-web.name } }
specifies the SLB configuration for the Thunder device.
Here we have specified a virtual server (VIP) of 100.64.1.250 for HTTP service with a service-group consisting of two back-end servers, 100.64.100.10 and 100.64.100.11.
Modify this to match your deployment.
Terraform Init command
Now run the "terraform init" command. This will download and install the A10 Terraform Provider:
~/a10$ terraform init Initializing the backend... Initializing provider plugins... - Finding a10networks/thunder versions matching "1.0.0"... - Installing a10networks/thunder v1.0.0... - Installed a10networks/thunder v1.0.0 (signed by a HashiCorp partner, key ID F192222783C8DB3D) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or 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.
Set values of variables for Thunder username/password
Next, we will run the "terraform plan" command.
However, before that, we will set the values of Terraform variables for the Thunder username/password.
Here we set the values to the default username/password for the Thunder device, however, this could be different for your setup:
~/a10$ export TF_VAR_thunder_username=admin ~/a10$ export TF_VAR_thunder_password=a10
Terraform Plan command
Now, run the "terraform plan" command. This command lets you preview the proposed changes before actually executing them.
~/a10$ terraform plan Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # thunder_server.rs1 will be created + resource "thunder_server" "rs1" { + host = "100.64.100.10" + id = (known after apply) + name = "RS1" + port_list { + port_number = 80 + protocol = "tcp" } } # thunder_server.rs2 will be created + resource "thunder_server" "rs2" { + host = "100.64.100.11" + id = (known after apply) + name = "RS2" + port_list { + port_number = 80 + protocol = "tcp" } } # thunder_service_group.sg-web will be created + resource "thunder_service_group" "sg-web" { + id = (known after apply) + name = "SG-WEB" + protocol = "TCP" + member_list { + name = "RS1" + port = 80 } + member_list { + name = "RS2" + port = 80 } } # thunder_virtual_server.ws-vip will be created + resource "thunder_virtual_server" "ws-vip" { + id = (known after apply) + ip_address = "100.64.1.250" + name = "ws-vip" + port_list { + port_number = 80 + protocol = "http" + service_group = "SG-WEB" } } Plan: 4 to add, 0 to change, 0 to destroy. ────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. ~/a10$
Terraform Apply command
Now, run the "terraform apply" command to execute the proposed changes:
~/a10$ terraform apply --auto-approve Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # thunder_server.rs1 will be created + resource "thunder_server" "rs1" { + host = "100.64.100.10" + id = (known after apply) + name = "RS1" + port_list { + port_number = 80 + protocol = "tcp" } } # thunder_server.rs2 will be created + resource "thunder_server" "rs2" { + host = "100.64.100.11" + id = (known after apply) + name = "RS2" + port_list { + port_number = 80 + protocol = "tcp" } } # thunder_service_group.sg-web will be created + resource "thunder_service_group" "sg-web" { + id = (known after apply) + name = "SG-WEB" + protocol = "TCP" + member_list { + name = "RS1" + port = 80 } + member_list { + name = "RS2" + port = 80 } } # thunder_virtual_server.ws-vip will be created + resource "thunder_virtual_server" "ws-vip" { + id = (known after apply) + ip_address = "100.64.1.250" + name = "ws-vip" + port_list { + port_number = 80 + protocol = "http" + service_group = "SG-WEB" } } Plan: 4 to add, 0 to change, 0 to destroy. thunder_server.rs2: Creating... thunder_server.rs1: Creating... thunder_server.rs1: Creation complete after 1s [id=RS1] thunder_server.rs2: Creation complete after 1s [id=RS2] thunder_service_group.sg-web: Creating... thunder_service_group.sg-web: Creation complete after 0s [id=SG-WEB] thunder_virtual_server.ws-vip: Creating... thunder_virtual_server.ws-vip: Creation complete after 0s [id=ws-vip] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. ~/a10$
Verify SLB configuration on Thunder device
Now, if you check the configuration on the Thunder device, you will see the SLB configuration has been added:
vThunder# sh runn slb !Section configuration: 244 bytes ! slb server RS1 100.64.100.10 port 80 tcp ! slb server RS2 100.64.100.11 port 80 tcp ! slb service-group SG-WEB tcp member RS1 80 member RS2 80 ! slb virtual-server ws-vip 100.64.1.250 port 80 http service-group SG-WEB ! vThunder#
Note that in the above example, we manually specified the members of the SLB service-group in the Terraform configuration file. However, you can also automate this process as described in the article:
Automate Application Delivery Operation Tasks with A10 and HashiCorp NIA
Additional Details about A10 Terraform Provider
For more details about A10 Terraform Provider, please refer to: