Jump to content
Welcome to our new Citrix community!
  • Simplified Content Switching with Terraform


    Konstantinos Kaltsas
    • Validation Status: Validated
      Summary: Simplified Content Switching with Terraform and the NetScaler Automation Toolkit
      Has Video?: No

    Simplified Content Switching with Terraform

    Submitted Dec 12, 2023

    Author: Bhalchandra Chaudhari

    Continuing to our Parent-Child Terraform deployment, in the last blog, we saw the SSL offloading feature with simplified Terraform re-usable modules, which helps to keep your common configuration intact within the NetScaler infrastructure itself.  Today, we will see a similar use case for the layer 7 type load balancing feature of NetScaler, i.e., Content Switching, simplified with terraform modules. Content Switching enables the NetScaler ADC appliance to direct requests sent to the same Web host to different servers with different content. Find more details about the “Terraform Parent-Child” deployment in the mentioned SSL offloading article.

    Below is the Content Switching load balancing created using Terraform parent-child deployment

    Child Modules prepared to call in root/parent module:

    • SSL certificate key-pair

    • SSL cipher group for frontend traffic

    • SSL cipher group for backend traffic

    • SSL CS virtual server configuration and parameters set.

    • HTTP CS virtual server configuration for secure redirection

    • Require target load balancing set up.

    • Content Switching actions and policies.

    • Responder for HTTP to HTTPS redirection

    Parent/Root modules:

    • Application-specific module, e.g., corpservices.example.com

    The directory structure for this deployment is as below

     

    ├───citrixadc					- Citrix ADC terraform provider files├───commonmodules				- child/shared module main directory│   ├───cipher_svc					- child (shared) module backend cipher group│   ├───cipher_vs					- child (shared) module frontend cipher group│   ├───lbservice					- child (configuration) module load balancing services│   ├───responder_httpTohttps			- child (shared) module for responder│   └───sslcertkeypair				- child (shared) module SSL certificate keypair ├───contentswitching				- feature parent directory/module │   └───corporate.example.com			- application root/parent directory/module│       ├───TargetLB1				- child (configuration) module load balancing services│       ├───TargetLB2				- child (configuration) module load balancing services│       └───TargetLB3				- child (configuration) module load balancing services└───sslcerts					- SSL files (cert and key) directory

     

    Each module contains its terraform files to prepare the configuration plan and helps the root module execute the configuration depending on variable attributes/parameter values.

    The child or shared modules have their own configuration plan. The respective shared module values are provided as references in the application root module so that the required shared configuration should not get destroyed/changed if there is any change in application attributes/parameters. The necessary states are maintained separately.

    Below is the terraform structure depicts each main directory module and sub-directory (child module) with respective terraform files:

     

    │   .gitignore│   secret.tfvars│├───citrixadc├───commonmodules│   ├───cipher_svc│   │   │   .terraform.lock.hcl│   │   │   output.tf│   │   │   provider.tf│   │   │   README.md│   │   │   resources.tf│   │   │   terraform.tfstate│   │   │   terraform.tfstate.backup│   │   │   variables.tf│   ││   ├───cipher_vs│   │   │   .terraform.lock.hcl│   │   │   output.tf│   │   │   provider.tf│   │   │   README.md│   │   │   resources.tf│   │   │   terraform.tfstate│   │   │   terraform.tfstate.backup│   │   │   variables copy.tf│   │   │   variables.tf│   ││   ├───lbservice│   │       output.tf│   │       README.md│   │       resources.tf│   │       variables.tf│   ││   ├───responder_httpTohttps│   │   │   .terraform.lock.hcl│   │   │   output.tf│   │   │   provider.tf│   │   │   resources.tf│   │   │   terraform.tfstate│   │   │   terraform.tfstate.backup│   │   │   terraform.tfvars│   │   │   variables.tf│   ││   └───sslcertkeypair│       │   .terraform.lock.hcl│       │   output.tf│       │   provider.tf│       │   README.md│       │   resources.tf│       │   terraform.tfstate│       │   terraform.tfvars│       │   variables.tf│├───contentswitching│   │   README.md│   ││   └───corporate.example.com│       │   .terraform.lock.hcl│       │   provider.tf│       │   README.md│       │   resources.tf│       │   terraform.tfstate│       │   terraform.tfstate.backup│       │   terraform.tfvars│       │   variables.tf│       ││       ├───TargetLB1│       │   │   .terraform.lock.hcl│       │   │   provider.tf│       │   │   resources.tf│       │   │   terraform.tfstate│       │   │   terraform.tfstate.backup│       │   │   terraform.tfvars│       │   │   variables.tf│       ││       ├───TargetLB2│       │   │   .terraform.lock.hcl│       │   │   provider.tf│       │   │   resources.tf│       │   │   terraform.tfstate│       │   │   terraform.tfstate.backup│       │   │   terraform.tfvars│       │   │   variables.tf│       ││       └───TargetLB3│           │   .terraform.lock.hcl│           │   provider.tf│           │   resources.tf│           │   terraform.tfstate│           │   terraform.tfstate.backup│           │   terraform.tfvars│           │   variables.tf│           ││     └───sslcerts        bkclab.cer.cert        bkclab.cer.key        terracert.cert        terracert.key

     

    You can find the required terraform files of all modules here , where the resource block of each child module is called using data resource to configure load balancing entity.

     

    Execution

    As states are maintained separately, each child module except “lbservice” runs individually to refer to the output value of each in the parent application module. Similarly, the target LBs are executed to keep the web application content requests separate. 

    On running terraform init, terraform plan, and terraform apply, the module creates all the required entities and bindings between them, as shown below.

     

    PS C:\Users\bkchaudhari\article\contentswitching\corporate.example.com> terraform initInitializing modules... Initializing the backend... Initializing provider plugins...- terraform.io/builtin/terraform is built in to Terraform- Finding latest version of citrix/citrixadc...- Installing citrix/citrixadc v1.32.0...- Installed citrix/citrixadc v1.32.0 PS C:\Users\bhalchandrac\ssloffload\example.com> terraform plan -var-file="../../secret.tfvars" Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:  + create Intentionally I skipped the plan output, to reduce the article size. Terraform will create 23 resources to configure content switching. PS C:\Users\bhalchandrac\article\example.com> terraform apply -var-file="../../secret.tfvars"  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: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  citrixadc_csaction.tf_csaction3: Creating...module.loadbalancingservices.citrixadc_server.tf_server["testservermain01"]: Creating...citrixadc_csaction.tf_csaction2: Creating...citrixadc_csaction.tf_csaction1: Creating...module.loadbalancingservices.citrixadc_server.tf_server["testservermain02"]: Creating...citrixadc_csvserver.tf_csvserverssl: Creating...citrixadc_csvserver.tf_csvserverhttp: Creating...citrixadc_lbvserver.tf_lbvserverhttp: Creating...citrixadc_csaction.tf_csaction3: Creation complete after 0s [id=csact.webapp3]citrixadc_cspolicy.tf_cspolicy3: Creating...citrixadc_csaction.tf_csaction2: Creation complete after 0s [id=csact.webapp2]citrixadc_cspolicy.tf_cspolicy2: Creating...citrixadc_csaction.tf_csaction1: Creation complete after 0s [id=csact.webapp1]citrixadc_cspolicy.tf_cspolicy1: Creating...module.loadbalancingservices.citrixadc_server.tf_server["testservermain01"]: Creation complete after 0s [id=testservermain01]module.loadbalancingservices.citrixadc_server.tf_server["testservermain02"]: Creation complete after 0s [id=testservermain02]module.loadbalancingservices.citrixadc_service.tf_service["testservermain02"]: Creating...module.loadbalancingservices.citrixadc_service.tf_service["testservermain01"]: Creating...citrixadc_cspolicy.tf_cspolicy3: Creation complete after 1s [id=cspol.webapp3]citrixadc_cspolicy.tf_cspolicy2: Creation complete after 1s [id=cspol.webapp2]citrixadc_cspolicy.tf_cspolicy1: Creation complete after 1s [id=cspol.webapp1]module.loadbalancingservices.citrixadc_service.tf_service["testservermain02"]: Creation complete after 1s [id=testservermain02-443]citrixadc_lbvserver.tf_lbvserverhttp: Creation complete after 1s [id=corpwebapp.corporate.com:443]citrixadc_csvserver.tf_csvserverhttp: Creation complete after 1s [id=corpservices.example.com:80]citrixadc_csvserver_responderpolicy_binding.tf_bind: Creating...module.loadbalancingservices.citrixadc_service.tf_service["testservermain01"]: Creation complete after 1s [id=testservermain01-443]citrixadc_lbvserver_service_binding.tf_bindinghttp["testservermain02"]: Creating...citrixadc_lbvserver_service_binding.tf_bindinghttp["testservermain01"]: Creating...citrixadc_csvserver_responderpolicy_binding.tf_bind: Creation complete after 0s [id=corpservices.example.com:80,httptohttps_pol]citrixadc_csvserver.tf_csvserverssl: Creation complete after 1s [id=corpservices.example.com:443]citrixadc_lbvserver_service_binding.tf_bindinghttp["testservermain01"]: Creation complete after 0s [id=corpwebapp.corporate.com:443,testservermain01-443]citrixadc_sslvserver.tf_cssslvserver: Creating...citrixadc_csvserver_cspolicy_binding.tf_cspolbind1: Creating...citrixadc_sslvserver_sslciphersuite_binding.tf_cssslvserver_sslciphersuite_binding: Creating...citrixadc_csvserver_cspolicy_binding.tf_cspolbind3: Creating...citrixadc_lbvserver_service_binding.tf_bindinghttp["testservermain02"]: Creation complete after 0s [id=corpwebapp.corporate.com:443,testservermain02-443]citrixadc_csvserver_cspolicy_binding.tf_cspolbind2: Creating...citrixadc_sslvserver_sslcertkey_binding.cert_bindingcs: Creating...citrixadc_csvserver.tf_defaulttargetbinding: Creating...citrixadc_csvserver_cspolicy_binding.tf_cspolbind1: Creation complete after 1s [id=corpservices.example.com:443,cspol.webapp1]citrixadc_csvserver_cspolicy_binding.tf_cspolbind3: Creation complete after 1s [id=corpservices.example.com:443,cspol.webapp3]citrixadc_sslvserver_sslciphersuite_binding.tf_cssslvserver_sslciphersuite_binding: Creation complete after 1s [id=corpservices.example.com:443,CorporateExternal]citrixadc_csvserver_cspolicy_binding.tf_cspolbind2: Creation complete after 1s [id=corpservices.example.com:443,cspol.webapp2]citrixadc_sslvserver_sslcertkey_binding.cert_bindingcs: Creation complete after 1s [id=corpservices.example.com:443,terracert]citrixadc_sslvserver.tf_cssslvserver: Creation complete after 1s [id=corpservices.example.com:443]citrixadc_csvserver.tf_defaulttargetbinding: Creation complete after 1s [id=corpservices.example.com:443] Apply complete! Resources: 23 added, 0 changed, 0 destroyed. Outputs: csaction1 = "csact.webapp1"csaction2 = "csact.webapp2"csaction3 = "csact.webapp3"cspolicy1 = "cspol.webapp1"cspolicy1binding = "corpservices.example.com:443,cspol.webapp1"cspolicy2 = "cspol.webapp2"cspolicy2binding = "corpservices.example.com:443,cspol.webapp2"cspolicy3 = "cspol.webapp3"cspolicy3binding = "corpservices.example.com:443,cspol.webapp3"cssslvserver_certbinding = "corpservices.example.com:443,terracert"cssslvserver_cipherbinding = "corpservices.example.com:443,CorporateExternal"csvserverhttp = "corpservices.example.com:80"csvserverssl = "corpservices.example.com:443"lbservices = [  "testservermain01-443",  "testservermain02-443",]lbvserverhttp = "corpwebapp.corporate.com:443"

     

    The module creates all the required entities and binding between them.

    Note: This module does not show the destroy function of content-switching entities. The parent module can be destroyed entirely at once; however, the target load balancing virtual cannot be destroyed if it has a CS action attached. To remove or change the target LB, unset the target LB from the action and then change/destroy the configuration.

    Conclusion

     

    You can use the NetScaler and Terraform solutions for new content switching or adding settings to existing content switching, or to customize a deployment to fit with the application content access that you want to provide to end users as they need. NetScaler Terraform modules enable an infrastructure-as-code approach and seamlessly integrate with your automation environment using reusable modules.

     

    What's next?

    How to get started with NetScaler Automation Toolkit?

    (You can find all NetScaler Automation Toolkit details in our Automation Toolkit GitHub repository )

     

    1. Visit the hands-on labs for Terraform with NetScaler to familiarize yourself with NetScaler Automation Toolkit.

     

    2. Set up your private lab by following NetScaler's Get Started guides for Terraform.

     

     

    3. Follow the Beginners Guide to get comfortable with common commands.

     

     

    4. Be part of the Community. Pick a common NetScaler use case/configuration, create a Terraform template, and publish it on the NetScaler Community.

     

    Additional resources for NetScaler Automation Toolkit?

    Visit the following links to get more details on using Terraform with NetScaler.


    User Feedback

    Recommended Comments

    There are no comments to display.



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...