Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HashiCorp Vault support #16

Merged
merged 8 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
## 0.2.0 (UNRELEASED)
FEATURES:
* Official support for HashiCorp Vault for secrets storage as an alternative to GCP Secret Manager
- add: variables hcp_vault_enabled, hcp_vault_address, hcp_vault_secret_path, hcp_vault_role_name, hcp_vault_port, and hcp_vault_ips
- **Dependency:** Requires new GCP Compute version (TBD)

ENHANCEMENTS:
* Module changes:
- terraform-zscc-network-gcp
- add pre-defined firewall rule for egress tcp/8200 to HashiCorp Vault (if that secrets storage option is selected)
- terraform-zscc-iam-service-account-gcp
- add google_service_account_iam_member.iam_token_creator resource for SA role dependency if HCP Vault with GCP Auth Method is utilized
- add variable byo_ccvm_service_account for flexibility in providing and reference an existing Service Account ID rather than Terraform creating a new one
- terraform-zscc-ilb-gcp
- add explicit backend balancing_mode to "CONNECTION" as required for Passthrough Network ILB since a default empty/null value changed to UTILIZATION which is not supported
* add: zsec prompts for HashiCorp Vault selection and byo service account
* refactor: gcp provider bump to 6.13.0


## v0.1.2 (January 20, 2024)
ENHANCEMENTS:
* terraform-zscc-iam-service-account-gcp module customization support
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ cloud (VPC). The [examples](examples/) directory contains complete automation sc
The GCP Terraform scripts leverage Terraform v1.1.9 which includes full binary and provider support for macOS M1 chips, but any Terraform
version 0.13.7 should be generally supported.

- provider registry.terraform.io/hashicorp/google v5.11.x
- provider registry.terraform.io/hashicorp/google v6.13.x
- provider registry.terraform.io/hashicorp/random v3.3.x
- provider registry.terraform.io/hashicorp/local v2.2.x
- provider registry.terraform.io/hashicorp/null v3.1.x
Expand All @@ -35,7 +35,7 @@ version 0.13.7 should be generally supported.

### Zscaler requirements
4. A valid Zscaler Cloud Connector provisioning URL generated from the Cloud Connector Portal
5. Zscaler Cloud Connector Credentials (api key, username, password) are stored in GCP Secrets Manager
5. Zscaler Cloud Connector Credentials (api key, username, password) are stored in GCP Secret Manager or HashiCorp Vault

### **Terraform client requirements**
6. If executing Terraform via the "zsec" wrapper bash script, it is advised that you run from a MacOS or Linux workstation. Minimum installed application requirements to successfully from the script are:
Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

### Zscaler requirements
4. A valid Zscaler Cloud Connector provisioning URL generated from the Cloud Connector Portal
5. Zscaler Cloud Connector Credentials (api key, username, password) are stored in GCP Secrets Manager
5. Zscaler Cloud Connector Credentials (api key, username, password) are stored in GCP Secret Manager or HashiCorp Vault

