Note: Scroll down this article to download the terrafom files in zip format. |
Cloud Security Connector MUX for Zscaler (ZIA) with PriCPA for Azure
This Terraform template deploys one or two Cloud Security Connector (CSC) MUX with PriCPA for Azure appliances into an existing Azure Virtual Network (VNet).
It is based on the official Cloud Security Connector ARM templates from the Azure Marketplace but consolidates multiple deployment scenarios (Availability Zones, Availability Sets, and single/dual VM) into a single, flexible Terraform configuration.
Features
- Flexible Deployment: Deploy in High Availability (2 VMs) or as a single instance (1 VM) using the
vm_countvariable. - Flexible Infrastructure:
az: Deploys VMs across different Availability Zones.as: Deploys VMs into a new Availability Set.ni: Deploys VMs with no specific HA infrastructure.
- Multi-Model Support: Supports MUX models 1, 2, 4, and 8 via the
csc_model_versionvariable. The template automatically adjusts:- The number of ZTUN Public IPs and network interface configurations.
- The correct VM Marketplace Image and Plan.
- Accelerated Networking (enabled for models 4 and 8).
- Automated Role Assignments: Automatically grants the VM's Managed Identity the "Contributor" and "Network Contributor" roles on:
- The VM's Resource Group.
- The VNet's Resource Group (if different from the VM's).
- User Data Provisioning: Reads a
configUserData.jsonfile from the local directory, Base64 encodes it, and passes it to the VM'suser_dataproperty for provisioning.
Prerequisites
Before running this template, you must have:
- Terraform (v1.0+) and the Azure provider (v3.1+).
- Azure Credentials configured (e.g., by running
az login). - An Existing Azure VNet.
- Two Existing Subnets in the VNet (e.g.,
csc-external-subnetandcsc-internal-subnet). - A
configUserData.jsonfile in the same directory. You can pass configuration values or leave it by default.
Usage
- Place all
.tffiles,terraform.auto.tfvars, andconfigUserData.jsonin the same directory. - Edit
terraform.auto.tfvarsto match your environment. - Edit
configUserData.jsonwith your specific CSC provisioning data. - Initialize the project:
terraform init - Review the plan:
terraform plan - Apply the configuration:
terraform apply
Configuration Files
1. terraform.auto.tfvars (User Configuration)
This is the primary file you will edit.
# ----------------------------------------------------------------
# CSC Deployment Configuration
# ----------------------------------------------------------------
# --- CSC MUX Model ---
# 1 = zs-csc-mux-1 (1 ZTUN)
# 2 = zs-csc-mux-2 (2 ZTUNs)
# 4 = zs-csc-mux-4 (4 ZTUNs)
# 8 = zs-csc-mux-8 (8 ZTUNs)
csc_model_version = 2 # <--- SET YOUR MODEL HERE
# --- Select Single or HA ---
# 1 = Single VM
# 2 = High Availability (HA) Pair
vm_count = 2
# -- Deployment Choices --
# "az" = Availability Zones (Recommended for HA)
# "as" = Availability Sets (For regions without AZs)
# "ni" = No Infrastructure (Single VM or standalone VMs)
deployment_type = "az"
# -- Availability Zone Settings (Only used if deployment_type = "az") --
# Ensure you have one zone per VM in vm_count.
availability_zones = ["1", "2"]
# -- Availability Set Settings (Only used if deployment_type = "as") --
availability_set_name = "zs-csc-av-set"
fault_domains = 2
update_domains = 5
# -- VM Configuration --
# This is the base name for all your VMs (e.g., "zs-csc-mux")
vm_name_prefix = "zs-csc-mux-2-az"
# The resource group where the new VMs and NICs will be created.
resource_group_name = "my-zscaler-rg"
# --- IMPORTANT ---
# Recommended VM Sizes:
# zs-csc-mux-1: "Standard_B2ats_v2"
# zs-csc-mux-2: "Standard_D2s_v3"
# zs-csc-mux-4: "Standard_D4s_v3"
# zs-csc-mux-8: "Standard_D8s_v3"
# Models 4 and 8 require Accelerated Networking.
vm_size = "Standard_B2ats_v2"
# Example: "Standard_LRS", "Premium_LRS", "StandardSSD_LRS"
storage_disk_type = "Standard_LRS"
# -- VM Authentication --
# "sshPublicKey" or "password"
authentication_type = "sshPublicKey"
# Paste your *full public SSH key* here (if using sshPublicKey)
# or your desired password (if using password).
admin_password_or_key = "ssh-rsa AAAA..." # <--- REPLACE THIS
# The names of your *existing* network resources.
vnet_name = "my-vnet"
vnet_resource_group_name = "my-network-rg"
external_subnet_name = "csc-external-subnet"
internal_subnet_name = "csc-internal-subnet"
Outputs
| Name | Description |
|---|---|
virtual_machine_names | The names of the created virtual machines. |
vm_public_ips | A map of all external IPs (Bypass and ZTUNs) for each VM. |
vm_private_ips | A map of the primary private IPs for each VM's internal NIC. |
vm_managed_identity_principal_ids | A map of the Managed Identity Principal IDs for each VM, used for role-based access control. |