"
diff --git a/examples/base_1cc/variables.tf b/examples/base_1cc/variables.tf
index 7626071..623b254 100755
--- a/examples/base_1cc/variables.tf
+++ b/examples/base_1cc/variables.tf
@@ -96,6 +96,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -121,7 +122,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -156,6 +157,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "http_probe_port" {
type = number
description = "Port number for Cloud Connector cloud init to enable listener port for HTTP probe from Azure LB"
@@ -236,3 +243,9 @@ variable "encryption_at_host_enabled" {
description = "User input for enabling or disabling host encryption"
default = true
}
+
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
diff --git a/examples/base_1cc_zpa/README.md b/examples/base_1cc_zpa/README.md
index 7fd7fe2..94dd5c2 100644
--- a/examples/base_1cc_zpa/README.md
+++ b/examples/base_1cc_zpa/README.md
@@ -100,6 +100,7 @@ From base_1cc_zpa directory execute:
| [ccvm\_image\_sku](#input\_ccvm\_image\_sku) | Azure Marketplace Cloud Connector Image SKU | `string` | `"zs_ser_gen1_cc_01"` | no |
| [ccvm\_image\_version](#input\_ccvm\_image\_version) | Azure Marketplace Cloud Connector Image Version | `string` | `"latest"` | no |
| [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Image size | `string` | `"Standard_D2s_v3"` | no |
+| [ccvm\_source\_image\_id](#input\_ccvm\_source\_image\_id) | Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher | `string` | `null` | no |
| [domain\_names](#input\_domain\_names) | Domain names fqdn/wildcard to have Azure Private DNS redirect DNS requests to Cloud Connector | `map(any)` | n/a | yes |
| [encryption\_at\_host\_enabled](#input\_encryption\_at\_host\_enabled) | User input for enabling or disabling host encryption | `bool` | `true` | no |
| [env\_subscription\_id](#input\_env\_subscription\_id) | Azure Subscription ID where resources are to be deployed in | `string` | n/a | yes |
@@ -113,6 +114,7 @@ From base_1cc_zpa directory execute:
| [private\_dns\_subnet](#input\_private\_dns\_subnet) | Private DNS Resolver Outbound Endpoint Subnet to create in VNet. This is only required if you want to override the default subnet that this code creates via network\_address\_space variable. | `string` | `null` | no |
| [public\_subnets](#input\_public\_subnets) | Public/Bastion Subnets to create in VNet. This is only required if you want to override the default subnets that this code creates via network\_address\_space variable. | `list(string)` | `null` | no |
| [reuse\_nsg](#input\_reuse\_nsg) | Specifies whether the NSG module should create 1:1 network security groups per instance or 1 network security group for all instances | `bool` | `"false"` | no |
+| [support\_access\_enabled](#input\_support\_access\_enabled) | If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true | `bool` | `true` | no |
| [target\_address](#input\_target\_address) | Azure DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses | `list(string)` | [
"185.46.212.88",
"185.46.212.89"
]
| no |
| [tls\_key\_algorithm](#input\_tls\_key\_algorithm) | algorithm for tls\_private\_key resource | `string` | `"RSA"` | no |
| [workload\_count](#input\_workload\_count) | The number of Workload VMs to deploy | `number` | `1` | no |
diff --git a/examples/base_1cc_zpa/main.tf b/examples/base_1cc_zpa/main.tf
index a0a116c..5bf4117 100755
--- a/examples/base_1cc_zpa/main.tf
+++ b/examples/base_1cc_zpa/main.tf
@@ -143,6 +143,7 @@ module "cc_vm" {
ccvm_image_offer = var.ccvm_image_offer
ccvm_image_sku = var.ccvm_image_sku
ccvm_image_version = var.ccvm_image_version
+ ccvm_source_image_id = var.ccvm_source_image_id
cc_instance_size = var.cc_instance_size
mgmt_nsg_id = module.cc_nsg.mgmt_nsg_id
service_nsg_id = module.cc_nsg.service_nsg_id
@@ -163,13 +164,14 @@ module "cc_vm" {
# created and assigned to ALL Cloud Connectors
################################################################################
module "cc_nsg" {
- source = "../../modules/terraform-zscc-nsg-azure"
- nsg_count = var.reuse_nsg == false ? var.cc_count : 1
- name_prefix = var.name_prefix
- resource_tag = random_string.suffix.result
- resource_group = module.network.resource_group_name
- location = var.arm_location
- global_tags = local.global_tags
+ source = "../../modules/terraform-zscc-nsg-azure"
+ nsg_count = var.reuse_nsg == false ? var.cc_count : 1
+ name_prefix = var.name_prefix
+ resource_tag = random_string.suffix.result
+ resource_group = module.network.resource_group_name
+ location = var.arm_location
+ global_tags = local.global_tags
+ support_access_enabled = var.support_access_enabled
}
diff --git a/examples/base_1cc_zpa/terraform.tfvars b/examples/base_1cc_zpa/terraform.tfvars
index 6c5161d..8db1740 100755
--- a/examples/base_1cc_zpa/terraform.tfvars
+++ b/examples/base_1cc_zpa/terraform.tfvars
@@ -170,11 +170,28 @@
#encryption_at_host_enabled = false
+## 21. By default, if Terraform is creating NSGs an outbound rule named Zscaler_Support_Access is configured enabling
+## Zscaler remote support access. Without this firewall access, Zscaler Support may not be able to assist as
+## efficiently if troubleshooting is required. Uncomment if you do not want to enable this rule.
+##
+## For more information, refer to: https://config.zscaler.com/zscaler.net/cloud-branch-connector and
+## https://help.zscaler.com/cloud-branch-connector/enabling-remote-access
+
+#support_access_enabled = false
+
+## 22. By default, Terraform will lookup the latest Cloud Connector image version from the Azure Marketplace.
+## Uncomment and set this value to the path of a local subscription Microsoft.Compute image to override the
+## Cloud Connector deployment with a private VHD instead of using the marketplace publisher.
+## *** This is recommended only for testing purposes and not supported for production deployments ***
+## Example: /subscriptions//resourceGroups//providers/Microsoft.Compute/images/
+
+#ccvm_source_image_id = ""
+
#####################################################################################################################
##### ZPA/Azure Private DNS specific variables #####
#####################################################################################################################
-## 21. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
+## 23. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
## Only applicable for base + zpa or zpa_enabled = true deployment types where Outbound DNS subnets, Resolver Ruleset/Rules,
## and Outbound Endpoints are being created. Two example domains are populated to show the mapping structure and syntax.
## Azure does require a trailing dot "." on all domain entries. ZPA Module will read through each to create a resolver rule per
@@ -185,7 +202,7 @@
# appseg2 = "app2.com."
#}
-## 22. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
+## 24. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
## The required expectation is that the target should follow VNet/subnet routing towards the configured Cloud Connector Load Balancer VIP for
## ZPA DNS interception
diff --git a/examples/base_1cc_zpa/variables.tf b/examples/base_1cc_zpa/variables.tf
index db3e38e..3323692 100755
--- a/examples/base_1cc_zpa/variables.tf
+++ b/examples/base_1cc_zpa/variables.tf
@@ -102,6 +102,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -127,7 +128,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -162,6 +163,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "http_probe_port" {
type = number
description = "Port number for Cloud Connector cloud init to enable listener port for HTTP probe from Azure LB"
@@ -260,3 +267,9 @@ variable "target_address" {
description = "Azure DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses"
default = ["185.46.212.88", "185.46.212.89"]
}
+
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
diff --git a/examples/base_cc_lb/README.md b/examples/base_cc_lb/README.md
index 75b2e93..73f5d34 100644
--- a/examples/base_cc_lb/README.md
+++ b/examples/base_cc_lb/README.md
@@ -99,6 +99,7 @@ From base_cc_lb directory execute:
| [ccvm\_image\_sku](#input\_ccvm\_image\_sku) | Azure Marketplace Cloud Connector Image SKU | `string` | `"zs_ser_gen1_cc_01"` | no |
| [ccvm\_image\_version](#input\_ccvm\_image\_version) | Azure Marketplace Cloud Connector Image Version | `string` | `"latest"` | no |
| [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Image size | `string` | `"Standard_D2s_v3"` | no |
+| [ccvm\_source\_image\_id](#input\_ccvm\_source\_image\_id) | Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher | `string` | `null` | no |
| [encryption\_at\_host\_enabled](#input\_encryption\_at\_host\_enabled) | User input for enabling or disabling host encryption | `bool` | `true` | no |
| [env\_subscription\_id](#input\_env\_subscription\_id) | Azure Subscription ID where resources are to be deployed in | `string` | n/a | yes |
| [environment](#input\_environment) | Customer defined environment tag. ie: Dev, QA, Prod, etc. | `string` | `"Development"` | no |
@@ -114,6 +115,7 @@ From base_cc_lb directory execute:
| [probe\_threshold](#input\_probe\_threshold) | The number of consecutive successful or failed probes in order to allow or deny traffic from being delivered to this endpoint. After failing the number of consecutive probes equal to this value, the endpoint will be taken out of rotation and require the same number of successful consecutive probes to be placed back in rotation. | `number` | `2` | no |
| [public\_subnets](#input\_public\_subnets) | Public/Bastion Subnets to create in VNet. This is only required if you want to override the default subnets that this code creates via network\_address\_space variable. | `list(string)` | `null` | no |
| [reuse\_nsg](#input\_reuse\_nsg) | Specifies whether the NSG module should create 1:1 network security groups per instance or 1 network security group for all instances | `bool` | `"false"` | no |
+| [support\_access\_enabled](#input\_support\_access\_enabled) | If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true | `bool` | `true` | no |
| [tls\_key\_algorithm](#input\_tls\_key\_algorithm) | algorithm for tls\_private\_key resource | `string` | `"RSA"` | no |
| [workload\_count](#input\_workload\_count) | The number of Workload VMs to deploy | `number` | `1` | no |
| [workloads\_subnets](#input\_workloads\_subnets) | Workload Subnets to create in VNet. This is only required if you want to override the default subnets that this code creates via network\_address\_space variable. | `list(string)` | `null` | no |
diff --git a/examples/base_cc_lb/main.tf b/examples/base_cc_lb/main.tf
index bd3dbad..ceb37fc 100755
--- a/examples/base_cc_lb/main.tf
+++ b/examples/base_cc_lb/main.tf
@@ -144,6 +144,7 @@ module "cc_vm" {
ccvm_image_offer = var.ccvm_image_offer
ccvm_image_sku = var.ccvm_image_sku
ccvm_image_version = var.ccvm_image_version
+ ccvm_source_image_id = var.ccvm_source_image_id
cc_instance_size = var.cc_instance_size
mgmt_nsg_id = module.cc_nsg.mgmt_nsg_id
service_nsg_id = module.cc_nsg.service_nsg_id
@@ -164,13 +165,14 @@ module "cc_vm" {
# created and assigned to ALL Cloud Connectors
################################################################################
module "cc_nsg" {
- source = "../../modules/terraform-zscc-nsg-azure"
- nsg_count = var.reuse_nsg == false ? var.cc_count : 1
- name_prefix = var.name_prefix
- resource_tag = random_string.suffix.result
- resource_group = module.network.resource_group_name
- location = var.arm_location
- global_tags = local.global_tags
+ source = "../../modules/terraform-zscc-nsg-azure"
+ nsg_count = var.reuse_nsg == false ? var.cc_count : 1
+ name_prefix = var.name_prefix
+ resource_tag = random_string.suffix.result
+ resource_group = module.network.resource_group_name
+ location = var.arm_location
+ global_tags = local.global_tags
+ support_access_enabled = var.support_access_enabled
}
diff --git a/examples/base_cc_lb/terraform.tfvars b/examples/base_cc_lb/terraform.tfvars
index 0af8c3f..ba06391 100755
--- a/examples/base_cc_lb/terraform.tfvars
+++ b/examples/base_cc_lb/terraform.tfvars
@@ -168,3 +168,20 @@
## Uncomment if you want to not enable this VM setting
#encryption_at_host_enabled = false
+
+## 21. By default, if Terraform is creating NSGs an outbound rule named Zscaler_Support_Access is configured enabling
+## Zscaler remote support access. Without this firewall access, Zscaler Support may not be able to assist as
+## efficiently if troubleshooting is required. Uncomment if you do not want to enable this rule.
+##
+## For more information, refer to: https://config.zscaler.com/zscaler.net/cloud-branch-connector and
+## https://help.zscaler.com/cloud-branch-connector/enabling-remote-access
+
+#support_access_enabled = false
+
+## 22. By default, Terraform will lookup the latest Cloud Connector image version from the Azure Marketplace.
+## Uncomment and set this value to the path of a local subscription Microsoft.Compute image to override the
+## Cloud Connector deployment with a private VHD instead of using the marketplace publisher.
+## *** This is recommended only for testing purposes and not supported for production deployments ***
+## Example: /subscriptions//resourceGroups//providers/Microsoft.Compute/images/
+
+#ccvm_source_image_id = ""
diff --git a/examples/base_cc_lb/variables.tf b/examples/base_cc_lb/variables.tf
index e4b762b..8a82dda 100755
--- a/examples/base_cc_lb/variables.tf
+++ b/examples/base_cc_lb/variables.tf
@@ -96,6 +96,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -121,7 +122,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -156,6 +157,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "http_probe_port" {
type = number
description = "Port number for Cloud Connector cloud init to enable listener port for HTTP probe from Azure LB"
@@ -274,3 +281,9 @@ variable "encryption_at_host_enabled" {
description = "User input for enabling or disabling host encryption"
default = true
}
+
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
diff --git a/examples/base_cc_lb_zpa/README.md b/examples/base_cc_lb_zpa/README.md
index 7d4adc8..9a7942b 100644
--- a/examples/base_cc_lb_zpa/README.md
+++ b/examples/base_cc_lb_zpa/README.md
@@ -102,6 +102,7 @@ From base_cc_lb_zpa directory execute:
| [ccvm\_image\_sku](#input\_ccvm\_image\_sku) | Azure Marketplace Cloud Connector Image SKU | `string` | `"zs_ser_gen1_cc_01"` | no |
| [ccvm\_image\_version](#input\_ccvm\_image\_version) | Azure Marketplace Cloud Connector Image Version | `string` | `"latest"` | no |
| [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Image size | `string` | `"Standard_D2s_v3"` | no |
+| [ccvm\_source\_image\_id](#input\_ccvm\_source\_image\_id) | Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher | `string` | `null` | no |
| [domain\_names](#input\_domain\_names) | Domain names fqdn/wildcard to have Azure Private DNS redirect DNS requests to Cloud Connector | `map(any)` | n/a | yes |
| [encryption\_at\_host\_enabled](#input\_encryption\_at\_host\_enabled) | User input for enabling or disabling host encryption | `bool` | `true` | no |
| [env\_subscription\_id](#input\_env\_subscription\_id) | Azure Subscription ID where resources are to be deployed in | `string` | n/a | yes |
@@ -119,6 +120,7 @@ From base_cc_lb_zpa directory execute:
| [probe\_threshold](#input\_probe\_threshold) | The number of consecutive successful or failed probes in order to allow or deny traffic from being delivered to this endpoint. After failing the number of consecutive probes equal to this value, the endpoint will be taken out of rotation and require the same number of successful consecutive probes to be placed back in rotation. | `number` | `2` | no |
| [public\_subnets](#input\_public\_subnets) | Public/Bastion Subnets to create in VNet. This is only required if you want to override the default subnets that this code creates via network\_address\_space variable. | `list(string)` | `null` | no |
| [reuse\_nsg](#input\_reuse\_nsg) | Specifies whether the NSG module should create 1:1 network security groups per instance or 1 network security group for all instances | `bool` | `"false"` | no |
+| [support\_access\_enabled](#input\_support\_access\_enabled) | If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true | `bool` | `true` | no |
| [target\_address](#input\_target\_address) | Azure DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses | `list(string)` | [
"185.46.212.88",
"185.46.212.89"
]
| no |
| [tls\_key\_algorithm](#input\_tls\_key\_algorithm) | algorithm for tls\_private\_key resource | `string` | `"RSA"` | no |
| [workload\_count](#input\_workload\_count) | The number of Workload VMs to deploy | `number` | `1` | no |
diff --git a/examples/base_cc_lb_zpa/main.tf b/examples/base_cc_lb_zpa/main.tf
index 0789327..01be2c2 100755
--- a/examples/base_cc_lb_zpa/main.tf
+++ b/examples/base_cc_lb_zpa/main.tf
@@ -146,6 +146,7 @@ module "cc_vm" {
ccvm_image_offer = var.ccvm_image_offer
ccvm_image_sku = var.ccvm_image_sku
ccvm_image_version = var.ccvm_image_version
+ ccvm_source_image_id = var.ccvm_source_image_id
cc_instance_size = var.cc_instance_size
mgmt_nsg_id = module.cc_nsg.mgmt_nsg_id
service_nsg_id = module.cc_nsg.service_nsg_id
@@ -166,13 +167,14 @@ module "cc_vm" {
# created and assigned to ALL Cloud Connectors
################################################################################
module "cc_nsg" {
- source = "../../modules/terraform-zscc-nsg-azure"
- nsg_count = var.reuse_nsg == false ? var.cc_count : 1
- name_prefix = var.name_prefix
- resource_tag = random_string.suffix.result
- resource_group = module.network.resource_group_name
- location = var.arm_location
- global_tags = local.global_tags
+ source = "../../modules/terraform-zscc-nsg-azure"
+ nsg_count = var.reuse_nsg == false ? var.cc_count : 1
+ name_prefix = var.name_prefix
+ resource_tag = random_string.suffix.result
+ resource_group = module.network.resource_group_name
+ location = var.arm_location
+ global_tags = local.global_tags
+ support_access_enabled = var.support_access_enabled
}
diff --git a/examples/base_cc_lb_zpa/terraform.tfvars b/examples/base_cc_lb_zpa/terraform.tfvars
index d7b72b0..0304431 100755
--- a/examples/base_cc_lb_zpa/terraform.tfvars
+++ b/examples/base_cc_lb_zpa/terraform.tfvars
@@ -170,11 +170,28 @@
#encryption_at_host_enabled = false
+## 21. By default, if Terraform is creating NSGs an outbound rule named Zscaler_Support_Access is configured enabling
+## Zscaler remote support access. Without this firewall access, Zscaler Support may not be able to assist as
+## efficiently if troubleshooting is required. Uncomment if you do not want to enable this rule.
+##
+## For more information, refer to: https://config.zscaler.com/zscaler.net/cloud-branch-connector and
+## https://help.zscaler.com/cloud-branch-connector/enabling-remote-access
+
+#support_access_enabled = false
+
+## 22. By default, Terraform will lookup the latest Cloud Connector image version from the Azure Marketplace.
+## Uncomment and set this value to the path of a local subscription Microsoft.Compute image to override the
+## Cloud Connector deployment with a private VHD instead of using the marketplace publisher.
+## *** This is recommended only for testing purposes and not supported for production deployments ***
+## Example: /subscriptions//resourceGroups//providers/Microsoft.Compute/images/
+
+#ccvm_source_image_id = ""
+
#####################################################################################################################
##### ZPA/Azure Private DNS specific variables #####
#####################################################################################################################
-## 21. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
+## 23. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
## Only applicable for base + zpa or zpa_enabled = true deployment types where Outbound DNS subnets, Resolver Ruleset/Rules,
## and Outbound Endpoints are being created. Two example domains are populated to show the mapping structure and syntax.
## Azure does require a trailing dot "." on all domain entries. ZPA Module will read through each to create a resolver rule per
@@ -185,7 +202,7 @@
# appseg2 = "app2.com."
#}
-## 22. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
+## 24. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
## The required expectation is that the target should follow VNet/subnet routing towards the configured Cloud Connector Load Balancer VIP for
## ZPA DNS interception
diff --git a/examples/base_cc_lb_zpa/variables.tf b/examples/base_cc_lb_zpa/variables.tf
index 2df8851..4562588 100755
--- a/examples/base_cc_lb_zpa/variables.tf
+++ b/examples/base_cc_lb_zpa/variables.tf
@@ -102,6 +102,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -127,7 +128,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -162,6 +163,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "http_probe_port" {
type = number
description = "Port number for Cloud Connector cloud init to enable listener port for HTTP probe from Azure LB"
@@ -281,6 +288,12 @@ variable "encryption_at_host_enabled" {
default = true
}
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
+
# Azure Private DNS specific variables
variable "zpa_enabled" {
diff --git a/examples/cc_lb/README.md b/examples/cc_lb/README.md
index 4cde591..b5a49e1 100644
--- a/examples/cc_lb/README.md
+++ b/examples/cc_lb/README.md
@@ -117,7 +117,8 @@ From cc_lb directory execute:
| [ccvm\_image\_sku](#input\_ccvm\_image\_sku) | Azure Marketplace Cloud Connector Image SKU | `string` | `"zs_ser_gen1_cc_01"` | no |
| [ccvm\_image\_version](#input\_ccvm\_image\_version) | Azure Marketplace Cloud Connector Image Version | `string` | `"latest"` | no |
| [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Image size | `string` | `"Standard_D2s_v3"` | no |
-| [domain\_names](#input\_domain\_names) | Domain names fqdn/wildcard to have Azure Private DNS redirect DNS requests to Cloud Connector | `map(any)` | n/a | yes |
+| [ccvm\_source\_image\_id](#input\_ccvm\_source\_image\_id) | Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher | `string` | `null` | no |
+| [domain\_names](#input\_domain\_names) | Domain names fqdn/wildcard to have Azure Private DNS redirect DNS requests to Cloud Connector | `map(any)` | `{}` | no |
| [encryption\_at\_host\_enabled](#input\_encryption\_at\_host\_enabled) | User input for enabling or disabling host encryption | `bool` | `false` | no |
| [env\_subscription\_id](#input\_env\_subscription\_id) | Azure Subscription ID where resources are to be deployed in | `string` | n/a | yes |
| [environment](#input\_environment) | Customer defined environment tag. ie: Dev, QA, Prod, etc. | `string` | `"Development"` | no |
@@ -134,11 +135,12 @@ From cc_lb directory execute:
| [private\_dns\_subnet](#input\_private\_dns\_subnet) | Private DNS Resolver Outbound Endpoint Subnet to create in VNet. This is only required if you want to override the default subnet that this code creates via network\_address\_space variable. | `string` | `null` | no |
| [probe\_threshold](#input\_probe\_threshold) | The number of consecutive successful or failed probes in order to allow or deny traffic from being delivered to this endpoint. After failing the number of consecutive probes equal to this value, the endpoint will be taken out of rotation and require the same number of successful consecutive probes to be placed back in rotation. | `number` | `2` | no |
| [reuse\_nsg](#input\_reuse\_nsg) | Specifies whether the NSG module should create 1:1 network security groups per instance or 1 network security group for all instances | `bool` | `"false"` | no |
+| [support\_access\_enabled](#input\_support\_access\_enabled) | If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true | `bool` | `true` | no |
| [target\_address](#input\_target\_address) | Azure DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses | `list(string)` | [
"185.46.212.88",
"185.46.212.89"
]
| no |
| [tls\_key\_algorithm](#input\_tls\_key\_algorithm) | algorithm for tls\_private\_key resource | `string` | `"RSA"` | no |
| [zones](#input\_zones) | Specify which availability zone(s) to deploy VM resources in if zones\_enabled variable is set to true | `list(string)` | [
"1"
]
| no |
| [zones\_enabled](#input\_zones\_enabled) | Determine whether to provision Cloud Connector VMs explicitly in defined zones (if supported by the Azure region provided in the location variable). If left false, Azure will automatically choose a zone and module will create an availability set resource instead for VM fault tolerance | `bool` | `false` | no |
-| [zpa\_enabled](#input\_zpa\_enabled) | Configure Azure Private DNS Outbound subnet, Resolvers, Rulesets/Rules, and Outbound Endpoint ZPA DNS redirection | `bool` | `true` | no |
+| [zpa\_enabled](#input\_zpa\_enabled) | Configure Azure Private DNS Outbound subnet, Resolvers, Rulesets/Rules, and Outbound Endpoint ZPA DNS redirection | `bool` | `false` | no |
## Outputs
diff --git a/examples/cc_lb/main.tf b/examples/cc_lb/main.tf
index 9aaf427..4592ee3 100755
--- a/examples/cc_lb/main.tf
+++ b/examples/cc_lb/main.tf
@@ -124,6 +124,7 @@ module "cc_vm" {
ccvm_image_offer = var.ccvm_image_offer
ccvm_image_sku = var.ccvm_image_sku
ccvm_image_version = var.ccvm_image_version
+ ccvm_source_image_id = var.ccvm_source_image_id
cc_instance_size = var.cc_instance_size
mgmt_nsg_id = module.cc_nsg.mgmt_nsg_id
service_nsg_id = module.cc_nsg.service_nsg_id
@@ -144,13 +145,14 @@ module "cc_vm" {
# created and assigned to ALL Cloud Connectors
################################################################################
module "cc_nsg" {
- source = "../../modules/terraform-zscc-nsg-azure"
- nsg_count = var.reuse_nsg == false ? var.cc_count : 1
- name_prefix = var.name_prefix
- resource_tag = random_string.suffix.result
- resource_group = var.byo_nsg == false ? module.network.resource_group_name : var.byo_nsg_rg
- location = var.arm_location
- global_tags = local.global_tags
+ source = "../../modules/terraform-zscc-nsg-azure"
+ nsg_count = var.reuse_nsg == false ? var.cc_count : 1
+ name_prefix = var.name_prefix
+ resource_tag = random_string.suffix.result
+ resource_group = var.byo_nsg == false ? module.network.resource_group_name : var.byo_nsg_rg
+ location = var.arm_location
+ global_tags = local.global_tags
+ support_access_enabled = var.support_access_enabled
byo_nsg = var.byo_nsg
# optional inputs. only required if byo_nsg set to true
diff --git a/examples/cc_lb/outputs.tf b/examples/cc_lb/outputs.tf
index 1580267..c91ff8e 100755
--- a/examples/cc_lb/outputs.tf
+++ b/examples/cc_lb/outputs.tf
@@ -32,13 +32,13 @@ All NAT GW IPs:
${join("\n", module.network.public_ip_address)}
Private DNS Resolver:
-${try(module.private_dns.private_dns_resolver_name, "")}
+${try(module.private_dns.private_dns_resolver_name, "N/A")}
Private DNS Forwarding Ruleset:
-${try(module.private_dns.private_dns_forwarding_ruleset_name, "")}
+${try(module.private_dns.private_dns_forwarding_ruleset_name, "N/A")}
Private DNS Outbound Endpoint:
-${try(module.private_dns.private_dns_outbound_endpoint_name, "")}
+${try(module.private_dns.private_dns_outbound_endpoint_name, "N/A")}
TB
}
diff --git a/examples/cc_lb/terraform.tfvars b/examples/cc_lb/terraform.tfvars
index 226d866..25f0414 100755
--- a/examples/cc_lb/terraform.tfvars
+++ b/examples/cc_lb/terraform.tfvars
@@ -122,7 +122,7 @@
## IPv4 CIDR configured with VNet creation. All Subnet resources (Workload, Public, and Cloud Connector) will be created based off this prefix
## /24 subnets are created assuming this cidr is a /16. If you require creating a VNet smaller than /16, you may need to explicitly define all other
-## subnets via public_subnets, workload_subnets, and cc_subnets variables (Default: "10.1.0.0/16")
+## subnets via cc_subnets and private_dns_subnet (only if var.zpa_enabled = true) variables (Default: "10.1.0.0/16")
## Note: This variable only applies if you let Terraform create a new VNet. Custom deployment with byo_vnet enabled will ignore this
@@ -138,8 +138,6 @@
## Default/Minumum: 1 - Maximum: 3
## Example: If you change network_address_space to "10.2.0.0/24", set below variables to cidrs that fit in that /24 like cc_subnets = ["10.2.0.0/27","10.2.0.32/27"] etc.
-#public_subnets = ["10.x.y.z/24","10.x.y.z/24"]
-#workloads_subnets = ["10.x.y.z/24","10.x.y.z/24"]
#cc_subnets = ["10.x.y.z/24","10.x.y.z/24"]
#private_dns_subnet = "10.x.y.z/28"
@@ -170,35 +168,52 @@
#encryption_at_host_enabled = false
+## 21. By default, if Terraform is creating NSGs an outbound rule named Zscaler_Support_Access is configured enabling
+## Zscaler remote support access. Without this firewall access, Zscaler Support may not be able to assist as
+## efficiently if troubleshooting is required. Uncomment if you do not want to enable this rule.
+##
+## For more information, refer to: https://config.zscaler.com/zscaler.net/cloud-branch-connector and
+## https://help.zscaler.com/cloud-branch-connector/enabling-remote-access
+
+#support_access_enabled = false
+
+## 22. By default, Terraform will lookup the latest Cloud Connector image version from the Azure Marketplace.
+## Uncomment and set this value to the path of a local subscription Microsoft.Compute image to override the
+## Cloud Connector deployment with a private VHD instead of using the marketplace publisher.
+## *** This is recommended only for testing purposes and not supported for production deployments ***
+## Example: /subscriptions//resourceGroups//providers/Microsoft.Compute/images/
+
+#ccvm_source_image_id = ""
+
#####################################################################################################################
##### Custom BYO variables. Only applicable for "cc_lb" deployment without "base" resource requirements #####
#####################################################################################################################
-## 21. By default, this script will create a new Resource Group and place all resources in this group.
+## 23. By default, this script will create a new Resource Group and place all resources in this group.
## Uncomment if you want to deploy all resources in an existing Resource Group? (true or false. Default: false)
#byo_rg = true
-## 22. Provide your existing Resource Group name. Only uncomment and modify if you set byo_rg to true
+## 24. Provide your existing Resource Group name. Only uncomment and modify if you set byo_rg to true
#byo_rg_name = "existing-rg"
-## 23. By default, this script will create a new Azure Virtual Network in the default resource group.
+## 25. By default, this script will create a new Azure Virtual Network in the default resource group.
## Uncomment if you want to deploy all resources to a VNet that already exists (true or false. Default: false)
#byo_vnet = true
-## 24. Provide your existing VNet name. Only uncomment and modify if you set byo_vnet to true
+## 26. Provide your existing VNet name. Only uncomment and modify if you set byo_vnet to true
#byo_vnet_name = "existing-vnet"
-## 25. Provide the existing Resource Group name of your VNet. Only uncomment and modify if you set byo_vnet to true
+## 27. Provide the existing Resource Group name of your VNet. Only uncomment and modify if you set byo_vnet to true
## Subnets depend on VNet so the same resource group is implied for subnets
#byo_vnet_subnets_rg_name = "existing-vnet-rg"
-## 26. By default, this script will create 1 new Azure subnet in the default resource group unles the zones variable
+## 28. By default, this script will create 1 new Azure subnet in the default resource group unles the zones variable
## specifies multiple zonal deployments in which case subnet 1 would logically map to resources in zone "1", etc.
## Uncomment if you want to deploy all resources in subnets that already exist (true or false. Default: false)
## Dependencies require in order to reference existing subnets, the corresponding VNet must also already exist.
@@ -206,7 +221,7 @@
#byo_subnets = true
-## 27. Provide your existing Cloud Connector subnet names. Only uncomment and modify if you set byo_subnets to true
+## 29. Provide your existing Cloud Connector subnet names. Only uncomment and modify if you set byo_subnets to true
## By default, management and service interfaces reside in a single subnet. Therefore, specifying multiple subnets
## implies only that you are doing a zonal deployment with resources in separate AZs and corresponding zonal NAT
## Gateway resources associated with the CC subnets mapped to the same respective zones.
@@ -215,12 +230,12 @@
#byo_subnet_names = ["existing-cc-subnet"]
-## 28. By default, this script will create new Public IP resources to be associated with CC NAT Gateways.
+## 30. By default, this script will create new Public IP resources to be associated with CC NAT Gateways.
## Uncomment if you want to use your own public IP for the NAT GW (true or false. Default: false)
#byo_pips = true
-## 29. Provide your existing Azure Public IP resource names. Only uncomment and modify if you set byo_pips to true
+## 31. Provide your existing Azure Public IP resource names. Only uncomment and modify if you set byo_pips to true
## Existing Public IP resource cannot be associated with any resource other than an existing NAT Gateway in which
## case existing_pip_association and existing_nat_gw_association need both set to true
##
@@ -231,16 +246,16 @@
#byo_pip_names = ["pip-az1","pip-az2"]
-## 30. Provide the existing Resource Group name of your Azure public IPs. Only uncomment and modify if you set byo_pips to true
+## 32. Provide the existing Resource Group name of your Azure public IPs. Only uncomment and modify if you set byo_pips to true
#byo_pip_rg = "existing-pip-rg"
-## 31. By default, this script will create new NAT Gateway resources for the Cloud Connector subnets to be associated
+## 33. By default, this script will create new NAT Gateway resources for the Cloud Connector subnets to be associated
## Uncomment if you want to use your own NAT Gateway (true or false. Default: false)
#byo_nat_gws = true
-## 32. Provide your existing Azure NAT Gateway resource names. Only uncomment and modify if you set byo_nat_gws to true
+## 34. Provide your existing Azure NAT Gateway resource names. Only uncomment and modify if you set byo_nat_gws to true
## ***** Note *****
## If you already have existing NAT Gateways AND set zone_enabled to true these resource should be configured as zonal and
## be added here to this variable list in order of the zones specified in the "zones" variable.
@@ -248,30 +263,30 @@
#byo_nat_gw_names = ["natgw-az1","natgw-az2"]
-## 33. Provide the existing Resource Group name of your NAT Gateway. Only uncomment and modify if you set byo_nat_gws to true
+## 35. Provide the existing Resource Group name of your NAT Gateway. Only uncomment and modify if you set byo_nat_gws to true
#byo_nat_gw_rg = "existing-nat-gw-rg"
-## 34. By default, this script will create a new Azure Public IP and associate it with new/existing NAT Gateways.
+## 36. By default, this script will create a new Azure Public IP and associate it with new/existing NAT Gateways.
## Uncomment if you are deploying cloud connector to an environment where the PIP already exists AND is already asssociated to
## an existing NAT Gateway. (true or false. Default: false).
## Setting existing_pip_association to true means byo_nat_gws and byo_pips must ALSO be set to true.
#existing_nat_gw_pip_association = true
-## 35. By default this script will create a new Azure NAT Gateway and associate it with new or existing CC subnets.
+## 37. By default this script will create a new Azure NAT Gateway and associate it with new or existing CC subnets.
## Uncomment if you are deploying cloud connector to an environment where the subnet already exists AND is already asssociated to
## an existing NAT Gateway. (true or false. Default: false).
## Setting existing_nat_gw_association to true means byo_subnets AND byo_nat_gws must also be set to true.
#existing_nat_gw_subnet_association = true
-## 36. By default, this script will create new Network Security Groups for the Cloud Connector mgmt and service interfaces
+## 38. By default, this script will create new Network Security Groups for the Cloud Connector mgmt and service interfaces
## Uncomment if you want to use your own NSGs (true or false. Default: false)
#byo_nsg = true
-## 37. Provide your existing Network Security Group resource names. Only uncomment and modify if you set byo_nsg to true
+## 39. Provide your existing Network Security Group resource names. Only uncomment and modify if you set byo_nsg to true
## ***** Note *****
## Example: byo_mgmt_nsg_names = ["mgmt-nsg-1","mgmt-nsg-2"]
@@ -280,7 +295,7 @@
#byo_mgmt_nsg_names = ["mgmt-nsg-1","mgmt-nsg-2"]
#byo_service_nsg_names = ["service-nsg-1","service-nsg-2"]
-## 38. Provide the existing Resource Group name of your Network Security Groups. Only uncomment and modify if you set byo_nsg to true
+## 40. Provide the existing Resource Group name of your Network Security Groups. Only uncomment and modify if you set byo_nsg to true
#byo_nsg_rg = "existing-nsg-rg"
@@ -288,7 +303,12 @@
#####################################################################################################################
##### ZPA/Azure Private DNS specific variables #####
#####################################################################################################################
-## 39. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
+## 41. By default, the terraform-zscc-private-dns-azure (Azure Private DNS for ZPA) module and dependences are not
+## configured. Uncomment and set to true to enable this module resources creation.
+
+#zpa_enabled = true
+
+## 42. Provide the domain names you want Azure Private DNS to redirect to Cloud Connector for ZPA interception.
## Only applicable for base + zpa or zpa_enabled = true deployment types where Outbound DNS subnets, Resolver Ruleset/Rules,
## and Outbound Endpoints are being created. Two example domains are populated to show the mapping structure and syntax.
## Azure does require a trailing dot "." on all domain entries. ZPA Module will read through each to create a resolver rule per
@@ -299,7 +319,7 @@
# appseg2 = "app2.com."
#}
-## 40. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
+## 43. Azure Private DNS queries will be conditionally forwarded to these target IP addresses. Default are a pair of Zscaler Global VIP addresses.
## The required expectation is that the target should follow VNet/subnet routing towards the configured Cloud Connector Load Balancer VIP for
## ZPA DNS interception
diff --git a/examples/cc_lb/variables.tf b/examples/cc_lb/variables.tf
index b2d0662..c3bd5e1 100755
--- a/examples/cc_lb/variables.tf
+++ b/examples/cc_lb/variables.tf
@@ -90,6 +90,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -115,7 +116,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -150,6 +151,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "http_probe_port" {
type = number
description = "Port number for Cloud Connector cloud init to enable listener port for HTTP probe from Azure LB"
@@ -247,17 +254,24 @@ variable "encryption_at_host_enabled" {
default = false
}
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
+
# Azure Private DNS specific variables
variable "zpa_enabled" {
type = bool
description = "Configure Azure Private DNS Outbound subnet, Resolvers, Rulesets/Rules, and Outbound Endpoint ZPA DNS redirection"
- default = true
+ default = false
}
variable "domain_names" {
type = map(any)
description = "Domain names fqdn/wildcard to have Azure Private DNS redirect DNS requests to Cloud Connector"
+ default = {}
}
variable "target_address" {
diff --git a/examples/zsec b/examples/zsec
index 75ce9fa..7cf1ce3 100755
--- a/examples/zsec
+++ b/examples/zsec
@@ -2,9 +2,18 @@
set -eo pipefail
+### SET COLOR CODES ###
+# ${CYAN}
+# ${RESET}
+RED=$(tput setaf 1)
+GREEN=$(tput setaf 2)
+YELLOW=$(tput setaf 3)
+CYAN=$(tput setaf 6)
+RESET=$(tput sgr0)
+
usage()
{
- echo "Usage: $0 "
+ echo "Usage: $0 <${GREEN}up${RESET}|${RED}destroy${RESET}>"
exit 1
}
@@ -21,59 +30,83 @@ else
esac
fi
-if [[ "$oper" == "up" ]]; then
- # shellcheck disable=SC2153
- if [ -z "$dtype" ]; then
- while true; do
- read -r -p "Deployment: ( greenfield | brownfield ): " deploy
-
- case $deploy in
- greenfield)
- echo ""
- echo "**Caution** These deployments include test workloads and publicly accessible jump hosts and are intended primarily for lab/test environments"
- echo ""
- break
- ;;
- brownfield)
- break
- ;;
- *)
- echo "Invalid Deployment Type: ${dtype}"
- ;;
- esac
- done
-
- while [ "$deploy" == "greenfield" ]; do
- read -r -p "Deployment Type: ( base | base_1cc | base_1cc_zpa | base_cc_lb | base_cc_lb_zpa ) : " dtype
- case $dtype in
- base|base_1cc|base_1cc_zpa|base_cc_lb|base_cc_lb_zpa)
- echo "Deployment Type: ${dtype}"
- break
- ;;
- *)
- echo "Invalid Deployment Type: ${dtype}"
- ;;
- esac
- done
-
- while [ "$deploy" == "brownfield" ]; do
- read -r -p "Deployment Type: ( cc_lb ) : " dtype
+if [[ "$oper" == "up" ]]; then
+ PS3="${CYAN}Select desired deployment: ${RESET}"
+ deployments=("greenfield - Recommended for isolated test/POV deployments. Creates new network infrastructure, test workloads, and a public jump host" "brownfield - Recommended for prod deployments. Bring-your-own existing network infrastructure customizations + no workload/bastion creation")
+ select deployment in "${deployments[@]}"
+ do
+ case $REPLY in
+ 1)
+ echo "Greenfield deployment selected..."
+ echo "${YELLOW}**Caution** These deployments include test workloads and publicly accessible jump hosts and are intended primarily for lab/test environments${RESET}"
+ echo ""
+ deployment=greenfield
+ break
+ ;;
+ 2)
+ echo "Brownfield deployment selected..."
+ deployemt=brownfield
+ break
+ ;;
+ *)
+ echo "${RED}invalid response${RESET}"
+ esac
+ done
+fi
- case $dtype in
- cc_lb)
- echo "Deployment Type: ${dtype}"
- break
- ;;
- *)
- echo "Invalid Deployment Type: ${dtype}"
- ;;
- esac
- done
-
- else
- dtype=$dtype
- fi
+if [[ "$deployment" == "greenfield" ]]; then
+ PS3="${CYAN}Select desired deployment type: ${RESET}"
+ dtypes=("Deploy 1 Cloud Connector in a new Resource Group and VNet" "Deploy 1 Cloud Connector in a new Resource Group and VNet w/ Private DNS for ZPA" "Deploy multiple Cloud Connectors w/ Load Balancer in a new Resource Group and VNet" "Deploy multiple Cloud Connectors w/ Load Balancer in a new Resource Group and VNet w/ Private DNS for ZPA" "Deploy a new Resource Group and VNet only - No Cloud Connector" )
+ select greenfield_type in "${dtypes[@]}"
+ do
+ case $REPLY in
+ 1)
+ echo "Deployment type base_1cc selected..."
+ dtype=base_1cc
+ break
+ ;;
+ 2)
+ echo "Deployment type base_1cc_zpa selected..."
+ dtype=base_1cc_zpa
+ break
+ ;;
+ 3)
+ echo "Deployment type base_cc_lb selected..."
+ dtype=base_cc_lb
+ break
+ ;;
+ 4)
+ echo "Deployment type base_cc_lb_zpa selected..."
+ dtype=base_cc_lb_zpa
+ break
+ ;;
+ 5)
+ echo "Deployment type base selected..."
+ dtype=base
+ break
+ ;;
+ *)
+ echo "${RED}invalid response${RESET}"
+ esac
+ done
+elif [[ "$deployment" == "brownfield" ]]; then
+ PS3="${CYAN}Select desired deployment type: ${RESET}"
+ dtypes=("Deploy multiple Cloud Connectors w/ Load Balancer in a new or existing Resource Group and VNet" )
+ select greenfield_type in "${dtypes[@]}"
+ do
+ case $REPLY in
+ 1)
+ echo "Deployment type cc_lb selected..."
+ dtype=cc_lb
+ break
+ ;;
+ *)
+ echo "${RED}invalid response${RESET}"
+ esac
+ done
+else
+ dtype=$dtype
fi
echo "Discovering processor architecture..."
@@ -100,45 +133,53 @@ elif [[ "$OSTYPE" == "freebsd"* ]]; then
echo "FreeBSD support coming soon..."
exit 1
else
- echo "Unsupported OS: $OSTYPE"
+ echo "${RED}Unsupported OS: $OSTYPE${RESET}"
exit 1
fi
-echo "OS is $ostype"
+echo "${GREEN}OS is $ostype${RESET}"
dir=bin
echo "Creating a local $dir directory if not present..."
if [[ ! -e $dir ]]; then
mkdir $dir
elif [[ ! -d $dir ]]; then
- echo "$dir already exists but is not a directory" 1>&2
+ echo "${RED}$dir already exists but is not a directory${RESET}" 1>&2
exit 1
fi
-az_regions=["westus","West US","westus2","West US 2","eastus","East US","centralus","Central US","centraluseuap","Central US EUAP","southcentralus","South Central US","northcentralus","North Central US","westcentralus","West Central US","eastus2","East US 2","eastus2euap","East US 2 EUAP","brazilsouth","Brazil South","northeurope","North Europe","westeurope","West Europe","eastasia","East Asia","southeastasia","Southeast Asia","japanwest","Japan West","japaneast","Japan East","koreacentral","Korea Central","koreasouth","Korea South","southindia","South India","westindia","West India","centralindia","Central India","australiaeast","Australia East","australiasoutheast","Australia Southeast","canadacentral","Canada Central","canadaeast","Canada East","uksouth","UK South","ukwest","UK West","francecentral","France Central","francesouth","France South","australiacentral","Australia Central","australiacentral2","Australia Central 2","uaecentral","UAE Central","uaenorth","UAE North","southafricanorth"," South Africa North","southafricawest","South Africa West","switzerlandnorth","Switzerland North","switzerlandwest","Switzerland West","germanynorth","Germany North","germanywestcentral","Germany West Central","norwayeast","Norway East","norwaywest","Norway West","brazilsoutheast","Brazil Southeast","westus3","West US 3","swedencentral","Sweden Central","swedensouth","Sweden South"]
+az_regions=["westus","West US","westus2","West US 2","eastus","East US","centralus","Central US","centraluseuap","Central US EUAP","southcentralus","South Central US","northcentralus","North Central US","westcentralus","West Central US","eastus2","East US 2","eastus2euap","East US 2 EUAP","brazilsouth","Brazil South","northeurope","North Europe","westeurope","West Europe","eastasia","East Asia","southeastasia","Southeast Asia","japanwest","Japan West","japaneast","Japan East","koreacentral","Korea Central","koreasouth","Korea South","southindia","South India","westindia","West India","centralindia","Central India","australiaeast","Australia East","australiasoutheast","Australia Southeast","canadacentral","Canada Central","canadaeast","Canada East","uksouth","UK South","ukwest","UK West","francecentral","France Central","francesouth","France South","australiacentral","Australia Central","australiacentral2","Australia Central 2","uaecentral","UAE Central","uaenorth","UAE North","southafricanorth"," South Africa North","southafricawest","South Africa West","switzerlandnorth","Switzerland North","switzerlandwest","Switzerland West","germanynorth","Germany North","germanywestcentral","Germany West Central","norwayeast","Norway East","norwaywest","Norway West","brazilsoutheast","Brazil Southeast","westus3","West US 3","swedencentral","Sweden Central","swedensouth","Sweden South","chinaeast","China East","ChinaEast","chinaeast2","China East 2","ChinaEast2","chinanorth","China North","ChinaNorth","chinanorth2","China North 2","ChinaNorth2","chinanorth3","China North 3","ChinaNorth3"]
# if .zsecrc is not present we'll assume that Azure env was never set
if [[ $dtype == "base" && ! -e ./.zsecrc ]]; then
echo "Checking Azure Environment Variables..."
- read -r -p "Enter Azure Subcription ID: " azure_subscription_id
+ read -r -p "${CYAN}Enter Azure Subcription ID: ${RESET}" azure_subscription_id
echo "export ARM_SUBSCRIPTION_ID=${azure_subscription_id}" > .zsecrc
echo "export TF_VAR_env_subscription_id=${azure_subscription_id}" >> .zsecrc
- read -r -p "Enter Directory (tenant) ID: " azure_tenant_id
+ read -r -p "${CYAN}Enter Directory (tenant) ID: ${RESET}" azure_tenant_id
echo "export ARM_TENANT_ID=${azure_tenant_id}" >> .zsecrc
- read -r -p "Enter Application (client) ID of Service Principal: " azure_client_id
+ read -r -p "${CYAN}Enter Application (client) ID of Service Principal: ${RESET}" azure_client_id
echo "export ARM_CLIENT_ID=${azure_client_id}" >> .zsecrc
- read -r -p "Enter Client Secret Value of Service Principal: " azure_client_secret
+ read -r -p "${CYAN}Enter Client Secret Value of Service Principal: ${RESET}" azure_client_secret
echo "export ARM_CLIENT_SECRET=${azure_client_secret}" >> .zsecrc
- read -r -p "Enter Azure Region (e.g. westus2): " azure_location
+ read -r -p "${CYAN}Enter Azure Region (e.g. westus2): ${RESET}" azure_location
if [[ ${az_regions[*]} =~ $azure_location ]]; then
- echo "export TF_VAR_arm_location=${azure_location}" >> .zsecrc
+ echo "export TF_VAR_arm_location='$azure_location'" >> .zsecrc
+ # Convert the user input to lowercase for case-insensitive comparison
+ azure_location=$(echo "$azure_location" | tr '[:upper:]' '[:lower:]')
+ if [[ ${azure_location} = "china"* ]]; then
+ echo "${YELLOW} China region detected. Setting ARM_ENVIRONMENT...${RESET}"
+ echo "export ARM_ENVIRONMENT=china" >> .zsecrc
+ echo "export ARM_SKIP_PROVIDER_REGISTRATION=true" >> .zsecrc
+ fi
else
- echo "Invalid Azure region name entered."
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid Azure region name entered${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
+
while [[ "$dtype" == "base" && "$oper" == "up" ]]; do
clientpublicip=$(curl -s ifconfig.me)
echo "greenfield deployments include a publicly accessible ssh bastion host.."
- read -r -p "Your current public IP is ${clientpublicip}. Lock SSH access to this IP? [yes/no] " bastion_response
+ read -r -p "${CYAN}Your current public IP is ${clientpublicip}. Lock SSH access to this IP? [yes/no]: ${RESET}" bastion_response
case $bastion_response in
yes|y )
echo "Updating Bastion NSG to permit SSH only from ${clientpublicip}: "
@@ -156,27 +197,27 @@ done
if [[ "$useclientip" == "false" ]]; then
while true; do
-read -r -p "Lock SSH access to a different IP address or range? Default is open [yes/no]: " changebastionip
+read -r -p "${CYAN}Lock SSH access to a different IP address or range? Default is open [yes/no]: ${RESET}" changebastionip
case $changebastionip in
yes|y )
- read -r -p "Enter new IP Address or CIDR range (e.g. 2.2.2.2/32): " bastionipinput
+ read -r -p "${CYAN}Enter new IP Address or CIDR range (e.g. 2.2.2.2/32): ${RESET}" bastionipinput
echo "export TF_VAR_bastion_nsg_source_prefix=${bastionipinput}" >> .zsecrc
if [[ $bastionipinput =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[1-9]))$ ]]
then
echo "$bastionipinput - IP/Netmask valid"
else
- echo "$bastionipinput is not valid IP CIDR format"
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}$bastionipinput is not valid IP CIDR format${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
break
;;
no|n )
- echo "SSH access permitted for all IP addresses..."
+ echo "${YELLOW}**Caution** SSH access permitted for all IP addresses...${RESET}"
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
fi
@@ -185,28 +226,37 @@ fi
echo "Checking Azure Environment Variables and Cloud Connector bootstrap requirements... For ZPA or custom/byo deployments, please stop and refer to the README and terraform.tfvars file instructions"
# if .zsecrc is not present we'll assume that Azure env was never set
if [[ ! -e ./.zsecrc ]]; then
- read -r -p "Enter Azure Subcription ID: " azure_subscription_id
+ read -r -p "${CYAN}Enter Azure Subcription ID: ${RESET}" azure_subscription_id
echo "export ARM_SUBSCRIPTION_ID=${azure_subscription_id}" > .zsecrc
echo "export TF_VAR_env_subscription_id=${azure_subscription_id}" >> .zsecrc
- read -r -p "Enter Directory (tenant) ID: " azure_tenant_id
+ read -r -p "${CYAN}Enter Directory (tenant) ID: ${RESET}" azure_tenant_id
echo "export ARM_TENANT_ID=${azure_tenant_id}" >> .zsecrc
- read -r -p "Enter Application (client) ID of Service Principal: " azure_client_id
+ read -r -p "${CYAN}Enter Application (client) ID of Service Principal: ${RESET}" azure_client_id
echo "export ARM_CLIENT_ID=${azure_client_id}" >> .zsecrc
- read -r -p "Enter Client Secret Value of Service Principal: " azure_client_secret
+ read -r -p "${CYAN}Enter Client Secret Value of Service Principal: ${RESET}" azure_client_secret
echo "export ARM_CLIENT_SECRET=${azure_client_secret}" >> .zsecrc
- read -r -p "Enter Azure Region (e.g. westus2): " azure_location
+ read -r -p "${CYAN}Enter Azure Region (e.g. westus2): ${RESET}" azure_location
if [[ ${az_regions[*]} =~ $azure_location ]]; then
- echo "export TF_VAR_arm_location='${azure_location}'" >> .zsecrc
+ echo "export TF_VAR_arm_location='$azure_location'" >> .zsecrc
+ # Convert the user input to lowercase for case-insensitive comparison
+ azure_location=$(echo "$azure_location" | tr '[:upper:]' '[:lower:]')
+ if [[ ${azure_location} = "china"* ]]; then
+ echo "${YELLOW}Azure China region detected. Setting ARM_ENVIRONMENT...${RESET}"
+ echo "export ARM_ENVIRONMENT=china" >> .zsecrc
+ echo "export ARM_SKIP_PROVIDER_REGISTRATION=true" >> .zsecrc
+ read -r -p "${CYAN}Enter full Source Image ID path for your CC image (e.g. /subscriptions//resourceGroups//providers/Microsoft.Compute/images/): ${RESET}" ccvm_source_image_id
+ echo "export TF_VAR_ccvm_source_image_id='$ccvm_source_image_id'" >> .zsecrc
+ fi
else
- echo "Invalid Azure region name entered."
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid Azure region name entered${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
while [[ "$dtype" == "base"* && "$oper" == "up" ]]; do
clientpublicip=$(curl -s ifconfig.me)
echo "greenfield deployments include a publicly accessible ssh bastion host.."
- read -r -p "Your current public IP is ${clientpublicip}. Lock SSH access to this IP? [yes/no] " bastion_response
+ read -r -p "${CYAN}Your current public IP is ${clientpublicip}. Lock SSH access to this IP? [yes/no]: ${RESET}" bastion_response
case $bastion_response in
yes|y )
echo "Updating Bastion NSG to permit SSH only from ${clientpublicip}: "
@@ -218,33 +268,33 @@ case $bastion_response in
useclientip=false
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
if [[ "$useclientip" == "false" ]]; then
while true; do
-read -r -p "Lock SSH access to a different IP address or range? Default is open [yes/no]: " changebastionip
+read -r -p "${CYAN}Lock SSH access to a different IP address or range? Default is open [yes/no]: ${RESET}" changebastionip
case $changebastionip in
yes|y )
- read -r -p "Enter new IP Address or CIDR range (e.g. 2.2.2.2/32): " bastionipinput
+ read -r -p "${CYAN}Enter new IP Address or CIDR range (e.g. 2.2.2.2/32): ${RESET}" bastionipinput
echo "export TF_VAR_bastion_nsg_source_prefix=${bastionipinput}" >> .zsecrc
if [[ $bastionipinput =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[1-9]))$ ]]
then
echo "$bastionipinput - IP/Netmask valid"
else
- echo "$bastionipinput is not valid IP CIDR format"
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}$bastionipinput is not valid IP CIDR format${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
break
;;
no|n )
- echo "SSH access permitted for all IP addresses..."
+ echo "${YELLOW}**Caution** SSH access permitted for all IP addresses...${RESET}"
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
fi
@@ -254,50 +304,53 @@ fi
encryption_at_host_enabled=true
# Sourcing .zsecrc to use credentials during execution
source .zsecrc
+ if grep -q "export ARM_ENVIRONMENT=china" .zsecrc; then
+ TOKEN_ENDPOINT="https://login.partner.microsoftonline.cn/${ARM_TENANT_ID}/oauth2/token"
+ RESOURCE="https://management.chinacloudapi.cn"
+ else
+ TOKEN_ENDPOINT="https://login.microsoftonline.com/${ARM_TENANT_ID}/oauth2/token"
+ RESOURCE="https://management.azure.com/"
+ fi
while true; do
- read -r -p "Do you want to enable the Azure host encryption feature? [Default setting is Yes]: " input
+ read -r -p "${CYAN}Do you want to enable the Azure host encryption feature? [Default setting is Yes]: ${RESET}" input
# Convert the user input to lowercase for case-insensitive comparison
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
if [[ "$input" == "no" || "$input" == "n" ]]; then
- echo "Setting encryption_at_host_enabled to false..."
+ echo "${YELLOW}**Caution** Setting encryption_at_host_enabled to false...${RESET}"
encryption_at_host_enabled=false
break
- elif [[ "$input" == "yes" || "$input" == "y" || -z "$input" ]]; then
+ elif [[ "$input" == "yes" || "$input" == "y" || -z "$input" ]]; then
echo "Checking if EncryptionAtHost feature is enabled for subscription $ARM_SUBSCRIPTION_ID..."
-
- TOKEN_ENDPOINT="https://login.microsoftonline.com/${ARM_TENANT_ID}/oauth2/token"
- RESOURCE="https://management.azure.com/"
ACCESS_TOKEN=$(curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${ARM_CLIENT_ID}" \
-d "client_secret=${ARM_CLIENT_SECRET}" \
-d "resource=${RESOURCE}" \
"${TOKEN_ENDPOINT}" | grep -o '"access_token":"[^"]*' | awk -F'"' '{print $4}')
-
+
response=$(curl -s -X GET -H "Authorization: Bearer ${ACCESS_TOKEN}" \
- "https://management.azure.com/subscriptions/$ARM_SUBSCRIPTION_ID/providers/Microsoft.Features/providers/Microsoft.Compute/features/EncryptionAtHost?api-version=2021-07-01" \
+ "$RESOURCE/subscriptions/$ARM_SUBSCRIPTION_ID/providers/Microsoft.Features/providers/Microsoft.Compute/features/EncryptionAtHost?api-version=2021-07-01" \
|grep -o '"state":"[^"]*' | awk -F'"' '{print $4}')
if [ "$response" = "Registered" ]; then
- echo "EncryptionAtHost feature is enabled for subscription $ARM_SUBSCRIPTION_ID..."
echo "Setting encryption_at_host_enabled to true..."
encryption_at_host_enabled=true
else
- echo "Error: Azure Subscription $ARM_SUBSCRIPTION_ID is not registered to support host encryption. Please refer to documentation."
+ echo "${RED}Error: Azure Subscription $ARM_SUBSCRIPTION_ID is not registered to support host encryption. Please refer to documentation.${RESET}"
exit 1
fi
break
else
- echo "Invalid input. Please enter 'yes' or 'no'."
+ echo "${RED}Invalid input. Please enter 'yes' or 'no'.${RESET}"
fi
done
- echo "export TF_VAR_encryption_at_host_enabled=${encryption_at_host_enabled}" >> .zsecrc
- # End of Host Encryption support update
- # ---
+echo "export TF_VAR_encryption_at_host_enabled=${encryption_at_host_enabled}" >> .zsecrc
+# End of Host Encryption support update
+# ---
cc_instance_size=small
@@ -316,98 +369,105 @@ fi
# ;;
# esac
-ccvm_instance_type_default=Standard_D2s_v3
-while true; do
- read -r -p "Enter desired Azure VM type for CC. Recommended types: Small CC (Standard_D2s_v3) [Default=$ccvm_instance_type_default]: " ccvm_instance_type_input
-ccvm_instance_type=${ccvm_instance_type_input:-$ccvm_instance_type_default}
-case $ccvm_instance_type in
- Standard_D2s_v3|Standard_DS3_v2|Standard_D8s_v3|Standard_D16s_v3|Standard_DS5_v2 )
- echo "Cloud Connector VM type: ${ccvm_instance_type}"
- echo "export TF_VAR_ccvm_instance_type=${ccvm_instance_type}" >> .zsecrc
- break
- ;;
- *)
- echo "Invalid Cloud Connector VM type: ${ccvm_instance_type}. Please enter an approved VM type"
- esac
-done
-small_cc_instance=("Standard_D2s_v3" "Standard_DS3_v2" "Standard_D8s_v3" "Standard_D16s_v3" "Standard_DS5_v2")
-medium_cc_instance=("Standard_D8s_v3" "Standard_DS3_v2" "Standard_D16s_v3" "Standard_DS5_v2")
-large_cc_instance=("Standard_D16s_v3" "Standard_DS5_v2")
-
-if [[ ${small_cc_instance[*]} =~ $ccvm_instance_type && "$cc_instance_size" == small ]]; then
-echo "Proceeding. ${ccvm_instance_type} compatible with ${cc_instance_size} Cloud Connector size"
-elif [[ ${medium_cc_instance[*]} =~ $ccvm_instance_type && "$cc_instance_size" == medium ]]; then
-echo "Proceeding. ${ccvm_instance_type} compatible with ${cc_instance_size} Cloud Connector size"
-elif [[ ${large_cc_instance[*]} =~ $ccvm_instance_type && "$cc_instance_size" == large ]]; then
-echo "Proceeding. ${ccvm_instance_type} compatible with ${cc_instance_size} Cloud Connector size"
-elif [[ $dtype == base ]]; then
-echo "Proceeding with no CCs to deploy"
+
+if [[ $cc_instance_size == "small" ]]; then
+ PS3="${CYAN}Select desired Azure VM type for Cloud Connector: ${RESET}"
+ if [[ "$azure_location" == "chinanorth" || "$azure_location" == "China North" || "$azure_location" == "ChinaNorth" || "$azure_location" == "chinaeast" || "$azure_location" == "China East" || "$azure_location" == "ChinaEast" ]]; then
+ vm_sizes=("Standard_DS2_v2" "Standard_DS3_v2")
+ else
+ vm_sizes=("Standard_D2s_v3")
+ fi
+ select ccvm_instance_type in "${vm_sizes[@]}"
+ do
+ case $ccvm_instance_type in
+ Standard_D2s_v3)
+ echo "Cloud Connector VM type $ccvm_instance_type selected"
+ echo "export TF_VAR_ccvm_instance_type='$ccvm_instance_type'" >> .zsecrc
+ break
+ ;;
+ Standard_DS2_v2)
+ echo "Cloud Connector VM type $ccvm_instance_type selected"
+ echo "export TF_VAR_ccvm_instance_type='$ccvm_instance_type'" >> .zsecrc
+ break
+ ;;
+ Standard_DS3_v2)
+ echo "Cloud Connector VM type $ccvm_instance_type selected"
+ echo "export TF_VAR_ccvm_instance_type='$ccvm_instance_type'" >> .zsecrc
+ break
+ ;;
+ *)
+ echo "${RED}invalid response${RESET}"
+ esac
+ done
+elif [[ $cc_instance_size == "medium" ]]; then
+ echo ""
+elif [[ $cc_instance_size == "large" ]]; then
+ echo ""
else
- echo "Invalid CC deployment. ${ccvm_instance_type} not compatible with ${cc_instance_size} Cloud Connector size"
- echo "Delete .zsecrc file and re-run zsec up..."
exit 1
fi
- read -r -p "Enter CC Provisioning URL (E.g. connector.zscaler.net/api/v1/provUrl?name=azure_prov_url): " cc_vm_prov_url
- echo "Provisioning URL entered is: $cc_vm_prov_url. Make sure this matches the CC Instance Size $cc_instance_size chosen."
+
+ read -r -p "${CYAN}Enter CC Provisioning URL${RESET} (E.g. connector.zscaler.net/api/v1/provUrl?name=azure_prov_url): " cc_vm_prov_url
+ echo "Provisioning URL entered is: $cc_vm_prov_url. ${YELLOW}Make sure this matches the CC Instance Size $cc_instance_size chosen${RESET}"
echo "export TF_VAR_cc_vm_prov_url=${cc_vm_prov_url}" >> .zsecrc
- read -r -p "Enter Azure Key Vault URL (E.g https://zscaler-cc-demo.vault.azure.net): " azure_vault_url
+ read -r -p "${CYAN}Enter Azure Key Vault URL${RESET} (E.g https://zscaler-cc-demo.vault.azure.net): " azure_vault_url
echo "Key Vault URL entered is: $azure_vault_url"
echo "export TF_VAR_azure_vault_url=${azure_vault_url}" >> .zsecrc
http_probe_port_default=50000
- read -r -p "Enter CC service health probe TCP port number. Valid input = 80 or any number between 1024-65535 [Default=$http_probe_port_default]: " http_probe_port_input
+ read -r -p "${CYAN}Enter CC service health probe TCP port number. Valid input = 80 or any number between 1024-65535 [Default=$http_probe_port_default]: ${RESET}" http_probe_port_input
http_probe_port=${http_probe_port_input:-$http_probe_port_default}
if ((http_probe_port == 80 || http_probe_port >= 1024 && http_probe_port <= 65535)); then
- echo "Valid HTTP probe port input of $http_probe_port"
+ echo "${GREEN}Valid HTTP probe port input of $http_probe_port${RESET}"
echo "export TF_VAR_http_probe_port=${http_probe_port}" >> .zsecrc
else
- echo "Invalid HTTP probe port value"
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid HTTP probe port value${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
echo "Cloud Connector User Managed Identity Information:"
while true; do
- read -r -p "Is the Managed Identity in the same Subscription ID? [yes/no] " response
+ read -r -p "${CYAN}Is the Managed Identity in the same Subscription ID? [yes/no]: ${RESET}" response
case $response in
yes|y )
echo "Managed Identity is in the same Subscription"
break
;;
no|n )
- read -r -p "Enter Subscription ID of Managed Identity: " managed_identity_subscription_id
+ read -r -p "${CYAN}Enter Subscription ID of Managed Identity: ${RESET}" managed_identity_subscription_id
echo "export TF_VAR_managed_identity_subscription_id=${managed_identity_subscription_id}" >> .zsecrc
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
- read -r -p "Enter Managed Identity Name: " cc_vm_managed_identity_name
+ read -r -p "${CYAN}Enter Managed Identity Name: ${RESET}" cc_vm_managed_identity_name
echo "export TF_VAR_cc_vm_managed_identity_name=${cc_vm_managed_identity_name}" >> .zsecrc
- read -r -p "Enter Managed Identity Resource Group: " cc_vm_managed_identity_rg
+ read -r -p "${CYAN}Enter Managed Identity Resource Group: ${RESET}" cc_vm_managed_identity_rg
echo "export TF_VAR_cc_vm_managed_identity_rg=${cc_vm_managed_identity_rg}" >> .zsecrc
cc_count_default=2
if [[ "$dtype" == *"lb"* ]]; then
- read -r -p "Enter how many Cloud Connectors to deploy? [Default=$cc_count_default]: " cc_count_input
+ read -r -p "${CYAN}Enter how many Cloud Connectors to deploy? [Default=$cc_count_default]: ${RESET}" cc_count_input
cc_count=${cc_count_input:-$cc_count_default}
if ((cc_count >= 1 && cc_count <= 20)); then
echo "${dtype} will deploy ${cc_count} Cloud Connector in ${azure_location}"
echo "export TF_VAR_cc_count=${cc_count}" >> .zsecrc
else
- echo "invalid cc_count value. Must be a number between 1 and 20"
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}invalid cc_count value. Must be a number between 1 and 20${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
elif [[ "$dtype" == "base_1cc" ]]; then
echo "${dtype} will deploy one Cloud Connector in ${azure_location}"
fi
-az_supported_regions=["australiaeast","Australia East","brazilsouth","Brazil South","canadacentral","Canada Central","centralindia","Central India","centralus","Central US","eastasia","East Asia","eastus","East US","francecentral","France Central","germanywestcentral","Germany West Central","japaneast","Japan East","koreacentral","Korea Central","northeurope","North Europe","norwayeast","Norway East","southafricanorth","South Africa North","southcentralus","South Central US","southeastasia","Southeast Asia","swedencentral","Sweden Central","uksouth","UK South","westeurope","West Europe","westus2","West US 2","westus3","West US 3"]
+az_supported_regions=["australiaeast","Australia East","brazilsouth","Brazil South","canadacentral","Canada Central","centralindia","Central India","centralus","Central US","eastasia","East Asia","eastus","East US","francecentral","France Central","germanywestcentral","Germany West Central","japaneast","Japan East","koreacentral","Korea Central","northeurope","North Europe","norwayeast","Norway East","southafricanorth","South Africa North","southcentralus","South Central US","southeastasia","Southeast Asia","swedencentral","Sweden Central","uksouth","UK South","westeurope","West Europe","westus2","West US 2","westus3","West US 3","chinanorth3","China North 3","ChinaNorth3"]
if [[ ${az_supported_regions[*]} =~ $azure_location ]]; then
-echo "Azure region ${azure_location} supports Zones..."
+echo "${GREEN}Azure region ${azure_location} supports Zones...${RESET}"
zones_enabled_default=no
while true; do
- read -r -p "Deploy Cloud Connectors in dedicated Availability Zones/subnets? (Enter yes or no) [Default=$zones_enabled_default]: " zones_enabled_input
+ read -r -p "${CYAN}Deploy Cloud Connectors in dedicated Availability Zones/subnets? (Enter yes or no) [Default=$zones_enabled_default]: ${RESET}" zones_enabled_input
zones_enabled=${zones_enabled_input:-$zones_enabled_default}
case $zones_enabled in
yes|y )
@@ -416,10 +476,10 @@ case $zones_enabled in
;;
no|n )
echo "export TF_VAR_zones_enabled=false" >> .zsecrc
- echo "No zones defined. Proceeding with availability sets fault tolerance..."
+ echo "${YELLOW}**Caution** No zones defined. Proceeding with availability sets fault tolerance...${RESET}"
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
@@ -428,7 +488,7 @@ if [[ "$zones_enabled" == "yes" || "$zones_enabled" == "y" ]]; then
echo "Choose zones [1-3] to deploy in... "
echo "If deploying only one Cloud Connector, enter yes for only one Zone (1, 2, or 3)"
while true; do
- read -r -p "Zone 1 (yes/no): " zone1_response
+ read -r -p "${CYAN}Zone 1 (yes/no): ${RESET}" zone1_response
case $zone1_response in
yes|y )
echo "Availability Zone 1 selected"
@@ -439,11 +499,11 @@ case $zone1_response in
zone1_use=false
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
while true; do
- read -r -p "Zone 2 (yes/no): " zone2_response
+ read -r -p "${CYAN}Zone 2 (yes/no): ${RESET}" zone2_response
case $zone2_response in
yes|y )
echo "Availability Zone 2 selected"
@@ -454,11 +514,11 @@ case $zone2_response in
zone2_use=false
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
while true; do
- read -r -p "Zone 3 (yes/no): " zone3_response
+ read -r -p "${CYAN}Zone 3 (yes/no): ${RESET}" zone3_response
case $zone3_response in
yes|y )
echo "Availability Zone 3 selected"
@@ -469,7 +529,7 @@ case $zone3_response in
zone3_use=false
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
if [[ "$zone1_use" == "true" && "$zone2_use" == "false" && "$zone3_use" == "false" ]]; then
@@ -494,18 +554,18 @@ elif [[ "$zone1_use" == "false" && "$zone2_use" == "true" && "$zone3_use" == "tr
echo "Zones selected: 2 and 3"
echo "export TF_VAR_zones='[\"2\", \"3\"]'" >> .zsecrc
else
- echo "Invalid Zones selection. exiting..."
- echo "Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid Zones selection. exiting...${RESET}"
+ echo "${YELLOW}Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
fi
else
-echo "Azure region ${azure_location} does not support Zones. Proceeding..."
+echo "${YELLOW}Azure region ${azure_location} does not support Zones. Proceeding...${RESET}"
fi
if [[ "$dtype" == "cc"* ]]; then
while true; do
- read -r -p "Enable Azure Private DNS for ZPA? (yes/no): " zpa_response
+ read -r -p "${CYAN}Enable Azure Private DNS for ZPA? (yes/no): ${RESET}" zpa_response
case $zpa_response in
yes|y )
echo "Enabling Azure Private DNS module..."
@@ -519,7 +579,7 @@ case $zpa_response in
echo "export TF_VAR_zpa_enabled=$zpa_enabled" >> .zsecrc
break
;;
- * ) echo "invalid response. Please enter yes or no";;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
esac
done
fi
@@ -529,34 +589,34 @@ array=()
domain_names_map="'{ "
counter=0
while true; do
-read -r -p "How many Domain/FQDN application segments to add to Private DNS Resolver Rules? " domain_number
+read -r -p "${CYAN}How many Domain/FQDN application segments to add to Private DNS Resolver Rules?: ${RESET}" domain_number
if [[ $domain_number == 0 ]]; then
- echo "Invalid input. Please enter a whole number for the number of domains you will be adding..."
+ echo "${RED}Invalid input. Please enter a whole number for the number of domains you will be adding...${RESET}"
elif [[ $domain_number =~ ^[0-9]+$ ]]; then
echo "$domain_number domains to enter..."
break
else
- echo "Invalid input. Please enter a whole number for the number of domains you will be adding..."
+ echo "${RED}Invalid input. Please enter a whole number for the number of domains you will be adding...${RESET}"
fi
done
for i in $(seq $domain_number); do
-read -r -p "Enter a single ZPA Domain/FQDN ending with a trailing dot ( e.g. azure.company.com. ): " domain_name
+read -r -p "${CYAN}Enter a single ZPA Domain/FQDN ending with a trailing dot${RESET} ( e.g. azure.company.com. ): " domain_name
if [[ $domain_name = *" "* ]]; then
- echo "Spaces not allowed. Please enter only one domain at a time. Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Spaces not allowed. Please enter only one domain at a time. Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
elif [[ $domain_name == '' ]]; then
- echo "Empty entries are not allowed. Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Empty entries are not allowed. Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
elif [[ $domain_name == "." ]]; then
- echo "You entered '.' dot. While Azure does support this to forward all domain requests, this could have unintended consequences/compatibility issues with Azure services"
+ echo "${YELLOW}You entered '.' dot. While Azure does support this to forward all domain requests, this could have unintended consequences/compatibility issues with Azure services${RESET}"
elif [[ $domain_name == "."* ]]; then
- echo "Invalid format. Domains cannot start with a dot (.). Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid format. Domains cannot start with a dot (.). Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
elif [[ $domain_name == "*"* ]]; then
- echo "Invalid format. Domains cannot start with a star/wildcard (*). Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid format. Domains cannot start with a star/wildcard (*). Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
elif [[ $domain_name != *"." ]]; then
- echo "Invalid format. Domains must end with a dot (.). Delete .zsecrc file and re-run zsec up..."
+ echo "${RED}Invalid format. Domains must end with a dot (.). Delete .zsecrc file and re-run zsec up...${RESET}"
exit 1
fi
array+=("$domain_name")
@@ -567,6 +627,26 @@ domain_names_map+="}'"
echo "export TF_VAR_domain_names=$domain_names_map" >> .zsecrc
fi
+support_access_response_default="no"
+while true; do
+ read -r -p "${CYAN}By default, an outbound NSG rule is configured enabling Zscaler remote support access. Would you like to disable this rule creation? [Default=$support_access_response_default]: ${RESET}" support_access_response_input
+ support_access_response=${support_access_response_input:-$support_access_response_default}
+ case $support_access_response in
+ yes|y )
+ echo "Outbound rule Zscaler_Support_Access will not be created"
+ echo "${YELLOW}*** Caution: Zscaler Support may not be able to assist as efficiently if troubleshooting is required without this access${RESET}"
+ echo "export TF_VAR_support_access_enabled=false" >> .zsecrc
+ break
+ ;;
+ no|n )
+ echo "Outbound rule Zscaler_Support_Access will be created"
+ echo "export TF_VAR_support_access_enabled=true" >> .zsecrc
+ break
+ ;;
+ * ) echo "${RED}invalid response. Please enter yes or no${RESET}";;
+ esac
+done
+
fi
@@ -577,7 +657,7 @@ fi
# add deployment type to .zsecrc for future runs
if [[ "$oper" == "up" ]]; then
- echo "Updating .zsecrc with dtype of $dtype"
+ echo "${GREEN}Updating .zsecrc with dtype of $dtype${RESET}"
sed -i'' -e '/dtype/d' .zsecrc
echo "export dtype=${dtype}" >> .zsecrc
fi
@@ -587,14 +667,14 @@ fi
# check for valid environment variables in .zsecrc
if [ -z "$ARM_CLIENT_ID" ] || [ -z "$ARM_CLIENT_SECRET" ] || [ -z "$ARM_SUBSCRIPTION_ID" ] || [ -z "$ARM_TENANT_ID" ] || [ -z "$TF_VAR_arm_location" ]; then
- echo "Azure Access info is missing. Remove .zsecrc file and rerun $0 $1"
+ echo "${RED}Azure Access info is missing. Remove .zsecrc file and rerun $0 $1${RESET}"
exit 1
fi
if [[ $dtype != "base" ]]; then
echo "Checking Cloud Connector provisioning info"
if [ -z "$TF_VAR_cc_vm_prov_url" ] || [ -z "$TF_VAR_azure_vault_url" ] || [ -z "$TF_VAR_http_probe_port" ] || [ -z "$TF_VAR_cc_instance_size" ] || [ -z "$TF_VAR_ccvm_instance_type" ] || [ -z "$TF_VAR_cc_vm_managed_identity_name" ] || [ -z "$TF_VAR_cc_vm_managed_identity_rg" ]; then
- echo "Cloud Connector provisioning info is missing. Remove .zsecrc file and rerun $0 $1"
+ echo "${RED}Cloud Connector provisioning info is missing. Remove .zsecrc file and rerun $0 $1${RESET}"
exit 1
fi
fi
@@ -612,7 +692,7 @@ if [[ "$oper" == "do" ]]; then
fi
if [[ "$oper" == "up" ]]; then
- echo "Bringing up Cloud Connector cluster..."
+ echo "${GREEN}Bringing up Cloud Connector cluster...${RESET}"
TF_DATA_DIR=../.terraform ./$dir/terraform -chdir="$dtype" init
if [[ "$AUTO_APPROVE" ]]; then
TF_DATA_DIR=../.terraform ./$dir/terraform -chdir="$dtype" apply -auto-approve
@@ -621,14 +701,14 @@ if [[ "$oper" == "up" ]]; then
fi
elif [[ "$oper" == "destroy" ]]; then
- echo "Destroying Cloud Connector cluster..."
+ echo "${GREEN}Destroying Cloud Connector cluster...${RESET}"
TF_DATA_DIR=../.terraform ./$dir/terraform -chdir="$dtype" init
if [[ "$AUTO_APPROVE" ]]; then
TF_DATA_DIR=../.terraform ./$dir/terraform -chdir="$dtype" destroy -auto-approve
else
TF_DATA_DIR=../.terraform ./$dir/terraform -chdir="$dtype" destroy
fi
- echo "Removing Terraform files and directories..."
+ echo "${GREEN}Removing Terraform files and directories...${RESET}"
rm -rf bin
rm -rf **/.terraform/* && rm -rf **/.terraform*
find . -type f -name '.terraform.lock.hcl' -delete
@@ -639,7 +719,7 @@ elif [[ "$oper" == "destroy" ]]; then
rm -rf systems.json setup-*.tar
rm -rf **/errorlog.txt
now=$(date +'%Y-%m-%d-%H_%M_%S')
- echo "archiving .zsecrc file to .zsecrc-${now}"
+ echo "${GREEN}archiving .zsecrc file to .zsecrc-${now}${RESET}"
cp .zsecrc .zsecrc-${now}
rm -rf .zsecrc && rm -rf .zsecrc.bak
fi
diff --git a/modules/terraform-zscc-bastion-azure/README.md b/modules/terraform-zscc-bastion-azure/README.md
index ad2100e..1d3ada1 100644
--- a/modules/terraform-zscc-bastion-azure/README.md
+++ b/modules/terraform-zscc-bastion-azure/README.md
@@ -9,6 +9,7 @@ This module creates all Azure VM, NSG, and Public IP resources needed to deploy
|------|---------|
| [terraform](#requirement\_terraform) | >= 0.13.7, < 2.0.0 |
| [azurerm](#requirement\_azurerm) | >= 3.46, <= 3.74 |
+| [local](#requirement\_local) | ~> 2.2.0 |
## Providers
diff --git a/modules/terraform-zscc-bastion-azure/main.tf b/modules/terraform-zscc-bastion-azure/main.tf
index 6cc7f77..f51ad69 100755
--- a/modules/terraform-zscc-bastion-azure/main.tf
+++ b/modules/terraform-zscc-bastion-azure/main.tf
@@ -68,7 +68,7 @@ resource "azurerm_linux_virtual_machine" "bastion_vm" {
location = var.location
resource_group_name = var.resource_group
network_interface_ids = [azurerm_network_interface.bastion_nic.id]
- size = var.instance_size
+ size = contains(local.unsupported_regions, lower(var.location)) ? "Standard_A3" : var.instance_size
admin_username = var.server_admin_username
computer_name = "${var.name_prefix}-bastion-${var.resource_tag}"
admin_ssh_key {
@@ -78,7 +78,7 @@ resource "azurerm_linux_virtual_machine" "bastion_vm" {
os_disk {
caching = "ReadWrite"
- storage_account_type = "Premium_LRS"
+ storage_account_type = contains(local.unsupported_regions, lower(var.location)) ? "Standard_LRS" : "Premium_LRS"
}
source_image_reference {
diff --git a/modules/terraform-zscc-bastion-azure/variables.tf b/modules/terraform-zscc-bastion-azure/variables.tf
index 9cad19e..c832394 100755
--- a/modules/terraform-zscc-bastion-azure/variables.tf
+++ b/modules/terraform-zscc-bastion-azure/variables.tf
@@ -48,6 +48,10 @@ variable "instance_size" {
default = "Standard_B1s"
}
+locals {
+ unsupported_regions = ["chinanorth", "chinaeast", "china east", "china north"]
+}
+
variable "instance_image_publisher" {
type = string
description = "The Bastion Host CentOS image publisher"
diff --git a/modules/terraform-zscc-bastion-azure/versions.tf b/modules/terraform-zscc-bastion-azure/versions.tf
index 903cd9b..e0382c5 100755
--- a/modules/terraform-zscc-bastion-azure/versions.tf
+++ b/modules/terraform-zscc-bastion-azure/versions.tf
@@ -4,6 +4,10 @@ terraform {
source = "hashicorp/azurerm"
version = ">= 3.46, <= 3.74"
}
+ local = {
+ source = "hashicorp/local"
+ version = "~> 2.2.0"
+ }
}
required_version = ">= 0.13.7, < 2.0.0"
}
diff --git a/modules/terraform-zscc-ccvm-azure/README.md b/modules/terraform-zscc-ccvm-azure/README.md
index cc8504e..bd2ce47 100644
--- a/modules/terraform-zscc-ccvm-azure/README.md
+++ b/modules/terraform-zscc-ccvm-azure/README.md
@@ -69,6 +69,7 @@ No modules.
| [ccvm\_image\_sku](#input\_ccvm\_image\_sku) | Azure Marketplace Cloud Connector Image SKU | `string` | `"zs_ser_gen1_cc_01"` | no |
| [ccvm\_image\_version](#input\_ccvm\_image\_version) | Azure Marketplace Cloud Connector Image Version | `string` | `"latest"` | no |
| [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Image size | `string` | `"Standard_D2s_v3"` | no |
+| [ccvm\_source\_image\_id](#input\_ccvm\_source\_image\_id) | Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher | `string` | `null` | no |
| [encryption\_at\_host\_enabled](#input\_encryption\_at\_host\_enabled) | User input for enabling or disabling host encryption | `bool` | `true` | no |
| [global\_tags](#input\_global\_tags) | Populate any custom user defined tags from a map | `map(string)` | `{}` | no |
| [lb\_association\_enabled](#input\_lb\_association\_enabled) | Determines whether or not to create a nic backend pool assocation to the service nic(s) | `bool` | `false` | no |
diff --git a/modules/terraform-zscc-ccvm-azure/main.tf b/modules/terraform-zscc-ccvm-azure/main.tf
index e4d12b5..646f157 100755
--- a/modules/terraform-zscc-ccvm-azure/main.tf
+++ b/modules/terraform-zscc-ccvm-azure/main.tf
@@ -229,19 +229,29 @@ resource "azurerm_linux_virtual_machine" "cc_vm" {
storage_account_type = "Premium_LRS"
}
- source_image_reference {
- publisher = var.ccvm_image_publisher
- offer = var.ccvm_image_offer
- sku = var.ccvm_image_sku
- version = var.ccvm_image_version
+ dynamic "source_image_reference" {
+ for_each = var.ccvm_source_image_id == null ? [var.ccvm_image_publisher] : []
+
+ content {
+ publisher = var.ccvm_image_publisher
+ offer = var.ccvm_image_offer
+ sku = var.ccvm_image_sku
+ version = var.ccvm_image_version
+ }
}
- plan {
- publisher = var.ccvm_image_publisher
- name = var.ccvm_image_sku
- product = var.ccvm_image_offer
+ dynamic "plan" {
+ for_each = var.ccvm_source_image_id == null ? [var.ccvm_image_publisher] : []
+
+ content {
+ publisher = var.ccvm_image_publisher
+ name = var.ccvm_image_sku
+ product = var.ccvm_image_offer
+ }
}
+ source_image_id = var.ccvm_source_image_id != null ? var.ccvm_source_image_id : null
+
identity {
type = "UserAssigned"
identity_ids = [var.managed_identity_id]
diff --git a/modules/terraform-zscc-ccvm-azure/variables.tf b/modules/terraform-zscc-ccvm-azure/variables.tf
index c05ca52..4e645aa 100755
--- a/modules/terraform-zscc-ccvm-azure/variables.tf
+++ b/modules/terraform-zscc-ccvm-azure/variables.tf
@@ -56,6 +56,7 @@ variable "ccvm_instance_type" {
validation {
condition = (
var.ccvm_instance_type == "Standard_D2s_v3" ||
+ var.ccvm_instance_type == "Standard_DS2_v2" ||
var.ccvm_instance_type == "Standard_DS3_v2" ||
var.ccvm_instance_type == "Standard_D8s_v3" ||
var.ccvm_instance_type == "Standard_D16s_v3" ||
@@ -81,7 +82,7 @@ variable "cc_instance_size" {
# Validation to determine if the selected Azure VM type and CC VM size is compatible
locals {
- small_cc_instance = ["Standard_D2s_v3", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
+ small_cc_instance = ["Standard_D2s_v3", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
medium_cc_instance = ["Standard_DS3_v2", "Standard_D8s_v3", "Standard_D16s_v3", "Standard_DS5_v2"]
large_cc_instance = ["Standard_D16s_v3", "Standard_DS5_v2"]
@@ -121,6 +122,12 @@ variable "ccvm_image_version" {
default = "latest"
}
+variable "ccvm_source_image_id" {
+ type = string
+ description = "Custom Cloud Connector Source Image ID. Set this value to the path of a local subscription Microsoft.Compute image to override the Cloud Connector deployment instead of using the marketplace publisher"
+ default = null
+}
+
variable "cc_count" {
type = number
description = "The number of Cloud Connectors to deploy. Validation assumes max for /24 subnet but could be smaller or larger as long as subnet can accommodate"
@@ -145,7 +152,7 @@ variable "backend_address_pool" {
# Validation to determine if Azure Region selected supports availabilty zones if desired
locals {
- az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3"]
+ az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3", "chinanorth3", "China North 3", "ChinaNorth3"]
zones_supported = (
contains(local.az_supported_regions, var.location) && var.zones_enabled == true
)
diff --git a/modules/terraform-zscc-lb-azure/variables.tf b/modules/terraform-zscc-lb-azure/variables.tf
index 87d39f8..a129090 100755
--- a/modules/terraform-zscc-lb-azure/variables.tf
+++ b/modules/terraform-zscc-lb-azure/variables.tf
@@ -60,7 +60,7 @@ variable "load_distribution" {
# Validation to determine if Azure Region selected supports availabilty zones if desired
locals {
- az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3"]
+ az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3", "chinanorth3", "China North 3", "ChinaNorth3"]
zones_supported = (
contains(local.az_supported_regions, var.location) && var.zones_enabled == true
)
diff --git a/modules/terraform-zscc-network-azure/variables.tf b/modules/terraform-zscc-network-azure/variables.tf
index 48e2f37..24f1ee8 100755
--- a/modules/terraform-zscc-network-azure/variables.tf
+++ b/modules/terraform-zscc-network-azure/variables.tf
@@ -53,7 +53,7 @@ variable "private_dns_subnet" {
# Validation to determine if Azure Region selected supports availabilty zones if desired
locals {
- az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3"]
+ az_supported_regions = ["australiaeast", "Australia East", "brazilsouth", "Brazil South", "canadacentral", "Canada Central", "centralindia", "Central India", "centralus", "Central US", "eastasia", "East Asia", "eastus", "East US", "francecentral", "France Central", "germanywestcentral", "Germany West Central", "japaneast", "Japan East", "koreacentral", "Korea Central", "northeurope", "North Europe", "norwayeast", "Norway East", "southafricanorth", "South Africa North", "southcentralus", "South Central US", "southeastasia", "Southeast Asia", "swedencentral", "Sweden Central", "uksouth", "UK South", "westeurope", "West Europe", "westus2", "West US 2", "westus3", "West US 3", "chinanorth3", "China North 3", "ChinaNorth3"]
zones_supported = (
contains(local.az_supported_regions, var.location) && var.zones_enabled == true
)
diff --git a/modules/terraform-zscc-nsg-azure/README.md b/modules/terraform-zscc-nsg-azure/README.md
index 46f8148..db1a3e5 100644
--- a/modules/terraform-zscc-nsg-azure/README.md
+++ b/modules/terraform-zscc-nsg-azure/README.md
@@ -42,6 +42,7 @@ No modules.
| [nsg\_count](#input\_nsg\_count) | Default number of network security groups to create | `number` | `1` | no |
| [resource\_group](#input\_resource\_group) | Main Resource Group Name | `string` | n/a | yes |
| [resource\_tag](#input\_resource\_tag) | A tag to associate to all the NSG module resources | `string` | `null` | no |
+| [support\_access\_enabled](#input\_support\_access\_enabled) | If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true | `bool` | `true` | no |
## Outputs
diff --git a/modules/terraform-zscc-nsg-azure/main.tf b/modules/terraform-zscc-nsg-azure/main.tf
index 0a2a293..d0e9510 100755
--- a/modules/terraform-zscc-nsg-azure/main.tf
+++ b/modules/terraform-zscc-nsg-azure/main.tf
@@ -31,6 +31,23 @@ resource "azurerm_network_security_group" "cc_mgmt_nsg" {
destination_address_prefix = "*"
}
+ dynamic "security_rule" {
+ for_each = var.support_access_enabled ? ["1"] : []
+
+ content {
+ name = "Zscaler_Support_Access"
+ description = "Required for Cloud Connector to establish connectivity for Zscaler Support to remotely assist"
+ priority = 3000
+ direction = "Outbound"
+ access = "Allow"
+ protocol = "Tcp"
+ source_port_range = "*"
+ destination_port_range = "12002"
+ source_address_prefix = "*"
+ destination_address_prefix = "199.168.148.101"
+ }
+ }
+
security_rule {
name = "OUTBOUND"
priority = 4000
diff --git a/modules/terraform-zscc-nsg-azure/variables.tf b/modules/terraform-zscc-nsg-azure/variables.tf
index 67de470..b9a1537 100755
--- a/modules/terraform-zscc-nsg-azure/variables.tf
+++ b/modules/terraform-zscc-nsg-azure/variables.tf
@@ -49,3 +49,9 @@ variable "byo_service_nsg_names" {
description = "Service Network Security Group ID for Cloud Connector association"
default = null
}
+
+variable "support_access_enabled" {
+ type = bool
+ description = "If Network Security Group is being configured, enable a specific outbound rule for Cloud Connector to be able to establish connectivity for Zscaler support access. Default is true"
+ default = true
+}
diff --git a/modules/terraform-zscc-workload-azure/README.md b/modules/terraform-zscc-workload-azure/README.md
index 630b68e..ed9ac52 100644
--- a/modules/terraform-zscc-workload-azure/README.md
+++ b/modules/terraform-zscc-workload-azure/README.md
@@ -9,6 +9,7 @@ This module creates all Azure VM and NSG resources needed to deploy test workloa
|------|---------|
| [terraform](#requirement\_terraform) | >= 0.13.7, < 2.0.0 |
| [azurerm](#requirement\_azurerm) | >= 3.46, <= 3.74 |
+| [local](#requirement\_local) | ~> 2.2.0 |
## Providers
diff --git a/modules/terraform-zscc-workload-azure/main.tf b/modules/terraform-zscc-workload-azure/main.tf
index b92cd36..dba66b6 100755
--- a/modules/terraform-zscc-workload-azure/main.tf
+++ b/modules/terraform-zscc-workload-azure/main.tf
@@ -84,7 +84,7 @@ resource "azurerm_linux_virtual_machine" "workload_vm" {
resource_group_name = var.resource_group
network_interface_ids = [azurerm_network_interface.workload_nic[count.index].id]
- size = var.instance_size
+ size = contains(local.unsupported_regions, lower(var.location)) ? "Standard_A3" : var.instance_size
admin_username = var.server_admin_username
computer_name = "${var.name_prefix}-workload-${count.index + 1}-${var.resource_tag}"
admin_ssh_key {
@@ -94,7 +94,7 @@ resource "azurerm_linux_virtual_machine" "workload_vm" {
os_disk {
caching = "ReadWrite"
- storage_account_type = "Premium_LRS"
+ storage_account_type = contains(local.unsupported_regions, lower(var.location)) ? "Standard_LRS" : "Premium_LRS"
}
source_image_reference {
diff --git a/modules/terraform-zscc-workload-azure/variables.tf b/modules/terraform-zscc-workload-azure/variables.tf
index 57716d3..9748e3b 100755
--- a/modules/terraform-zscc-workload-azure/variables.tf
+++ b/modules/terraform-zscc-workload-azure/variables.tf
@@ -48,6 +48,10 @@ variable "instance_size" {
default = "Standard_B1s"
}
+locals {
+ unsupported_regions = ["chinanorth", "chinaeast", "china east", "china north"]
+}
+
variable "instance_image_publisher" {
type = string
description = "The workload CentOS image publisher"
diff --git a/modules/terraform-zscc-workload-azure/versions.tf b/modules/terraform-zscc-workload-azure/versions.tf
index 903cd9b..e0382c5 100755
--- a/modules/terraform-zscc-workload-azure/versions.tf
+++ b/modules/terraform-zscc-workload-azure/versions.tf
@@ -4,6 +4,10 @@ terraform {
source = "hashicorp/azurerm"
version = ">= 3.46, <= 3.74"
}
+ local = {
+ source = "hashicorp/local"
+ version = "~> 2.2.0"
+ }
}
required_version = ">= 0.13.7, < 2.0.0"
}