### **Terraform client requirements**
6. If executing Terraform via the "zsec" wrapper bash script, it is advised that you run from a MacOS or Linux workstation. Minimum installed application requirements to successfully from the script are:
Expand Down
15 changes: 12 additions & 3 deletions examples/base_1cc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ From base_1cc directory execute:
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.7, < 2.0.0 |
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 5.11.0 |
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 6.13.0 |
| <a name="requirement_local"></a> [local](#requirement\_local) | ~> 2.2.0 |
| <a name="requirement_null"></a> [null](#requirement\_null) | ~> 3.1.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | ~> 3.3.0 |
Expand All @@ -51,7 +51,7 @@ From base_1cc directory execute:

| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | ~> 5.11.0 |
| <a name="provider_google"></a> [google](#provider\_google) | ~> 6.13.0 |
| <a name="provider_local"></a> [local](#provider\_local) | ~> 2.2.0 |
| <a name="provider_random"></a> [random](#provider\_random) | ~> 3.3.0 |
| <a name="provider_tls"></a> [tls](#provider\_tls) | ~> 3.4.0 |
Expand Down Expand Up @@ -87,14 +87,23 @@ From base_1cc directory execute:
| <a name="input_az_count"></a> [az\_count](#input\_az\_count) | Default number zonal instance groups to create based on availability zone | `number` | `1` | no |
| <a name="input_base_instance_name"></a> [base\_instance\_name](#input\_base\_instance\_name) | The base instance name to use for instances in this group. The value must be a valid RFC1035 name. Supported characters are lowercase letters, numbers, and hyphens (-). Instances are named by appending a hyphen and a random four-character string to the base instance name | `list(string)` | <pre>[<br> ""<br>]</pre> | no |
| <a name="input_bastion_ssh_allow_ip"></a> [bastion\_ssh\_allow\_ip](#input\_bastion\_ssh\_allow\_ip) | CIDR blocks of trusted networks for bastion host ssh access from Internet | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
| <a name="input_byo_ccvm_service_account"></a> [byo\_ccvm\_service\_account](#input\_byo\_ccvm\_service\_account) | "Customer provided existing Service Account ID. If set, module will use this instead of trying to create a new one<br> - The name of the service account within the project (e.g. my-service)<br> - The fully-qualified path to a service account resource (e.g. projects/my-project/serviceAccounts/...)<br> - The email address of the service account (e.g. [email protected])" | `string` | `""` | no |
| <a name="input_cc_count"></a> [cc\_count](#input\_cc\_count) | Default number of Cloud Connector appliances to create per Instance Group/Availability Zone | `number` | `1` | no |
| <a name="input_cc_vm_prov_url"></a> [cc\_vm\_prov\_url](#input\_cc\_vm\_prov\_url) | Zscaler Cloud Connector Provisioning URL | `string` | n/a | yes |
| <a name="input_ccvm_instance_type"></a> [ccvm\_instance\_type](#input\_ccvm\_instance\_type) | Cloud Connector Instance Type | `string` | `"n2-standard-2"` | no |
| <a name="input_credentials"></a> [credentials](#input\_credentials) | Path to the service account json file for terraform to authenticate to Google Cloud | `string` | n/a | yes |
| <a name="input_default_nsg"></a> [default\_nsg](#input\_default\_nsg) | Default CIDR list to permit workload traffic destined for Cloud Connector | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
| <a name="input_fw_cc_mgmt_hcp_vault_address_name"></a> [fw\_cc\_mgmt\_hcp\_vault\_address\_name](#input\_fw\_cc\_mgmt\_hcp\_vault\_address\_name) | The name of the compute firewall created on the user defined Cloud Connector Management VPC Network permitting CC to access to HCP Vault Address port number | `string` | `null` | no |
| <a name="input_fw_cc_mgmt_ssh_ingress_name"></a> [fw\_cc\_mgmt\_ssh\_ingress\_name](#input\_fw\_cc\_mgmt\_ssh\_ingress\_name) | The name of the compute firewall created on the user defined Cloud Connector Management VPC Network permitting SSH inbound from the VPC CIDR range by default | `string` | `null` | no |
| <a name="input_fw_cc_mgmt_zssupport_tunnel_name"></a> [fw\_cc\_mgmt\_zssupport\_tunnel\_name](#input\_fw\_cc\_mgmt\_zssupport\_tunnel\_name) | The name of the compute firewall created on the user defined Cloud Connector Management VPC Network permitting CC to establish zssupport tunnel | `string` | `null` | no |
| <a name="input_fw_cc_service_default_name"></a> [fw\_cc\_service\_default\_name](#input\_fw\_cc\_service\_default\_name) | The name of the compute firewall created on the user defined Cloud Connector Service VPC Network permitting workload traffic to be sent to Zscaler | `string` | `null` | no |
| <a name="input_hcp_gcp_auth_role_type"></a> [hcp\_gcp\_auth\_role\_type](#input\_hcp\_gcp\_auth\_role\_type) | Customer managed HashiCorp Vault GCP Auth Method | `string` | `"gcp_iam"` | no |
| <a name="input_hcp_vault_address"></a> [hcp\_vault\_address](#input\_hcp\_vault\_address) | Customer managed HashiCorp Vault URL; including leading https (if applicable) and trailing port number | `string` | `""` | no |
| <a name="input_hcp_vault_enabled"></a> [hcp\_vault\_enabled](#input\_hcp\_vault\_enabled) | True/False used to determine specific HCP Vault configured network firewall and Service Account IAM roles. Default is false | `bool` | `false` | no |
| <a name="input_hcp_vault_ips"></a> [hcp\_vault\_ips](#input\_hcp\_vault\_ips) | Default CIDR list to permit Cloud Connector traffic destined for customer defined HCP Vault address(es) | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
| <a name="input_hcp_vault_port"></a> [hcp\_vault\_port](#input\_hcp\_vault\_port) | Default TCP Port Number for customer defined HCP Vault address(es) | `string` | `"8200"` | no |
| <a name="input_hcp_vault_role_name"></a> [hcp\_vault\_role\_name](#input\_hcp\_vault\_role\_name) | Customer managed HashiCorp Role Name | `string` | `""` | no |
| <a name="input_hcp_vault_secret_path"></a> [hcp\_vault\_secret\_path](#input\_hcp\_vault\_secret\_path) | Customer managed HashiCorp Vault secret path. The path to a secret is formed from three parts: <namespace>/<engine mount point>/<path to secret>. If you are not using the enterprise version of Vault, you should omit the first part | `string` | `""` | no |
| <a name="input_http_probe_port"></a> [http\_probe\_port](#input\_http\_probe\_port) | Port number for Cloud Connector cloud init to enable listener port for HTTP probe from GCP LB | `number` | `50000` | no |
| <a name="input_image_name"></a> [image\_name](#input\_image\_name) | Custom image name to be used for deploying Cloud Connector appliances. Ideally all VMs should be on the same Image as templates always pull the latest from Google Marketplace. This variable is provided if a customer desires to override/retain an old ami for existing deployments rather than upgrading and forcing a replacement. It is also inputted as a list to facilitate if a customer desired to manually upgrade select CCs deployed based on the cc\_count index | `string` | `""` | no |
| <a name="input_instance_group_name"></a> [instance\_group\_name](#input\_instance\_group\_name) | The name of the Instance Group Manager. Must be 1-63 characters long and comply with RFC1035. Supported characters include lowercase letters, numbers, and hyphens | `list(string)` | <pre>[<br> ""<br>]</pre> | no |
Expand All @@ -104,7 +113,7 @@ From base_1cc directory execute:
| <a name="input_project"></a> [project](#input\_project) | Google Cloud project name | `string` | n/a | yes |
| <a name="input_project_host"></a> [project\_host](#input\_project\_host) | Google Cloud Host Project name. Defaults to null. This variable is intended for environments where different resources might exist in separate host and service projects | `string` | `null` | no |
| <a name="input_region"></a> [region](#input\_region) | Google Cloud region | `string` | n/a | yes |
| <a name="input_secret_name"></a> [secret\_name](#input\_secret\_name) | Google Cloud Secret Name in Secret Manager | `string` | n/a | yes |
| <a name="input_secret_name"></a> [secret\_name](#input\_secret\_name) | GCP Secret Manager friendly name. Not required if using HashiCorp Vault | `string` | `""` | no |
| <a name="input_service_account_display_name"></a> [service\_account\_display\_name](#input\_service\_account\_display\_name) | Custom Service Account display name string for Cloud Connector | `string` | `null` | no |
| <a name="input_service_account_id"></a> [service\_account\_id](#input\_service\_account\_id) | Custom Service Account ID string for Cloud Connector | `string` | `null` | no |
| <a name="input_subnet_bastion"></a> [subnet\_bastion](#input\_subnet\_bastion) | A subnet IP CIDR for the greenfield/test bastion host in the Management VPC | `string` | `"10.0.0.0/24"` | no |
Expand Down
61 changes: 51 additions & 10 deletions examples/base_1cc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ module "network" {
allowed_ssh_from_internal_cidr = [var.subnet_cc_mgmt, var.subnet_bastion]
allowed_ports = var.allowed_ports

hcp_vault_enabled = var.hcp_vault_enabled
hcp_vault_ips = var.hcp_vault_ips
hcp_vault_port = var.hcp_vault_port

subnet_workload = var.subnet_workload
subnet_bastion = var.subnet_bastion
subnet_cc_mgmt = var.subnet_cc_mgmt
Expand All @@ -49,9 +53,12 @@ module "network" {
bastion_enabled = true
support_access_enabled = var.support_access_enabled

fw_cc_mgmt_ssh_ingress_name = var.fw_cc_mgmt_ssh_ingress_name
fw_cc_service_default_name = var.fw_cc_service_default_name
fw_cc_mgmt_zssupport_tunnel_name = var.fw_cc_mgmt_zssupport_tunnel_name
## Optional: Custom Firewall Rule Names. If not specified and conditions are met for rule
## creation, then names will be auto generated with pre-defined values
fw_cc_mgmt_ssh_ingress_name = var.fw_cc_mgmt_ssh_ingress_name
fw_cc_service_default_name = var.fw_cc_service_default_name
fw_cc_mgmt_zssupport_tunnel_name = var.fw_cc_mgmt_zssupport_tunnel_name
fw_cc_mgmt_hcp_vault_address_name = var.fw_cc_mgmt_hcp_vault_address_name
}


Expand Down Expand Up @@ -102,18 +109,42 @@ resource "google_compute_route" "route_to_cc_vm" {
################################################################################
# Create the user_data file with necessary bootstrap variables for Cloud Connector registration
locals {
# Populate potential locals map with HCP Vault variables
hcpuserdata = <<USERDATA
{
"cc_url": "${var.cc_vm_prov_url}",
"http_probe_port": ${var.http_probe_port},
"hcp_vault_addr": "${var.hcp_vault_address}",
"hcp_vault_secret_path": "${var.hcp_vault_secret_path}",
"hcp_vault_role_name": "${var.hcp_vault_role_name}",
"hcp_gcp_auth_role_type": "${var.hcp_gcp_auth_role_type}",
"gcp_service_account": "${module.iam_service_account.service_account}"
}
USERDATA

# Populate potential local map with default GCP Secret Manager
userdata = <<USERDATA
{"cc_url": "${var.cc_vm_prov_url}", "secret_name": "${var.secret_name}", "http_probe_port": ${var.http_probe_port}}
{
"cc_url": "${var.cc_vm_prov_url}",
"secret_name": "${var.secret_name}",
"http_probe_port": ${var.http_probe_port},
"gcp_service_account": "${module.iam_service_account.service_account}"
}
USERDATA

# if hcp_vault_enabled is true use hcpuserdata; else use standard userdata
userdata_selected = var.hcp_vault_enabled ? local.hcpuserdata : local.userdata
}

# Write the file to local filesystem for storage/reference

# Write the file to local filesystem for storage/reference. Use HCP Vault locals if values exist, else fall back to GCP Secrets Manager
resource "local_file" "user_data_file" {
content = local.userdata
content = local.userdata_selected
filename = "../user_data"
}



################################################################################
# Locate Latest CC Image
################################################################################
Expand Down Expand Up @@ -148,13 +179,15 @@ module "cc_vm" {
zones = local.zones_list
ccvm_instance_type = var.ccvm_instance_type
ssh_key = tls_private_key.key.public_key_openssh
user_data = local.userdata
user_data = local.userdata_selected
cc_count = var.cc_count
vpc_subnetwork_ccvm_mgmt = module.network.mgmt_subnet
vpc_subnetwork_ccvm_service = module.network.service_subnet
image_name = var.image_name != "" ? var.image_name : data.google_compute_image.zs_cc_img[0].self_link
service_account = module.iam_service_account.service_account

## Optional: Custom instance names. If not specified and conditions are met for resource
## creation, then names will be auto generated with pre-defined values
instance_template_name_prefix = var.instance_template_name_prefix
instance_template_name = var.instance_template_name
instance_group_name = var.instance_group_name
Expand All @@ -167,9 +200,17 @@ module "cc_vm" {
# 5. Create Service Account for all CC VMs
################################################################################
module "iam_service_account" {
source = "../../modules/terraform-zscc-iam-service-account-gcp"
secret_name = var.secret_name
project = var.project
source = "../../modules/terraform-zscc-iam-service-account-gcp"
project = var.project
byo_ccvm_service_account = var.byo_ccvm_service_account
## If byo_ccvm_service_account is provided any non-empty value, all variables below will be
## ignored/unused. Script assumes that role permissions for either Secret Manager
## (roles/secretmanager.secretAccessor) or HCP Vault (roles/iam.serviceAccountTokenCreator)
## already exists
secret_name = var.secret_name
hcp_vault_enabled = var.hcp_vault_enabled
## Optional: Custom Service Account names. If not specified and conditions are met for resource
## creation, then names will be auto generated with pre-defined values
service_account_id = coalesce(var.service_account_id, "${var.name_prefix}-ccvm-sa-${random_string.suffix.result}")
service_account_display_name = coalesce(var.service_account_display_name, "${var.name_prefix}-ccvm-sa-${random_string.suffix.result}")
}
Loading
Loading