mirror of
https://github.com/kasmtech/terraform.git
synced 2026-01-23 02:24:11 +00:00
Added new GCP terraform provider
This commit is contained in:
parent
d91303ab6b
commit
19816784af
48 changed files with 3788 additions and 0 deletions
70
gcp/MULTI_REGION.md
Normal file
70
gcp/MULTI_REGION.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# GCP Multi-Server Single Region
|
||||
This project will deploy Kasm Workspaces in a multi-server deployment in GCP within multiple regions of your choice. Each Kasm server role is placed in a separate subnet and you can optionally forward traffic from user sessions on the Kasm Agent through a NAT Gateway.
|
||||
|
||||
|
||||
![Diagram][Image_Diagram]
|
||||
|
||||
[Image_Diagram]: https://f.hubspotusercontent30.net/hubfs/5856039/terraform/diagrams/updated/gcp-multi-region.png "Diagram"
|
||||
|
||||
|
||||
# Pre-Configuration
|
||||
Consider creating a separate GCP Project for the Kasm deployment.
|
||||
|
||||
### DNS Zone
|
||||
There are a couple of DNS options available with this GCP Terraform. Regardless of method, Terraform will:
|
||||
- Add a DNS record for the load balancer
|
||||
- Add a private DNS zone and add records for the private load balancer used by Agents to communicate with the webapps
|
||||
|
||||
1. Create and verify the public DNS zone before deploying Terraform
|
||||
- Using this method, you will create a DNS zone or use an existing DNS zone in the same GCP Project where you deploy Kasm
|
||||
|
||||
2. Allow Terraform to create the public DNS zone for you
|
||||
- Using this method, Terraform will create a public DNS zone using the values you provide, and you must manually add the name server (NS) records to the parent DNS zone so queries are forwarded correctly
|
||||
|
||||
### Create Terraform service account and generate an API key
|
||||
Create a GCP Service Account to use with Terraform (https://cloud.google.com/iam/docs/service-accounts-create), and generate an API key. Once the API Key credential file is downloaded, copy it's contents into the `gcp_credentials.json` file in this directory, and Terraform will use these credentials to perform all operations.
|
||||
|
||||
Recommended Service Account roles:
|
||||
- Compute Admin
|
||||
- DNS Administrator
|
||||
- Network Management Admin
|
||||
- Service Account Admin
|
||||
|
||||
### GCP APIs to enable before running Terraform
|
||||
There are several GCP service APIs that must be enabled before this Terraform can build successfully. In your GCP project, navigate to each of these and ensure they are enabled before running the Terraform configuration stage below.
|
||||
|
||||
GCP APIs:
|
||||
- Cloud DNS
|
||||
- Cloud NAT
|
||||
|
||||
# Terraform Configuration
|
||||
|
||||
1. Initialize the project
|
||||
|
||||
terraform init
|
||||
|
||||
2. Open `terraform.tfvars` and update the variable values. The variable definitions, descriptions, and validation expectations can be found in the `variables.tf` file, or in the [README](./README.md).
|
||||
|
||||
> In order to deploy this in multiple regions, simply add all additional regions in the `kasm_deployment_regions` variable in the `terraform.tfvars` file. The first region in the list is where the Database will be deployed, thus, it is recommended to put this closest to those who will be responsible for Database administration to reduce network complexity and DB latency.
|
||||
|
||||
|
||||
3. Verify the configuration
|
||||
|
||||
terraform plan
|
||||
|
||||
4. Deploy
|
||||
|
||||
terraform apply
|
||||
|
||||
5. Login to the Deployment as an Admin via the domain defined e.g `https://kasm.contoso.com`
|
||||
|
||||
> NOTE: The Load Balancer certificate can take between 15-45 min. to become active so you can access your Kasm deployment.
|
||||
|
||||
6. Navigate to the Agents tab, and enable each Agent after it checks in. (May take a few minutes)
|
||||
|
||||
|
||||
# Detailed Terraform Deployment Diagram
|
||||
|
||||
![Detailed Diagram][Detailed_Diagram]
|
||||
|
||||
[Detailed_Diagram]: ./diagram/gcp_multi_region.png "Detailed Diagram"
|
||||
68
gcp/MULTI_SERVER.md
Normal file
68
gcp/MULTI_SERVER.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# GCP Multi-Server Single Region
|
||||
This project will deploy Kasm Workspaces in a multi-server deployment in GCP within a single region of your choice. Each Kasm server role is placed in a separate subnet and you can optionally forward traffic from user sessions on the Kasm Agent through a NAT Gateway.
|
||||
|
||||
|
||||
![Diagram][Image_Diagram]
|
||||
|
||||
[Image_Diagram]: https://f.hubspotusercontent30.net/hubfs/5856039/terraform/diagrams/updated/gcp-multi-server.png "Diagram"
|
||||
|
||||
|
||||
# Pre-Configuration
|
||||
Consider creating a separate GCP Project for the Kasm deployment.
|
||||
|
||||
### DNS Zone
|
||||
There are a couple of DNS options available with this GCP Terraform. Regardless of method, Terraform will:
|
||||
- Add a DNS record for the load balancer
|
||||
- Add a private DNS zone and add records for the private load balancer used by Agents to communicate with the webapps
|
||||
|
||||
1. Create and verify the public DNS zone before deploying Terraform
|
||||
- Using this method, you will create a DNS zone or use an existing DNS zone in the same GCP Project where you deploy Kasm
|
||||
|
||||
2. Allow Terraform to create the public DNS zone for you
|
||||
- Using this method, Terraform will create a public DNS zone using the values you provide, and you must manually add the name server (NS) records to the parent DNS zone so queries are forwarded correctly
|
||||
|
||||
### Create Terraform service account and generate an API key
|
||||
Create a GCP Service Account to use with Terraform (https://cloud.google.com/iam/docs/service-accounts-create), and generate an API key. Once the API Key credential file is downloaded, copy it's contents into the `gcp_credentials.json` file in this directory, and Terraform will use these credentials to perform all operations.
|
||||
|
||||
Recommended Service Account roles:
|
||||
- Compute Admin
|
||||
- DNS Administrator
|
||||
- Network Management Admin
|
||||
- Service Account Admin
|
||||
|
||||
### GCP APIs to enable before running Terraform
|
||||
There are several GCP service APIs that must be enabled before this Terraform can build successfully. In your GCP project, navigate to each of these and ensure they are enabled before running the Terraform configuration stage below.
|
||||
|
||||
GCP APIs:
|
||||
- Cloud DNS
|
||||
- Cloud NAT
|
||||
|
||||
# Terraform Configuration
|
||||
|
||||
1. Initialize the project
|
||||
|
||||
terraform init
|
||||
|
||||
2. Open `terraform.tfvars` and update the variable values. The variable definitions, descriptions, and validation expectations can be found in the `variables.tf` file, or in the [README](./README.md).
|
||||
|
||||
|
||||
3. Verify the configuration
|
||||
|
||||
terraform plan
|
||||
|
||||
4. Deploy
|
||||
|
||||
terraform apply
|
||||
|
||||
5. Login to the Deployment as an Admin via the domain defined e.g `https://kasm.contoso.com`
|
||||
|
||||
> NOTE: The Load Balancer certificate can take between 15-45 min. to become active so you can access your Kasm deployment.
|
||||
|
||||
6. Navigate to the Agents tab, and enable each Agent after it checks in. (May take a few minutes)
|
||||
|
||||
|
||||
# Detailed Terraform Deployment Diagram
|
||||
|
||||
![Detailed Diagram][Detailed_Diagram]
|
||||
|
||||
[Detailed_Diagram]: ./diagram/gcp_multi_server.png "Detailed Diagram"
|
||||
279
gcp/README.md
Normal file
279
gcp/README.md
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
# GCP Deployments
|
||||
|
||||
Before getting started with this Terraform, ensure the following GCP APIs or services are enabled to prevent any deployment failures or errors.
|
||||
- [Cloud NAT](https://cloud.google.com/nat/docs/overview)
|
||||
- [Cloud DNS API](https://console.cloud.google.com/apis/library/dns.googleapis.com)
|
||||
- [IAM API](https://console.cloud.google.com/apis/library/iam.googleapis.com)
|
||||
- [Cloud Resource Manager API](https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com)
|
||||
|
||||
To run this Terraform, create a GCP Service Account and generate an API key for the account. Use the below permissions as a starting point to allow the account to provision your Kasm deployment.
|
||||
|
||||
IAM Permissions (these are likely a little too permissive, but they are a good starting point):
|
||||
- roles/compute.loadBalancerAdmin
|
||||
- roles/compute.networkAdmin
|
||||
- roles/compute.securityAdmin
|
||||
- roles/compute.instanceAdmin
|
||||
- roles/iam.serviceAccountCreator
|
||||
- roles/iam.serviceAccountDeleter
|
||||
- roles/iam.serviceAccountTokenCreator
|
||||
- roles/iam.serviceAccountViewer
|
||||
- roles/servicenetworking.networksAdmin
|
||||
- roles/dns.admin
|
||||
- roles/storage.admin
|
||||
- roles/iam.serviceAccountUser
|
||||
- roles/iam.security.admin
|
||||
- roles/iam.serviceAccountKeys.create
|
||||
|
||||
|
||||
For additional information, check out Google's IAM documentation check out these links:
|
||||
- [Secure IAM](https://cloud.google.com/iam/docs/using-iam-securely)
|
||||
- [Understanding Service Accounts](https://cloud.google.com/iam/docs/service-account-overview)
|
||||
- [IAM Resource Hierarchy](https://cloud.google.com/iam/docs/resource-hierarchy-access-control)
|
||||
- [Predefined IAM Roles](https://cloud.google.com/iam/docs/understanding-roles)
|
||||
|
||||
|
||||
|
||||
GCP offers a unique Kasm deployment experience. Due to the way they flatten their cloud network architecture, it is possible to use the same terraform deployment for both single and multi-region deployment models. Below, you will find the Terraform variable and module reference, and if you wish to see documentation specific to a Kasm deployment using this Terraform, just click one of the links below.
|
||||
|
||||
- [Kasm Multi-Server Deployment](./MULTI_SERVER.md)
|
||||
- [Kasm Multi-Region Deployment](./MULTI_REGION.md)
|
||||
|
||||
|
||||
<!-- END PRIVATE BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
Deploy VPC and network resources
|
||||
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
| <a name="requirement_random"></a> [random](#requirement\_random) | ~> 3.0 |
|
||||
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | ~> 2.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
No providers.
|
||||
|
||||
## Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
|------|--------|---------|
|
||||
| <a name="module_agent_instances"></a> [agent\_instances](#module\_agent\_instances) | ./modules/compute_instance | n/a |
|
||||
| <a name="module_cloud_nat"></a> [cloud\_nat](#module\_cloud\_nat) | terraform-google-modules/cloud-nat/google | ~> 4.0 |
|
||||
| <a name="module_cpx_instance_group"></a> [cpx\_instance\_group](#module\_cpx\_instance\_group) | terraform-google-modules/vm/google//modules/mig | ~> 8.0 |
|
||||
| <a name="module_cpx_instance_template"></a> [cpx\_instance\_template](#module\_cpx\_instance\_template) | terraform-google-modules/vm/google//modules/instance_template | ~> 8.0 |
|
||||
| <a name="module_database_instance"></a> [database\_instance](#module\_database\_instance) | ./modules/compute_instance | n/a |
|
||||
| <a name="module_dns_private_zone"></a> [dns\_private\_zone](#module\_dns\_private\_zone) | terraform-google-modules/cloud-dns/google | ~> 5.0 |
|
||||
| <a name="module_dns_public_records"></a> [dns\_public\_records](#module\_dns\_public\_records) | ./modules/dns_records | n/a |
|
||||
| <a name="module_dns_public_zone"></a> [dns\_public\_zone](#module\_dns\_public\_zone) | terraform-google-modules/cloud-dns/google | ~> 5.0 |
|
||||
| <a name="module_kasm_autoscale_service_account"></a> [kasm\_autoscale\_service\_account](#module\_kasm\_autoscale\_service\_account) | ./modules/service_account_iam | n/a |
|
||||
| <a name="module_passwords"></a> [passwords](#module\_passwords) | ./modules/random | n/a |
|
||||
| <a name="module_public_load_balancer"></a> [public\_load\_balancer](#module\_public\_load\_balancer) | GoogleCloudPlatform/lb-http/google | ~> 9.0 |
|
||||
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-google-modules/network/google | ~> 7.0 |
|
||||
| <a name="module_webapp_instance_group"></a> [webapp\_instance\_group](#module\_webapp\_instance\_group) | terraform-google-modules/vm/google//modules/mig | ~> 8.0 |
|
||||
| <a name="module_webapp_instance_template"></a> [webapp\_instance\_template](#module\_webapp\_instance\_template) | terraform-google-modules/vm/google//modules/instance_template | ~> 8.0 |
|
||||
| <a name="module_webapp_private_load_balancer"></a> [webapp\_private\_load\_balancer](#module\_webapp\_private\_load\_balancer) | ./modules/private_load_balancer | n/a |
|
||||
|
||||
## Resources
|
||||
|
||||
No resources.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_additional_agent_install_options"></a> [additional\_agent\_install\_options](#input\_additional\_agent\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_cpx_install_options"></a> [additional\_cpx\_install\_options](#input\_additional\_cpx\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_database_install_options"></a> [additional\_database\_install\_options](#input\_additional\_database\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_kasm_install_options"></a> [additional\_kasm\_install\_options](#input\_additional\_kasm\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | <pre>[<br> "-O"<br>]</pre> | no |
|
||||
| <a name="input_additional_webapp_install_options"></a> [additional\_webapp\_install\_options](#input\_additional\_webapp\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_agent_gpu_enabled"></a> [agent\_gpu\_enabled](#input\_agent\_gpu\_enabled) | Whether or not to automatically install GPU libraries. NOTE: This is useless unless you deploy Kasm agents using a GPU-based instance. | `bool` | `false` | no |
|
||||
| <a name="input_agent_vm_instance_config"></a> [agent\_vm\_instance\_config](#input\_agent\_vm\_instance\_config) | Agent Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = number<br> instance_role = string<br> name = optional(string)<br> name_prefix = optional(string)<br> disk_auto_delete = optional(bool)<br> description = optional(string)<br> disk_type = optional(string)<br> })</pre> | n/a | yes |
|
||||
| <a name="input_compute_service_account"></a> [compute\_service\_account](#input\_compute\_service\_account) | Compute service account to use for CPX autoscaling | <pre>object({<br> email = optional(string)<br> scopes = list(string)<br> })</pre> | <pre>{<br> "email": "",<br> "scopes": [<br> "cloud-platform"<br> ]<br>}</pre> | no |
|
||||
| <a name="input_cpx_autoscale_cool_down_period"></a> [cpx\_autoscale\_cool\_down\_period](#input\_cpx\_autoscale\_cool\_down\_period) | Time in seconds for the autoscale group to wait before evaluating the health of the webapp | `number` | `600` | no |
|
||||
| <a name="input_cpx_autoscale_max_instances"></a> [cpx\_autoscale\_max\_instances](#input\_cpx\_autoscale\_max\_instances) | CPX Autoscale maximum number of instances | `number` | `5` | no |
|
||||
| <a name="input_cpx_autoscale_min_instances"></a> [cpx\_autoscale\_min\_instances](#input\_cpx\_autoscale\_min\_instances) | CPX Autoscale minimum number of instances | `number` | `1` | no |
|
||||
| <a name="input_cpx_autoscale_scale_in_settings"></a> [cpx\_autoscale\_scale\_in\_settings](#input\_cpx\_autoscale\_scale\_in\_settings) | CPX Autoscale scale-in settings | <pre>object({<br> fixed_replicas = number<br> time_window_sec = number<br> percent_replicas = optional(number, null)<br> })</pre> | <pre>{<br> "fixed_replicas": 1,<br> "time_window_sec": 600<br>}</pre> | no |
|
||||
| <a name="input_cpx_autoscale_scale_out_cpu"></a> [cpx\_autoscale\_scale\_out\_cpu](#input\_cpx\_autoscale\_scale\_out\_cpu) | CPX Autoscale CPU percent to scale up webapps | <pre>list(object({<br> target = number<br> predictive_method = optional(string, "NONE")<br> }))</pre> | <pre>[<br> {<br> "target": 0.6<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_hostname_prefix"></a> [cpx\_hostname\_prefix](#input\_cpx\_hostname\_prefix) | CPX hostname prefix to use for instance group | `string` | `"cpx"` | no |
|
||||
| <a name="input_cpx_instance_update_policy"></a> [cpx\_instance\_update\_policy](#input\_cpx\_instance\_update\_policy) | The CPX Instance group rolling update policy | <pre>list(object({<br> instance_redistribution_type = string<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> max_surge_fixed = optional(number, null)<br> max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances<br> max_unavailable_fixed = optional(number, null)<br> max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances<br> }))</pre> | <pre>[<br> {<br> "instance_redistribution_type": "PROACTIVE",<br> "max_surge_fixed": 3,<br> "max_unavailable_fixed": 0,<br> "min_ready_sec": 600,<br> "minimal_action": "REFRESH",<br> "replacement_method": "SUBSTITUTE",<br> "type": "PROACTIVE"<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_named_ports"></a> [cpx\_named\_ports](#input\_cpx\_named\_ports) | CPX named ports for firewall and Google service connectivity | <pre>list(object({<br> name = string<br> port = number<br> }))</pre> | <pre>[<br> {<br> "name": "https",<br> "port": 443<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_vm_instance_config"></a> [cpx\_vm\_instance\_config](#input\_cpx\_vm\_instance\_config) | CPX Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = string<br> disk_type = string<br> })</pre> | n/a | yes |
|
||||
| <a name="input_create_kasm_autoscale_service_account"></a> [create\_kasm\_autoscale\_service\_account](#input\_create\_kasm\_autoscale\_service\_account) | Create a GCP service account capable of managing Kasm Cloud Autoscaling for GCP agents | `bool` | `false` | no |
|
||||
| <a name="input_create_public_dns_zone"></a> [create\_public\_dns\_zone](#input\_create\_public\_dns\_zone) | Set to true if you wish to create a public DNS zone for this Kasm instance. If not, the public\_dns\_friendly\_name should belong to an existing DNS zone. | `bool` | `true` | no |
|
||||
| <a name="input_custom_firewall_rules"></a> [custom\_firewall\_rules](#input\_custom\_firewall\_rules) | Additional, custom firewall rules | <pre>list(object({<br> name = string<br> description = optional(string, null)<br> direction = optional(string, null)<br> priority = optional(number, null)<br> ranges = optional(list(string), null)<br> source_tags = optional(list(string), null)<br> source_service_accounts = optional(list(string), null)<br> target_tags = optional(list(string), null)<br> target_service_accounts = optional(list(string), null)<br> allow = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), null)<br> deny = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), null)<br> log_config = optional(object({<br> metadata = string<br> }), null)<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_custom_kasm_routes"></a> [custom\_kasm\_routes](#input\_custom\_kasm\_routes) | Custom routes to add to VPC | <pre>list(object({<br> name = string<br> destination_range = string<br> description = optional(string, null)<br> priority = optional(number, null)<br> next_hop_internet = optional(bool, false)<br> next_hop_ip = optional(string, null)<br> next_hop_instance = optional(string, null)<br> next_hop_instance_zone = optional(string, null)<br> next_hop_vpn_tunnel = optional(string, null)<br> next_hop_ilb = optional(string, null)<br> tags = optional(list(string), [])<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_database_vm_instance_config"></a> [database\_vm\_instance\_config](#input\_database\_vm\_instance\_config) | Database Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = number<br> instance_role = string<br> name = optional(string)<br> name_prefix = optional(string)<br> disk_auto_delete = optional(bool)<br> description = optional(string)<br> disk_type = optional(string)<br> })</pre> | n/a | yes |
|
||||
| <a name="input_deploy_connection_proxy"></a> [deploy\_connection\_proxy](#input\_deploy\_connection\_proxy) | Deploy Kasm Guacamole Server for RDP/SSH access to physical servers | `bool` | `false` | no |
|
||||
| <a name="input_deploy_windows_hosts"></a> [deploy\_windows\_hosts](#input\_deploy\_windows\_hosts) | Create a subnet and Firewall rules for Windows hosts. These hosts must be deployed manually, or you'll need to add your own compute entry for Windows hosts. | `bool` | `false` | no |
|
||||
| <a name="input_deployment_type"></a> [deployment\_type](#input\_deployment\_type) | The deployment type - Single-Server, Multi-Server, or Multi-Region | `string` | `"Multi-Server"` | no |
|
||||
| <a name="input_enable_agent_nat_gateway"></a> [enable\_agent\_nat\_gateway](#input\_enable\_agent\_nat\_gateway) | Deploy Kasm Agent behind a NAT gateway | `bool` | `false` | no |
|
||||
| <a name="input_google_credential_file_path"></a> [google\_credential\_file\_path](#input\_google\_credential\_file\_path) | File path to GCP account authentication file | `string` | `""` | no |
|
||||
| <a name="input_kasm_admin_password"></a> [kasm\_admin\_password](#input\_kasm\_admin\_password) | The administrative user password. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_cert_map_base_name"></a> [kasm\_cert\_map\_base\_name](#input\_kasm\_cert\_map\_base\_name) | Name to use for Kasm Global SSL certificate map | `string` | `"kasm-global-certificate-map"` | no |
|
||||
| <a name="input_kasm_certificate_base_name"></a> [kasm\_certificate\_base\_name](#input\_kasm\_certificate\_base\_name) | Name to use for Kasm Global SSL certificate | `string` | `"kasm-global-tls-certificate"` | no |
|
||||
| <a name="input_kasm_certificate_dns_auth_base_name"></a> [kasm\_certificate\_dns\_auth\_base\_name](#input\_kasm\_certificate\_dns\_auth\_base\_name) | Name to use for Kasm SSL DNS authorization service | `string` | `"kasm-global-certificate-dns-authorization"` | no |
|
||||
| <a name="input_kasm_database_password"></a> [kasm\_database\_password](#input\_kasm\_database\_password) | The password for the database. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_deployment_regions"></a> [kasm\_deployment\_regions](#input\_kasm\_deployment\_regions) | Kasm regions to deploy into | `list(string)` | n/a | yes |
|
||||
| <a name="input_kasm_domain_name"></a> [kasm\_domain\_name](#input\_kasm\_domain\_name) | Public DNS domain name to use for Kasm deployment | `string` | n/a | yes |
|
||||
| <a name="input_kasm_download_url"></a> [kasm\_download\_url](#input\_kasm\_download\_url) | Download URL for Kasm Workspaces installer | `string` | n/a | yes |
|
||||
| <a name="input_kasm_firewall_security_tags"></a> [kasm\_firewall\_security\_tags](#input\_kasm\_firewall\_security\_tags) | Firewall tags to use for Kasm CPX firewall rules | <pre>object({<br> webapp = list(string)<br> database = list(string)<br> agent = list(string)<br> cpx = optional(list(string), [])<br> windows = optional(list(string), [])<br> })</pre> | <pre>{<br> "agent": [<br> "kasm-agent"<br> ],<br> "cpx": [<br> "kasm-cpx"<br> ],<br> "database": [<br> "database"<br> ],<br> "webapp": [<br> "webapp"<br> ],<br> "windows": [<br> "kasm-windows"<br> ]<br>}</pre> | no |
|
||||
| <a name="input_kasm_manager_token"></a> [kasm\_manager\_token](#input\_kasm\_manager\_token) | The manager token value for Agents to authenticate to webapps. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_project_name"></a> [kasm\_project\_name](#input\_kasm\_project\_name) | Kasm deployment project name (separate from GCP Project id or Project Name) | `string` | `""` | no |
|
||||
| <a name="input_kasm_redis_password"></a> [kasm\_redis\_password](#input\_kasm\_redis\_password) | The password for the Redis server. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_service_token"></a> [kasm\_service\_token](#input\_kasm\_service\_token) | The service registration token value for Guac RDP servers to authenticate to webapps. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_source_image"></a> [kasm\_source\_image](#input\_kasm\_source\_image) | The source VM Image information to use for deploying Kasm. Recommended to use Ubuntu 20.04 Minimal. You can either explicitly define the source image to use, or the image project and family so that Terraform always chooses the latest. | <pre>object({<br> source_image = optional(string, null)<br> project = optional(string, null)<br> family = optional(string, null)<br> })</pre> | <pre>{<br> "family": "ubuntu-minimal-2004-lts",<br> "project": "ubuntu-os-cloud"<br>}</pre> | no |
|
||||
| <a name="input_kasm_user_password"></a> [kasm\_user\_password](#input\_kasm\_user\_password) | The standard (non administrator) user password. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_version"></a> [kasm\_version](#input\_kasm\_version) | Kasm version to deploy | `string` | `""` | no |
|
||||
| <a name="input_kasm_vpc_subnet"></a> [kasm\_vpc\_subnet](#input\_kasm\_vpc\_subnet) | VPC Subnet CIDR range. All other Subnets will be automatically calculated from this seed value. | `string` | `"10.0.0.0/16"` | no |
|
||||
| <a name="input_number_of_agents_per_region"></a> [number\_of\_agents\_per\_region](#input\_number\_of\_agents\_per\_region) | The number of static Kasm agents to deploy in each region. Set this to 0 to | `number` | n/a | yes |
|
||||
| <a name="input_private_dns_friendly_name"></a> [private\_dns\_friendly\_name](#input\_private\_dns\_friendly\_name) | Private DNS Zone resource name | `string` | n/a | yes |
|
||||
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | GCP Project ID where to deploy Kasm | `string` | n/a | yes |
|
||||
| <a name="input_public_dns_friendly_name"></a> [public\_dns\_friendly\_name](#input\_public\_dns\_friendly\_name) | Public DNS Zone resource name. If not creating a new DNS Zone, make sure the desired DNS zone already exists. | `string` | n/a | yes |
|
||||
| <a name="input_public_load_balancer_name"></a> [public\_load\_balancer\_name](#input\_public\_load\_balancer\_name) | GCP name for Global Public HTTPS Load balancer | `string` | `"webapp-global-load-balancer"` | no |
|
||||
| <a name="input_resource_labels"></a> [resource\_labels](#input\_resource\_labels) | Default tags to add to Terraform-deployed Kasm services | `map(any)` | `null` | no |
|
||||
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Account name to use for Kasm Autoscaling service account | `string` | `""` | no |
|
||||
| <a name="input_show_passwords"></a> [show\_passwords](#input\_show\_passwords) | Show Kasm passwords in root Terraform output | `bool` | `true` | no |
|
||||
| <a name="input_show_sa_credentials"></a> [show\_sa\_credentials](#input\_show\_sa\_credentials) | Show GCP Service account credential file in output | `bool` | `true` | no |
|
||||
| <a name="input_use_gcp_certificate_manager"></a> [use\_gcp\_certificate\_manager](#input\_use\_gcp\_certificate\_manager) | Use Certificate Manager to create and manage the Kasm public SSL certificate | `bool` | `false` | no |
|
||||
| <a name="input_vpc_name"></a> [vpc\_name](#input\_vpc\_name) | Name for Kasm VPC | `string` | n/a | yes |
|
||||
| <a name="input_webapp_autoscale_cool_down_period"></a> [webapp\_autoscale\_cool\_down\_period](#input\_webapp\_autoscale\_cool\_down\_period) | Time in seconds for the autoscale group to wait before evaluating the health of the webapp | `number` | `600` | no |
|
||||
| <a name="input_webapp_autoscale_max_instances"></a> [webapp\_autoscale\_max\_instances](#input\_webapp\_autoscale\_max\_instances) | Webapp Autoscale maximum number of instances | `number` | `5` | no |
|
||||
| <a name="input_webapp_autoscale_min_instances"></a> [webapp\_autoscale\_min\_instances](#input\_webapp\_autoscale\_min\_instances) | Webapp Autoscale minimum number of instances | `number` | `2` | no |
|
||||
| <a name="input_webapp_autoscale_scale_in_settings"></a> [webapp\_autoscale\_scale\_in\_settings](#input\_webapp\_autoscale\_scale\_in\_settings) | Webapp Autoscale scale-in settings | <pre>object({<br> fixed_replicas = number<br> time_window_sec = number<br> percent_replicas = optional(number, null)<br> })</pre> | <pre>{<br> "fixed_replicas": 1,<br> "time_window_sec": 600<br>}</pre> | no |
|
||||
| <a name="input_webapp_autoscale_scale_out_cpu"></a> [webapp\_autoscale\_scale\_out\_cpu](#input\_webapp\_autoscale\_scale\_out\_cpu) | Webapp Autoscale CPU percent to scale up webapps | <pre>list(object({<br> target = number<br> predictive_method = string<br> }))</pre> | <pre>[<br> {<br> "predictive_method": "NONE",<br> "target": 0.6<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_health_check"></a> [webapp\_health\_check](#input\_webapp\_health\_check) | HTTPS Managed Instance Group healthcheck for webapps. | <pre>object({<br> type = string<br> initial_delay_sec = number<br> check_interval_sec = number<br> healthy_threshold = number<br> timeout_sec = number<br> unhealthy_threshold = number<br> port = number<br> port_name = string<br> request_path = string<br> response = optional(string, "")<br> proxy_header = optional(string, "NONE")<br> request = optional(string, "")<br> host = optional(string, "")<br> enable_log = optional(bool, false)<br> enable_logging = optional(string, false)<br> })</pre> | <pre>{<br> "check_interval_sec": 30,<br> "healthy_threshold": 2,<br> "initial_delay_sec": 600,<br> "port": 443,<br> "port_name": "https",<br> "request_path": "/api/__healthcheck",<br> "timeout_sec": 10,<br> "type": "https",<br> "unhealthy_threshold": 5<br>}</pre> | no |
|
||||
| <a name="input_webapp_health_check_name"></a> [webapp\_health\_check\_name](#input\_webapp\_health\_check\_name) | Name of Webapp Managed Instance Group healthcheck | `string` | `"webapp-healthcheck"` | no |
|
||||
| <a name="input_webapp_hostname_prefix"></a> [webapp\_hostname\_prefix](#input\_webapp\_hostname\_prefix) | Webapp hostname prefix to use for instance group | `string` | `"webapp"` | no |
|
||||
| <a name="input_webapp_instance_update_policy"></a> [webapp\_instance\_update\_policy](#input\_webapp\_instance\_update\_policy) | The Instance group rolling update policy | <pre>list(object({<br> instance_redistribution_type = string<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> max_surge_fixed = optional(number, null)<br> max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances<br> max_unavailable_fixed = optional(number, null)<br> max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances<br> }))</pre> | <pre>[<br> {<br> "instance_redistribution_type": "PROACTIVE",<br> "max_surge_fixed": 3,<br> "max_unavailable_fixed": 0,<br> "min_ready_sec": 600,<br> "minimal_action": "REFRESH",<br> "replacement_method": "SUBSTITUTE",<br> "type": "PROACTIVE"<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_lb_health_check"></a> [webapp\_lb\_health\_check](#input\_webapp\_lb\_health\_check) | HTTPS Load balancer and healthcheck for webapps. | <pre>object({<br> check_interval_sec = optional(number)<br> timeout_sec = optional(number)<br> healthy_threshold = optional(number)<br> unhealthy_threshold = optional(number)<br> request_path = optional(string)<br> port = optional(number)<br> host = optional(string)<br> logging = optional(bool)<br> })</pre> | <pre>{<br> "check_interval_sec": 30,<br> "healthy_threshold": 2,<br> "port": 443,<br> "request_path": "/api/__healthcheck",<br> "timeout_sec": 10,<br> "unhealthy_threshold": 3<br>}</pre> | no |
|
||||
| <a name="input_webapp_named_ports"></a> [webapp\_named\_ports](#input\_webapp\_named\_ports) | Webapp named ports for firewall and Google service connectivity | <pre>list(object({<br> name = string<br> port = number<br> }))</pre> | <pre>[<br> {<br> "name": "https",<br> "port": 443<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_vm_instance_config"></a> [webapp\_vm\_instance\_config](#input\_webapp\_vm\_instance\_config) | Webapp Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = string<br> disk_type = string<br> })</pre> | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_kasm_passwords"></a> [kasm\_passwords](#output\_kasm\_passwords) | Kasm login passwords |
|
||||
| <a name="output_kasm_sa_account"></a> [kasm\_sa\_account](#output\_kasm\_sa\_account) | Kasm Service Account connection details |
|
||||
<!-- END PRIVATE END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
Deploy VPC and network resources
|
||||
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
| <a name="requirement_random"></a> [random](#requirement\_random) | ~> 3.0 |
|
||||
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | ~> 2.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
No providers.
|
||||
|
||||
## Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
|------|--------|---------|
|
||||
| <a name="module_agent_instances"></a> [agent\_instances](#module\_agent\_instances) | ./modules/compute_instance | n/a |
|
||||
| <a name="module_cloud_nat"></a> [cloud\_nat](#module\_cloud\_nat) | terraform-google-modules/cloud-nat/google | ~> 4.0 |
|
||||
| <a name="module_cpx_instance_group"></a> [cpx\_instance\_group](#module\_cpx\_instance\_group) | terraform-google-modules/vm/google//modules/mig | ~> 8.0 |
|
||||
| <a name="module_cpx_instance_template"></a> [cpx\_instance\_template](#module\_cpx\_instance\_template) | terraform-google-modules/vm/google//modules/instance_template | ~> 8.0 |
|
||||
| <a name="module_database_instance"></a> [database\_instance](#module\_database\_instance) | ./modules/compute_instance | n/a |
|
||||
| <a name="module_dns_private_zone"></a> [dns\_private\_zone](#module\_dns\_private\_zone) | terraform-google-modules/cloud-dns/google | ~> 5.0 |
|
||||
| <a name="module_dns_public_records"></a> [dns\_public\_records](#module\_dns\_public\_records) | ./modules/dns_records | n/a |
|
||||
| <a name="module_dns_public_zone"></a> [dns\_public\_zone](#module\_dns\_public\_zone) | terraform-google-modules/cloud-dns/google | ~> 5.0 |
|
||||
| <a name="module_kasm_autoscale_service_account"></a> [kasm\_autoscale\_service\_account](#module\_kasm\_autoscale\_service\_account) | ./modules/service_account_iam | n/a |
|
||||
| <a name="module_passwords"></a> [passwords](#module\_passwords) | ./modules/random | n/a |
|
||||
| <a name="module_public_load_balancer"></a> [public\_load\_balancer](#module\_public\_load\_balancer) | GoogleCloudPlatform/lb-http/google | ~> 9.0 |
|
||||
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-google-modules/network/google | ~> 7.0 |
|
||||
| <a name="module_webapp_instance_group"></a> [webapp\_instance\_group](#module\_webapp\_instance\_group) | terraform-google-modules/vm/google//modules/mig | ~> 8.0 |
|
||||
| <a name="module_webapp_instance_template"></a> [webapp\_instance\_template](#module\_webapp\_instance\_template) | terraform-google-modules/vm/google//modules/instance_template | ~> 8.0 |
|
||||
| <a name="module_webapp_private_load_balancer"></a> [webapp\_private\_load\_balancer](#module\_webapp\_private\_load\_balancer) | ./modules/private_load_balancer | n/a |
|
||||
|
||||
## Resources
|
||||
|
||||
No resources.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_additional_agent_install_options"></a> [additional\_agent\_install\_options](#input\_additional\_agent\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_cpx_install_options"></a> [additional\_cpx\_install\_options](#input\_additional\_cpx\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_database_install_options"></a> [additional\_database\_install\_options](#input\_additional\_database\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_additional_kasm_install_options"></a> [additional\_kasm\_install\_options](#input\_additional\_kasm\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | <pre>[<br> "-O"<br>]</pre> | no |
|
||||
| <a name="input_additional_webapp_install_options"></a> [additional\_webapp\_install\_options](#input\_additional\_webapp\_install\_options) | Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details. | `list(string)` | `[]` | no |
|
||||
| <a name="input_agent_gpu_enabled"></a> [agent\_gpu\_enabled](#input\_agent\_gpu\_enabled) | Whether or not to automatically install GPU libraries. NOTE: This is useless unless you deploy Kasm agents using a GPU-based instance. | `bool` | `false` | no |
|
||||
| <a name="input_agent_vm_instance_config"></a> [agent\_vm\_instance\_config](#input\_agent\_vm\_instance\_config) | Agent Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = number<br> instance_role = string<br> name = optional(string)<br> name_prefix = optional(string)<br> disk_auto_delete = optional(bool)<br> description = optional(string)<br> disk_type = optional(string)<br> })</pre> | n/a | yes |
|
||||
| <a name="input_compute_service_account"></a> [compute\_service\_account](#input\_compute\_service\_account) | Compute service account to use for CPX autoscaling | <pre>object({<br> email = optional(string)<br> scopes = list(string)<br> })</pre> | <pre>{<br> "email": "",<br> "scopes": [<br> "cloud-platform"<br> ]<br>}</pre> | no |
|
||||
| <a name="input_cpx_autoscale_cool_down_period"></a> [cpx\_autoscale\_cool\_down\_period](#input\_cpx\_autoscale\_cool\_down\_period) | Time in seconds for the autoscale group to wait before evaluating the health of the webapp | `number` | `600` | no |
|
||||
| <a name="input_cpx_autoscale_max_instances"></a> [cpx\_autoscale\_max\_instances](#input\_cpx\_autoscale\_max\_instances) | CPX Autoscale maximum number of instances | `number` | `5` | no |
|
||||
| <a name="input_cpx_autoscale_min_instances"></a> [cpx\_autoscale\_min\_instances](#input\_cpx\_autoscale\_min\_instances) | CPX Autoscale minimum number of instances | `number` | `1` | no |
|
||||
| <a name="input_cpx_autoscale_scale_in_settings"></a> [cpx\_autoscale\_scale\_in\_settings](#input\_cpx\_autoscale\_scale\_in\_settings) | CPX Autoscale scale-in settings | <pre>object({<br> fixed_replicas = number<br> time_window_sec = number<br> percent_replicas = optional(number, null)<br> })</pre> | <pre>{<br> "fixed_replicas": 1,<br> "time_window_sec": 600<br>}</pre> | no |
|
||||
| <a name="input_cpx_autoscale_scale_out_cpu"></a> [cpx\_autoscale\_scale\_out\_cpu](#input\_cpx\_autoscale\_scale\_out\_cpu) | CPX Autoscale CPU percent to scale up webapps | <pre>list(object({<br> target = number<br> predictive_method = optional(string, "NONE")<br> }))</pre> | <pre>[<br> {<br> "target": 0.6<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_hostname_prefix"></a> [cpx\_hostname\_prefix](#input\_cpx\_hostname\_prefix) | CPX hostname prefix to use for instance group | `string` | `"cpx"` | no |
|
||||
| <a name="input_cpx_instance_update_policy"></a> [cpx\_instance\_update\_policy](#input\_cpx\_instance\_update\_policy) | The CPX Instance group rolling update policy | <pre>list(object({<br> instance_redistribution_type = string<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> max_surge_fixed = optional(number, null)<br> max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances<br> max_unavailable_fixed = optional(number, null)<br> max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances<br> }))</pre> | <pre>[<br> {<br> "instance_redistribution_type": "PROACTIVE",<br> "max_surge_fixed": 3,<br> "max_unavailable_fixed": 0,<br> "min_ready_sec": 600,<br> "minimal_action": "REFRESH",<br> "replacement_method": "SUBSTITUTE",<br> "type": "PROACTIVE"<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_named_ports"></a> [cpx\_named\_ports](#input\_cpx\_named\_ports) | CPX named ports for firewall and Google service connectivity | <pre>list(object({<br> name = string<br> port = number<br> }))</pre> | <pre>[<br> {<br> "name": "https",<br> "port": 443<br> }<br>]</pre> | no |
|
||||
| <a name="input_cpx_vm_instance_config"></a> [cpx\_vm\_instance\_config](#input\_cpx\_vm\_instance\_config) | CPX Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = string<br> disk_type = string<br> })</pre> | n/a | yes |
|
||||
| <a name="input_create_kasm_autoscale_service_account"></a> [create\_kasm\_autoscale\_service\_account](#input\_create\_kasm\_autoscale\_service\_account) | Create a GCP service account capable of managing Kasm Cloud Autoscaling for GCP agents | `bool` | `false` | no |
|
||||
| <a name="input_create_public_dns_zone"></a> [create\_public\_dns\_zone](#input\_create\_public\_dns\_zone) | Set to true if you wish to create a public DNS zone for this Kasm instance. If not, the public\_dns\_friendly\_name should belong to an existing DNS zone. | `bool` | `true` | no |
|
||||
| <a name="input_custom_firewall_rules"></a> [custom\_firewall\_rules](#input\_custom\_firewall\_rules) | Additional, custom firewall rules | <pre>list(object({<br> name = string<br> description = optional(string, null)<br> direction = optional(string, null)<br> priority = optional(number, null)<br> ranges = optional(list(string), null)<br> source_tags = optional(list(string), null)<br> source_service_accounts = optional(list(string), null)<br> target_tags = optional(list(string), null)<br> target_service_accounts = optional(list(string), null)<br> allow = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), null)<br> deny = optional(list(object({<br> protocol = string<br> ports = optional(list(string))<br> })), null)<br> log_config = optional(object({<br> metadata = string<br> }), null)<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_custom_kasm_routes"></a> [custom\_kasm\_routes](#input\_custom\_kasm\_routes) | Custom routes to add to VPC | <pre>list(object({<br> name = string<br> destination_range = string<br> description = optional(string, null)<br> priority = optional(number, null)<br> next_hop_internet = optional(bool, false)<br> next_hop_ip = optional(string, null)<br> next_hop_instance = optional(string, null)<br> next_hop_instance_zone = optional(string, null)<br> next_hop_vpn_tunnel = optional(string, null)<br> next_hop_ilb = optional(string, null)<br> tags = optional(list(string), [])<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_database_vm_instance_config"></a> [database\_vm\_instance\_config](#input\_database\_vm\_instance\_config) | Database Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = number<br> instance_role = string<br> name = optional(string)<br> name_prefix = optional(string)<br> disk_auto_delete = optional(bool)<br> description = optional(string)<br> disk_type = optional(string)<br> })</pre> | n/a | yes |
|
||||
| <a name="input_deploy_connection_proxy"></a> [deploy\_connection\_proxy](#input\_deploy\_connection\_proxy) | Deploy Kasm Guacamole Server for RDP/SSH access to physical servers | `bool` | `false` | no |
|
||||
| <a name="input_deploy_windows_hosts"></a> [deploy\_windows\_hosts](#input\_deploy\_windows\_hosts) | Create a subnet and Firewall rules for Windows hosts. These hosts must be deployed manually, or you'll need to add your own compute entry for Windows hosts. | `bool` | `false` | no |
|
||||
| <a name="input_deployment_type"></a> [deployment\_type](#input\_deployment\_type) | The deployment type - Single-Server, Multi-Server, or Multi-Region | `string` | `"Multi-Server"` | no |
|
||||
| <a name="input_enable_agent_nat_gateway"></a> [enable\_agent\_nat\_gateway](#input\_enable\_agent\_nat\_gateway) | Deploy Kasm Agent behind a NAT gateway | `bool` | `false` | no |
|
||||
| <a name="input_google_credential_file_path"></a> [google\_credential\_file\_path](#input\_google\_credential\_file\_path) | File path to GCP account authentication file | `string` | `""` | no |
|
||||
| <a name="input_kasm_admin_password"></a> [kasm\_admin\_password](#input\_kasm\_admin\_password) | The administrative user password. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_cert_map_base_name"></a> [kasm\_cert\_map\_base\_name](#input\_kasm\_cert\_map\_base\_name) | Name to use for Kasm Global SSL certificate map | `string` | `"kasm-global-certificate-map"` | no |
|
||||
| <a name="input_kasm_certificate_base_name"></a> [kasm\_certificate\_base\_name](#input\_kasm\_certificate\_base\_name) | Name to use for Kasm Global SSL certificate | `string` | `"kasm-global-tls-certificate"` | no |
|
||||
| <a name="input_kasm_certificate_dns_auth_base_name"></a> [kasm\_certificate\_dns\_auth\_base\_name](#input\_kasm\_certificate\_dns\_auth\_base\_name) | Name to use for Kasm SSL DNS authorization service | `string` | `"kasm-global-certificate-dns-authorization"` | no |
|
||||
| <a name="input_kasm_database_password"></a> [kasm\_database\_password](#input\_kasm\_database\_password) | The password for the database. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_deployment_regions"></a> [kasm\_deployment\_regions](#input\_kasm\_deployment\_regions) | Kasm regions to deploy into | `list(string)` | n/a | yes |
|
||||
| <a name="input_kasm_domain_name"></a> [kasm\_domain\_name](#input\_kasm\_domain\_name) | Public DNS domain name to use for Kasm deployment | `string` | n/a | yes |
|
||||
| <a name="input_kasm_download_url"></a> [kasm\_download\_url](#input\_kasm\_download\_url) | Download URL for Kasm Workspaces installer | `string` | n/a | yes |
|
||||
| <a name="input_kasm_firewall_security_tags"></a> [kasm\_firewall\_security\_tags](#input\_kasm\_firewall\_security\_tags) | Firewall tags to use for Kasm CPX firewall rules | <pre>object({<br> webapp = list(string)<br> database = list(string)<br> agent = list(string)<br> cpx = optional(list(string), [])<br> windows = optional(list(string), [])<br> })</pre> | <pre>{<br> "agent": [<br> "kasm-agent"<br> ],<br> "cpx": [<br> "kasm-cpx"<br> ],<br> "database": [<br> "database"<br> ],<br> "webapp": [<br> "webapp"<br> ],<br> "windows": [<br> "kasm-windows"<br> ]<br>}</pre> | no |
|
||||
| <a name="input_kasm_manager_token"></a> [kasm\_manager\_token](#input\_kasm\_manager\_token) | The manager token value for Agents to authenticate to webapps. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_project_name"></a> [kasm\_project\_name](#input\_kasm\_project\_name) | Kasm deployment project name (separate from GCP Project id or Project Name) | `string` | `""` | no |
|
||||
| <a name="input_kasm_redis_password"></a> [kasm\_redis\_password](#input\_kasm\_redis\_password) | The password for the Redis server. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_service_token"></a> [kasm\_service\_token](#input\_kasm\_service\_token) | The service registration token value for Guac RDP servers to authenticate to webapps. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_source_image"></a> [kasm\_source\_image](#input\_kasm\_source\_image) | The source VM Image information to use for deploying Kasm. Recommended to use Ubuntu 20.04 Minimal. You can either explicitly define the source image to use, or the image project and family so that Terraform always chooses the latest. | <pre>object({<br> source_image = optional(string, null)<br> project = optional(string, null)<br> family = optional(string, null)<br> })</pre> | <pre>{<br> "family": "ubuntu-minimal-2004-lts",<br> "project": "ubuntu-os-cloud"<br>}</pre> | no |
|
||||
| <a name="input_kasm_user_password"></a> [kasm\_user\_password](#input\_kasm\_user\_password) | The standard (non administrator) user password. No special characters | `string` | `""` | no |
|
||||
| <a name="input_kasm_version"></a> [kasm\_version](#input\_kasm\_version) | Kasm version to deploy | `string` | `""` | no |
|
||||
| <a name="input_kasm_vpc_subnet"></a> [kasm\_vpc\_subnet](#input\_kasm\_vpc\_subnet) | VPC Subnet CIDR range. All other Subnets will be automatically calculated from this seed value. | `string` | `"10.0.0.0/16"` | no |
|
||||
| <a name="input_number_of_agents_per_region"></a> [number\_of\_agents\_per\_region](#input\_number\_of\_agents\_per\_region) | The number of static Kasm agents to deploy in each region. Set this to 0 to | `number` | n/a | yes |
|
||||
| <a name="input_private_dns_friendly_name"></a> [private\_dns\_friendly\_name](#input\_private\_dns\_friendly\_name) | Private DNS Zone resource name | `string` | n/a | yes |
|
||||
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | GCP Project ID where to deploy Kasm | `string` | n/a | yes |
|
||||
| <a name="input_public_dns_friendly_name"></a> [public\_dns\_friendly\_name](#input\_public\_dns\_friendly\_name) | Public DNS Zone resource name. If not creating a new DNS Zone, make sure the desired DNS zone already exists. | `string` | n/a | yes |
|
||||
| <a name="input_public_load_balancer_name"></a> [public\_load\_balancer\_name](#input\_public\_load\_balancer\_name) | GCP name for Global Public HTTPS Load balancer | `string` | `"webapp-global-load-balancer"` | no |
|
||||
| <a name="input_resource_labels"></a> [resource\_labels](#input\_resource\_labels) | Default tags to add to Terraform-deployed Kasm services | `map(any)` | `null` | no |
|
||||
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Account name to use for Kasm Autoscaling service account | `string` | `""` | no |
|
||||
| <a name="input_show_passwords"></a> [show\_passwords](#input\_show\_passwords) | Show Kasm passwords in root Terraform output | `bool` | `true` | no |
|
||||
| <a name="input_show_sa_credentials"></a> [show\_sa\_credentials](#input\_show\_sa\_credentials) | Show GCP Service account credential file in output | `bool` | `true` | no |
|
||||
| <a name="input_use_gcp_certificate_manager"></a> [use\_gcp\_certificate\_manager](#input\_use\_gcp\_certificate\_manager) | Use Certificate Manager to create and manage the Kasm public SSL certificate | `bool` | `false` | no |
|
||||
| <a name="input_vpc_name"></a> [vpc\_name](#input\_vpc\_name) | Name for Kasm VPC | `string` | n/a | yes |
|
||||
| <a name="input_webapp_autoscale_cool_down_period"></a> [webapp\_autoscale\_cool\_down\_period](#input\_webapp\_autoscale\_cool\_down\_period) | Time in seconds for the autoscale group to wait before evaluating the health of the webapp | `number` | `600` | no |
|
||||
| <a name="input_webapp_autoscale_max_instances"></a> [webapp\_autoscale\_max\_instances](#input\_webapp\_autoscale\_max\_instances) | Webapp Autoscale maximum number of instances | `number` | `5` | no |
|
||||
| <a name="input_webapp_autoscale_min_instances"></a> [webapp\_autoscale\_min\_instances](#input\_webapp\_autoscale\_min\_instances) | Webapp Autoscale minimum number of instances | `number` | `2` | no |
|
||||
| <a name="input_webapp_autoscale_scale_in_settings"></a> [webapp\_autoscale\_scale\_in\_settings](#input\_webapp\_autoscale\_scale\_in\_settings) | Webapp Autoscale scale-in settings | <pre>object({<br> fixed_replicas = number<br> time_window_sec = number<br> percent_replicas = optional(number, null)<br> })</pre> | <pre>{<br> "fixed_replicas": 1,<br> "time_window_sec": 600<br>}</pre> | no |
|
||||
| <a name="input_webapp_autoscale_scale_out_cpu"></a> [webapp\_autoscale\_scale\_out\_cpu](#input\_webapp\_autoscale\_scale\_out\_cpu) | Webapp Autoscale CPU percent to scale up webapps | <pre>list(object({<br> target = number<br> predictive_method = string<br> }))</pre> | <pre>[<br> {<br> "predictive_method": "NONE",<br> "target": 0.6<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_health_check"></a> [webapp\_health\_check](#input\_webapp\_health\_check) | HTTPS Managed Instance Group healthcheck for webapps. | <pre>object({<br> type = string<br> initial_delay_sec = number<br> check_interval_sec = number<br> healthy_threshold = number<br> timeout_sec = number<br> unhealthy_threshold = number<br> port = number<br> port_name = string<br> request_path = string<br> response = optional(string, "")<br> proxy_header = optional(string, "NONE")<br> request = optional(string, "")<br> host = optional(string, "")<br> enable_log = optional(bool, false)<br> enable_logging = optional(string, false)<br> })</pre> | <pre>{<br> "check_interval_sec": 30,<br> "healthy_threshold": 2,<br> "initial_delay_sec": 600,<br> "port": 443,<br> "port_name": "https",<br> "request_path": "/api/__healthcheck",<br> "timeout_sec": 10,<br> "type": "https",<br> "unhealthy_threshold": 5<br>}</pre> | no |
|
||||
| <a name="input_webapp_health_check_name"></a> [webapp\_health\_check\_name](#input\_webapp\_health\_check\_name) | Name of Webapp Managed Instance Group healthcheck | `string` | `"webapp-healthcheck"` | no |
|
||||
| <a name="input_webapp_hostname_prefix"></a> [webapp\_hostname\_prefix](#input\_webapp\_hostname\_prefix) | Webapp hostname prefix to use for instance group | `string` | `"webapp"` | no |
|
||||
| <a name="input_webapp_instance_update_policy"></a> [webapp\_instance\_update\_policy](#input\_webapp\_instance\_update\_policy) | The Instance group rolling update policy | <pre>list(object({<br> instance_redistribution_type = string<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> max_surge_fixed = optional(number, null)<br> max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances<br> max_unavailable_fixed = optional(number, null)<br> max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances<br> }))</pre> | <pre>[<br> {<br> "instance_redistribution_type": "PROACTIVE",<br> "max_surge_fixed": 3,<br> "max_unavailable_fixed": 0,<br> "min_ready_sec": 600,<br> "minimal_action": "REFRESH",<br> "replacement_method": "SUBSTITUTE",<br> "type": "PROACTIVE"<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_lb_health_check"></a> [webapp\_lb\_health\_check](#input\_webapp\_lb\_health\_check) | HTTPS Load balancer and healthcheck for webapps. | <pre>object({<br> check_interval_sec = optional(number)<br> timeout_sec = optional(number)<br> healthy_threshold = optional(number)<br> unhealthy_threshold = optional(number)<br> request_path = optional(string)<br> port = optional(number)<br> host = optional(string)<br> logging = optional(bool)<br> })</pre> | <pre>{<br> "check_interval_sec": 30,<br> "healthy_threshold": 2,<br> "port": 443,<br> "request_path": "/api/__healthcheck",<br> "timeout_sec": 10,<br> "unhealthy_threshold": 3<br>}</pre> | no |
|
||||
| <a name="input_webapp_named_ports"></a> [webapp\_named\_ports](#input\_webapp\_named\_ports) | Webapp named ports for firewall and Google service connectivity | <pre>list(object({<br> name = string<br> port = number<br> }))</pre> | <pre>[<br> {<br> "name": "https",<br> "port": 443<br> }<br>]</pre> | no |
|
||||
| <a name="input_webapp_vm_instance_config"></a> [webapp\_vm\_instance\_config](#input\_webapp\_vm\_instance\_config) | Webapp Compute instance configuration settings | <pre>object({<br> machine_type = string<br> disk_size_gb = string<br> disk_type = string<br> })</pre> | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_kasm_passwords"></a> [kasm\_passwords](#output\_kasm\_passwords) | Kasm login passwords |
|
||||
| <a name="output_kasm_sa_account"></a> [kasm\_sa\_account](#output\_kasm\_sa\_account) | Kasm Service Account connection details |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
353
gcp/diagram/gcp_multi_region.drawio
Normal file
353
gcp/diagram/gcp_multi_region.drawio
Normal file
File diff suppressed because one or more lines are too long
BIN
gcp/diagram/gcp_multi_region.png
Normal file
BIN
gcp/diagram/gcp_multi_region.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 232 KiB |
213
gcp/diagram/gcp_multi_server.drawio
Normal file
213
gcp/diagram/gcp_multi_server.drawio
Normal file
File diff suppressed because one or more lines are too long
BIN
gcp/diagram/gcp_multi_server.png
Normal file
BIN
gcp/diagram/gcp_multi_server.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
281
gcp/locals.tf
Normal file
281
gcp/locals.tf
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
locals {
|
||||
## GCP Credential file - set to null for users who wish to use environment/cached credentials.
|
||||
## NOTE: If you wish to use direct-to-agent, then this credential file must be populated since
|
||||
## Let's Encrypt will use it to automatically add the Certificate's DNS validation record.
|
||||
gcp_credentials = var.google_credential_file_path == "" ? null : file(var.google_credential_file_path)
|
||||
|
||||
## Kasm Passwords
|
||||
admin_password = var.kasm_admin_password == "" ? module.passwords[0].password : var.kasm_admin_password
|
||||
user_password = var.kasm_user_password == "" ? module.passwords[1].password : var.kasm_user_password
|
||||
database_password = var.kasm_database_password == "" ? module.passwords[2].password : var.kasm_database_password
|
||||
redis_password = var.kasm_redis_password == "" ? module.passwords[3].password : var.kasm_redis_password
|
||||
service_token = var.kasm_service_token == "" ? module.passwords[4].password : var.kasm_service_token
|
||||
manager_token = var.kasm_manager_token == "" ? module.passwords[5].password : var.kasm_manager_token
|
||||
|
||||
## List of Kasm resources to install
|
||||
kasm_resources = compact(["webapp", "proxy", "database", "agent", var.deploy_connection_proxy ? "cpx" : "", var.deploy_windows_hosts ? "windows" : ""])
|
||||
|
||||
## Generate VPC subnet map for Kasm resources
|
||||
cidr_mask_size = (21 - split("/", var.kasm_vpc_subnet)[1])
|
||||
vpc_subnets = [for idx in range(pow(2, local.cidr_mask_size)) : cidrsubnet(var.kasm_vpc_subnet, local.cidr_mask_size, idx)]
|
||||
vpc_subnets_by_region = { for idx, region in var.kasm_deployment_regions : region => local.vpc_subnets[idx] }
|
||||
kasm_subnets = flatten([for r_index, region in var.kasm_deployment_regions :
|
||||
[for idx, subnet in local.kasm_resources : {
|
||||
subnet_name = "${region}-${subnet}-subnet"
|
||||
subnet_ip = cidrsubnet(local.vpc_subnets_by_region[region], 3, idx)
|
||||
subnet_region = region
|
||||
subnet_private_access = subnet == "proxy" ? false : true
|
||||
purpose = subnet == "proxy" ? "REGIONAL_MANAGED_PROXY" : "PRIVATE"
|
||||
role = subnet == "proxy" ? "ACTIVE" : null
|
||||
} if !(r_index != 0 && (subnet == "database"))]
|
||||
])
|
||||
|
||||
## Create VPC routes. Use the custom_kasm_routes variable to add your own custom
|
||||
## route entries to the VPC's route table.
|
||||
kasm_routes = concat(flatten([var.custom_kasm_routes]))
|
||||
|
||||
## VPC outputs
|
||||
vpc_network_self_link = module.vpc.network_self_link
|
||||
|
||||
## Webapp Userdata Sartup configurations
|
||||
webapp_startup_scripts = { for region in var.kasm_deployment_regions : region => templatefile("${path.module}/userdata/webapp_bootstrap.sh", {
|
||||
DB_PRIVATE_IP = local.database_private_ip
|
||||
KASM_DB_PASS = local.database_password
|
||||
KASM_REDIS_PASS = local.redis_password
|
||||
KASM_DOWNLOAD_URL = var.kasm_download_url
|
||||
ADDITIONAL_WEBAPP_INSTALL_ARGS = join(" ", distinct(flatten([var.additional_kasm_install_options, var.additional_webapp_install_options])))
|
||||
KASM_ZONE_NAME = region
|
||||
}) }
|
||||
|
||||
## Webapp instance output
|
||||
webapp_instance_template_self_link = { for region in var.kasm_deployment_regions : region => module.webapp_instance_template[region].self_link }
|
||||
|
||||
## Database Userdata Startup configuration
|
||||
database_startup_config = [templatefile("${path.module}/userdata/database_bootstrap.sh", {
|
||||
KASM_USER_PASS = local.user_password
|
||||
KASM_ADMIN_PASS = local.admin_password
|
||||
KASM_MANAGER_TOKEN = local.manager_token
|
||||
KASM_SERVICE_TOKEN = local.service_token
|
||||
KASM_DB_PASS = local.database_password
|
||||
KASM_REDIS_PASS = local.redis_password
|
||||
KASM_DOWNLOAD_URL = var.kasm_download_url
|
||||
ADDITIONAL_DATABASE_INSTALL_ARGS = join(" ", distinct(flatten([var.additional_kasm_install_options, var.additional_database_install_options])))
|
||||
})]
|
||||
|
||||
## Database outputs
|
||||
database_private_ip = module.database_instance.private_ip[0]
|
||||
|
||||
## Agent Userdata Startup configurations
|
||||
agent_public_ip = var.enable_agent_nat_gateway ? [] : [{ network_tier = "PREMIUM" }]
|
||||
agent_startup_configs = { for region in var.kasm_deployment_regions : region => [
|
||||
for idx in range(var.number_of_agents_per_region) : templatefile("${path.module}/userdata/agent_bootstrap.sh", {
|
||||
KASM_MANAGER_TOKEN = local.manager_token
|
||||
PRIVATE_LB_HOSTNAME = "${region}-lb.private.${var.kasm_domain_name}"
|
||||
KASM_DOWNLOAD_URL = var.kasm_download_url
|
||||
ADDITIONAL_AGENT_INSTALL_ARGS = join(" ", distinct(flatten([var.additional_kasm_install_options, var.additional_agent_install_options])))
|
||||
GPU_ENABLED = var.agent_gpu_enabled ? "1" : "0"
|
||||
})]
|
||||
}
|
||||
|
||||
## CPX Userdata Sartup configurations
|
||||
cpx_startup_configs = { for region in var.kasm_deployment_regions : region => templatefile("${path.module}/userdata/cpx_bootstrap.sh", {
|
||||
PRIVATE_LB_HOSTNAME = "${region}-lb.private.${var.kasm_domain_name}"
|
||||
KASM_SERVICE_TOKEN = local.service_token
|
||||
KASM_DOWNLOAD_URL = var.kasm_download_url
|
||||
ADDITIONAL_CPX_INSTALL_ARGS = join(" ", distinct(flatten([var.additional_kasm_install_options, var.additional_cpx_install_options])))
|
||||
KASM_ZONE_NAME = region
|
||||
}) }
|
||||
|
||||
## CPX Outputs
|
||||
cpx_instance_template_self_link = var.deploy_connection_proxy ? { for region in var.kasm_deployment_regions : region => module.cpx_instance_template[region].self_link } : {}
|
||||
|
||||
## Public load balancer backends
|
||||
public_load_balancer_backends = {
|
||||
kasm-global-lb-backend = {
|
||||
description = "Global HTTPS Load balancer backend"
|
||||
protocol = "HTTPS"
|
||||
port = var.webapp_named_ports[0].port
|
||||
port_name = var.webapp_named_ports[0].name
|
||||
timeout_sec = 1800
|
||||
enable_cdn = false
|
||||
health_check = var.webapp_lb_health_check
|
||||
custom_request_headers = []
|
||||
custom_response_headers = []
|
||||
compression_mode = ""
|
||||
affinity_cookie_ttl_sec = null
|
||||
connection_draining_timeout_sec = null
|
||||
edge_security_policy = null
|
||||
security_policy = null
|
||||
session_affinity = null
|
||||
log_config = {
|
||||
enable = false
|
||||
sample_rate = null
|
||||
}
|
||||
iap_config = {
|
||||
enable = false
|
||||
oauth2_client_id = null
|
||||
oauth2_client_secret = null
|
||||
}
|
||||
groups = [for region in var.kasm_deployment_regions :
|
||||
{
|
||||
group = module.webapp_instance_group[region].instance_group
|
||||
max_utilization = 0.8
|
||||
description = "${region} Webapp Public LB Backend"
|
||||
balancing_mode = "UTILIZATION"
|
||||
max_connections = null
|
||||
max_connections_per_endpoint = null
|
||||
max_connections_per_instance = null
|
||||
max_rate = null
|
||||
max_rate_per_endpoint = null
|
||||
max_rate_per_instance = null
|
||||
capacity_scaler = null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private_load_balancer_backends = { for region in var.kasm_deployment_regions : region => [
|
||||
{
|
||||
group = module.webapp_instance_group[region].instance_group
|
||||
max_utilization = 0.8
|
||||
description = "${title(region)} Webapp private load balancer backend"
|
||||
balancing_mode = "UTILIZATION"
|
||||
failover = false
|
||||
capacity_scaler = 1
|
||||
}]
|
||||
}
|
||||
|
||||
## TLS Certificate locals for public Load Balancer
|
||||
managed_ssl_domains = var.use_gcp_certificate_manager ? [] : [var.kasm_domain_name]
|
||||
use_lb_ssl = var.use_gcp_certificate_manager ? false : true
|
||||
cert_manager_map_name = null #var.use_gcp_certificate_manager ? "" : "" #module.certificate_manager[0].certificate_map_id : ""
|
||||
|
||||
public_dns_records = [{
|
||||
name = ""
|
||||
type = "A"
|
||||
ttl = 300
|
||||
records = [
|
||||
module.public_load_balancer.external_ip
|
||||
]
|
||||
}]
|
||||
|
||||
## Private DNS Load balancer records
|
||||
private_dns_records = [for region in var.kasm_deployment_regions : {
|
||||
name = "${region}-lb"
|
||||
type = "A"
|
||||
ttl = 300
|
||||
records = [module.webapp_private_load_balancer[region].ip_address]
|
||||
}]
|
||||
|
||||
## VPC Firewall rules
|
||||
firewall_rules = concat(flatten([[for rule in [
|
||||
{
|
||||
name = "kasm-webapp"
|
||||
description = "Webapp HTTPS ingress"
|
||||
priority = 1000
|
||||
direction = "INGRESS"
|
||||
ranges = ["130.211.0.0/22", "35.191.0.0/16"]
|
||||
source_tags = compact(flatten([
|
||||
var.kasm_firewall_security_tags.agent,
|
||||
var.deploy_connection_proxy ? var.kasm_firewall_security_tags.cpx : []
|
||||
]))
|
||||
target_tags = var.kasm_firewall_security_tags.webapp
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["443"]
|
||||
}]
|
||||
},
|
||||
{
|
||||
name = "kasm-agent"
|
||||
description = "Kasm Agent ingress"
|
||||
priority = 1010
|
||||
direction = "INGRESS"
|
||||
source_tags = var.kasm_firewall_security_tags.webapp
|
||||
target_tags = var.kasm_firewall_security_tags.agent
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["443"]
|
||||
}]
|
||||
},
|
||||
{
|
||||
name = "kasm-agent-to-private-lb"
|
||||
description = "Private Load Balancer ingress from agent to webapp"
|
||||
priority = 1020
|
||||
direction = "INGRESS"
|
||||
target_tags = var.kasm_firewall_security_tags.webapp
|
||||
ranges = [for dict in local.kasm_subnets : dict.subnet_ip if contains(split("-", dict.subnet_name), "proxy")]
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["443"]
|
||||
}]
|
||||
},
|
||||
{
|
||||
name = "kasm-database"
|
||||
description = "Kasm Database ingress"
|
||||
priority = 1030
|
||||
direction = "INGRESS"
|
||||
source_tags = var.kasm_firewall_security_tags.webapp
|
||||
target_tags = var.kasm_firewall_security_tags.database
|
||||
ranges = ["35.235.240.0/20"]
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["5432", "6379"]
|
||||
}]
|
||||
},
|
||||
{
|
||||
name = "ssh-access"
|
||||
description = "Allow GCP web-based SSH access to Kasm services"
|
||||
prioritiy = 1040
|
||||
direction = "INGRESS"
|
||||
ranges = ["35.235.240.0/20"]
|
||||
target_tags = compact(flatten([
|
||||
var.kasm_firewall_security_tags.webapp,
|
||||
var.kasm_firewall_security_tags.agent,
|
||||
var.kasm_firewall_security_tags.database,
|
||||
var.deploy_connection_proxy ? var.kasm_firewall_security_tags.cpx : []
|
||||
]))
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["22"]
|
||||
}]
|
||||
},
|
||||
var.deploy_connection_proxy ? {
|
||||
name = "connection-proxy"
|
||||
description = "Kasm Connection Proxy ingress"
|
||||
priority = 1050
|
||||
direction = "INGRESS"
|
||||
source_tags = var.kasm_firewall_security_tags.webapp
|
||||
target_tags = var.kasm_firewall_security_tags.cpx
|
||||
ranges = ["35.235.240.0/20"]
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["443"]
|
||||
}]
|
||||
} : null,
|
||||
var.deploy_windows_hosts ? {
|
||||
name = "windows-hosts"
|
||||
description = "Kasm Windows-managed Host ingress"
|
||||
priority = 1060
|
||||
direction = "INGRESS"
|
||||
source_tags = flatten([
|
||||
var.kasm_firewall_security_tags.cpx,
|
||||
var.kasm_firewall_security_tags.webapp
|
||||
])
|
||||
target_tags = var.kasm_firewall_security_tags.windows
|
||||
allow = [{
|
||||
protocol = "tcp"
|
||||
ports = ["3389", "4902"]
|
||||
}]
|
||||
} : null
|
||||
] : rule if rule != null], var.custom_firewall_rules]))
|
||||
|
||||
## Labels to apply to resources
|
||||
resource_labels = merge(var.resource_labels, {
|
||||
deployed_by = "terraform"
|
||||
deployed_application = "kasm_workspaces"
|
||||
customer = "weave"
|
||||
kasm_version = try(replace("v${var.kasm_version}", ".", "-"), null)
|
||||
project_name = try(lower(var.kasm_project_name), null)
|
||||
deployment_type = try(lower(var.deployment_type), null)
|
||||
})
|
||||
}
|
||||
288
gcp/main.tf
Normal file
288
gcp/main.tf
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Deploy VPC and network resources
|
||||
*/
|
||||
## VPC
|
||||
module "vpc" {
|
||||
source = "terraform-google-modules/network/google"
|
||||
version = "~> 9.0"
|
||||
|
||||
network_name = var.vpc_name
|
||||
project_id = var.project_id
|
||||
routing_mode = "GLOBAL"
|
||||
subnets = local.kasm_subnets
|
||||
routes = local.kasm_routes
|
||||
firewall_rules = local.firewall_rules
|
||||
mtu = "1500"
|
||||
}
|
||||
|
||||
## NAT Gateway
|
||||
module "cloud_nat" {
|
||||
source = "terraform-google-modules/cloud-nat/google"
|
||||
version = "~> 5.0"
|
||||
for_each = toset(var.kasm_deployment_regions)
|
||||
|
||||
name = "${each.key}-nat-gateway"
|
||||
network = module.vpc.network_self_link
|
||||
project_id = var.project_id
|
||||
region = each.key
|
||||
create_router = true
|
||||
router = "${each.key}-router"
|
||||
enable_dynamic_port_allocation = true
|
||||
enable_endpoint_independent_mapping = false
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy Kasm WebApps
|
||||
*/
|
||||
## Create Kasm Webapp Instance Groups
|
||||
module "webapp_instance_template" {
|
||||
source = "terraform-google-modules/vm/google//modules/instance_template"
|
||||
version = "~> 11.0"
|
||||
for_each = toset(var.kasm_deployment_regions)
|
||||
|
||||
project_id = var.project_id
|
||||
network = local.vpc_network_self_link
|
||||
subnetwork = "${each.key}-webapp-subnet"
|
||||
region = each.key
|
||||
service_account = var.compute_service_account
|
||||
name_prefix = substr("${each.key}-${var.webapp_hostname_prefix}-template", 0, 37)
|
||||
source_image_project = var.kasm_source_image.project
|
||||
source_image_family = var.kasm_source_image.family
|
||||
machine_type = var.webapp_vm_instance_config.machine_type
|
||||
disk_size_gb = var.webapp_vm_instance_config.disk_size_gb
|
||||
disk_type = var.webapp_vm_instance_config.disk_type
|
||||
tags = var.kasm_firewall_security_tags.webapp
|
||||
startup_script = local.webapp_startup_scripts[each.key]
|
||||
labels = local.resource_labels
|
||||
}
|
||||
|
||||
## Create Kasm Webapp Instance groups
|
||||
module "webapp_instance_group" {
|
||||
source = "terraform-google-modules/vm/google//modules/mig"
|
||||
version = "~> 11.0"
|
||||
for_each = toset(var.kasm_deployment_regions)
|
||||
|
||||
project_id = var.project_id
|
||||
mig_name = "${each.key}-${var.webapp_hostname_prefix}-group"
|
||||
instance_template = local.webapp_instance_template_self_link[each.key]
|
||||
region = each.key
|
||||
hostname = "${each.key}-${var.webapp_hostname_prefix}"
|
||||
named_ports = var.webapp_named_ports
|
||||
health_check_name = "${each.key}-${var.webapp_health_check_name}"
|
||||
health_check = var.webapp_health_check
|
||||
autoscaling_enabled = true
|
||||
max_replicas = var.webapp_autoscale_max_instances
|
||||
min_replicas = var.webapp_autoscale_min_instances
|
||||
cooldown_period = var.webapp_autoscale_cool_down_period
|
||||
autoscaling_cpu = var.webapp_autoscale_scale_out_cpu
|
||||
autoscaling_scale_in_control = var.webapp_autoscale_scale_in_settings
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy WebApp public and private load balancers
|
||||
*/
|
||||
## Internal (private) Load balancers for Agent auth
|
||||
module "webapp_private_load_balancer" {
|
||||
source = "./modules/private_load_balancer"
|
||||
for_each = toset(var.kasm_deployment_regions)
|
||||
|
||||
project = var.project_id
|
||||
region = each.key
|
||||
network = module.vpc.network_name
|
||||
subnetwork = one([for subnet in module.vpc.subnets_names : subnet if can(regex("${each.key}.webapp", subnet)) ])
|
||||
name = "${each.key}-webapp-private-load-balancer"
|
||||
port_range = var.webapp_named_ports[0].port
|
||||
ip_protocol = "TCP"
|
||||
named_port = var.webapp_named_ports[0].name
|
||||
health_check = var.webapp_health_check
|
||||
backends = local.private_load_balancer_backends[each.key]
|
||||
|
||||
depends_on = [ module.vpc ]
|
||||
}
|
||||
|
||||
## Public access Load balancer for client Kasm access
|
||||
module "public_load_balancer" {
|
||||
source = "GoogleCloudPlatform/lb-http/google"
|
||||
version = "~> 10.0"
|
||||
|
||||
name = var.public_load_balancer_name
|
||||
project = var.project_id
|
||||
https_redirect = true
|
||||
ssl = local.use_lb_ssl
|
||||
managed_ssl_certificate_domains = local.managed_ssl_domains
|
||||
certificate_map = local.cert_manager_map_name
|
||||
firewall_networks = []
|
||||
firewall_projects = []
|
||||
backends = local.public_load_balancer_backends
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy Kasm Database
|
||||
*/
|
||||
## Database Instance
|
||||
module "database_instance" {
|
||||
source = "./modules/compute_instance"
|
||||
instance_details = var.database_vm_instance_config
|
||||
instance_network = local.vpc_network_self_link
|
||||
instance_subnetwork = "${var.kasm_deployment_regions[0]}-database-subnet"
|
||||
source_image = [var.kasm_source_image]
|
||||
service_account = [var.compute_service_account]
|
||||
cloud_init_script = local.database_startup_config
|
||||
security_tags = var.kasm_firewall_security_tags.database
|
||||
resource_labels = local.resource_labels
|
||||
public_access_config = []
|
||||
kasm_region = var.kasm_deployment_regions[0]
|
||||
|
||||
depends_on = [ module.vpc ]
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy Kasm Agents
|
||||
*/
|
||||
## Agent Instances
|
||||
module "agent_instances" {
|
||||
source = "./modules/compute_instance"
|
||||
for_each = toset(var.kasm_deployment_regions)
|
||||
|
||||
number_of_instances = var.number_of_agents_per_region
|
||||
instance_details = var.agent_vm_instance_config
|
||||
instance_network = local.vpc_network_self_link
|
||||
instance_subnetwork = "${each.key}-agent-subnet"
|
||||
source_image = [var.kasm_source_image]
|
||||
service_account = [var.compute_service_account]
|
||||
cloud_init_script = local.agent_startup_configs[each.key]
|
||||
security_tags = var.kasm_firewall_security_tags.agent
|
||||
resource_labels = local.resource_labels
|
||||
public_access_config = local.agent_public_ip
|
||||
kasm_region = each.key
|
||||
|
||||
depends_on = [ module.vpc ]
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy Kasm Connection Proxy (CPX/Guac)
|
||||
*/
|
||||
## Create Kasm CPX Instance templates
|
||||
module "cpx_instance_template" {
|
||||
source = "terraform-google-modules/vm/google//modules/instance_template"
|
||||
version = "~> 11.0"
|
||||
for_each = var.deploy_connection_proxy ? toset(var.kasm_deployment_regions) : []
|
||||
|
||||
project_id = var.project_id
|
||||
network = local.vpc_network_self_link
|
||||
subnetwork = "${each.key}-cpx-subnet"
|
||||
region = each.key
|
||||
service_account = var.compute_service_account
|
||||
name_prefix = substr("${each.key}-${var.cpx_hostname_prefix}-template", 0, 63)
|
||||
source_image_project = var.kasm_source_image.project
|
||||
source_image_family = var.kasm_source_image.family
|
||||
machine_type = var.cpx_vm_instance_config.machine_type
|
||||
disk_size_gb = var.cpx_vm_instance_config.disk_size_gb
|
||||
disk_type = var.cpx_vm_instance_config.disk_type
|
||||
tags = var.kasm_firewall_security_tags.webapp
|
||||
startup_script = local.cpx_startup_configs[each.key]
|
||||
labels = local.resource_labels
|
||||
|
||||
depends_on = [ module.vpc ]
|
||||
}
|
||||
|
||||
## Create Kasm Webapp Instance groups
|
||||
module "cpx_instance_group" {
|
||||
source = "terraform-google-modules/vm/google//modules/mig"
|
||||
version = "~> 11.0"
|
||||
for_each = var.deploy_connection_proxy ? toset(var.kasm_deployment_regions) : []
|
||||
|
||||
project_id = var.project_id
|
||||
mig_name = "${each.key}-cpx-instance-group"
|
||||
instance_template = local.cpx_instance_template_self_link[each.key]
|
||||
region = each.key
|
||||
hostname = "${each.key}-${var.cpx_hostname_prefix}-group"
|
||||
named_ports = var.cpx_named_ports
|
||||
autoscaling_enabled = true
|
||||
max_replicas = var.cpx_autoscale_max_instances
|
||||
min_replicas = var.cpx_autoscale_min_instances
|
||||
cooldown_period = var.cpx_autoscale_cool_down_period
|
||||
autoscaling_cpu = var.cpx_autoscale_scale_out_cpu
|
||||
autoscaling_scale_in_control = var.cpx_autoscale_scale_in_settings
|
||||
}
|
||||
|
||||
/*
|
||||
* Deploy DNS
|
||||
*/
|
||||
## Public DNS Zone
|
||||
module "dns_public_zone" {
|
||||
source = "terraform-google-modules/cloud-dns/google"
|
||||
version = "~> 5.0"
|
||||
count = var.create_public_dns_zone ? 1 : 0
|
||||
|
||||
type = "public"
|
||||
project_id = var.project_id
|
||||
name = var.public_dns_friendly_name
|
||||
domain = "${var.kasm_domain_name}."
|
||||
recordsets = local.public_dns_records
|
||||
}
|
||||
|
||||
## Add records to existing public DNS zone (e.g. this TF didn't create the public zone)
|
||||
module "dns_public_records" {
|
||||
source = "./modules/dns_records"
|
||||
count = var.create_public_dns_zone ? 0 : 1
|
||||
|
||||
project_id = var.project_id
|
||||
name = var.public_dns_friendly_name
|
||||
domain = var.kasm_domain_name
|
||||
recordsets = local.public_dns_records
|
||||
}
|
||||
|
||||
## Private DNS Zone
|
||||
module "dns_private_zone" {
|
||||
source = "terraform-google-modules/cloud-dns/google"
|
||||
version = "~> 5.0"
|
||||
|
||||
type = "private"
|
||||
project_id = var.project_id
|
||||
name = var.private_dns_friendly_name
|
||||
domain = "private.${var.kasm_domain_name}."
|
||||
private_visibility_config_networks = [local.vpc_network_self_link]
|
||||
recordsets = local.private_dns_records
|
||||
}
|
||||
|
||||
/*
|
||||
* Create Kasm Autoscale service IAM account
|
||||
*/
|
||||
module "kasm_autoscale_service_account" {
|
||||
source = "./modules/service_account_iam"
|
||||
count = var.create_kasm_autoscale_service_account ? 1 : 0
|
||||
|
||||
project_id = var.project_id
|
||||
account_id = var.service_account_name
|
||||
}
|
||||
|
||||
/*
|
||||
* Create passwords (always run, but not alwayse used). Refer
|
||||
* to locals.tf for conditional usage.
|
||||
*/
|
||||
module "passwords" {
|
||||
source = "./modules/random"
|
||||
count = 6
|
||||
kasm_version = var.kasm_version
|
||||
}
|
||||
|
||||
/*
|
||||
* Create Public GCP-managed SSL cert in Cert Manager
|
||||
*
|
||||
* Using Certificate manager only works with this Terraform if you deploy it independently,
|
||||
* then reference the created certificate map ID directly. There is a concurrency issue
|
||||
* with Terraform that causes problems, so, this and the referenced module serve as an
|
||||
* example deployment method until this issue is resolved.
|
||||
*/
|
||||
# module "certificate_manager" {
|
||||
# source = "./modules/certificate_manager"
|
||||
# count = var.use_gcp_certificate_manager ? 1 : 0
|
||||
|
||||
# domain_name = var.kasm_domain_name
|
||||
# dns_managed_zone_name = local.public_dns_name
|
||||
# certificate_name = local.tls_certificate_name
|
||||
# certificate_dns_authorization_name = local.tls_certificate_dns_auth_name
|
||||
# certificate_map_name = local.tls_certificate_map_name
|
||||
# resource_labels = var.resource_labels
|
||||
# }
|
||||
50
gcp/modules/certificate_manager/README.md
Normal file
50
gcp/modules/certificate_manager/README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_google"></a> [google](#provider\_google) | 4.81.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [google_certificate_manager_certificate.cert](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/certificate_manager_certificate) | resource |
|
||||
| [google_certificate_manager_certificate_map.cert_map](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/certificate_manager_certificate_map) | resource |
|
||||
| [google_certificate_manager_certificate_map_entry.cert_map_entry](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/certificate_manager_certificate_map_entry) | resource |
|
||||
| [google_certificate_manager_dns_authorization.cert_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/certificate_manager_dns_authorization) | resource |
|
||||
| [google_dns_record_set.cert_dns_record](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_certificate_description"></a> [certificate\_description](#input\_certificate\_description) | Certificate description | `string` | `"Global Load Balancer SSL Certificate"` | no |
|
||||
| <a name="input_certificate_dns_authorization_description"></a> [certificate\_dns\_authorization\_description](#input\_certificate\_dns\_authorization\_description) | Description of the DNS Authorization job in Certificate Manager | `string` | `"Global Load Balancer certificate DNS authorization"` | no |
|
||||
| <a name="input_certificate_dns_authorization_name"></a> [certificate\_dns\_authorization\_name](#input\_certificate\_dns\_authorization\_name) | The name of the DNS Authorization job in Certificate Manager | `string` | n/a | yes |
|
||||
| <a name="input_certificate_map_description"></a> [certificate\_map\_description](#input\_certificate\_map\_description) | Description of the certificate map | `string` | `"Global HTTPS Load Balancer Certificate Map"` | no |
|
||||
| <a name="input_certificate_map_name"></a> [certificate\_map\_name](#input\_certificate\_map\_name) | Certificate map name | `string` | n/a | yes |
|
||||
| <a name="input_certificate_name"></a> [certificate\_name](#input\_certificate\_name) | Certificate name in Certificate manager. Must be globally unique. | `string` | n/a | yes |
|
||||
| <a name="input_certificate_scope"></a> [certificate\_scope](#input\_certificate\_scope) | GCP Certificate scope | `string` | `"DEFAULT"` | no |
|
||||
| <a name="input_create_wildcard"></a> [create\_wildcard](#input\_create\_wildcard) | Add wildcard domain to certificate | `bool` | `true` | no |
|
||||
| <a name="input_dns_managed_zone_name"></a> [dns\_managed\_zone\_name](#input\_dns\_managed\_zone\_name) | The name of the GCP DNS zone | `string` | n/a | yes |
|
||||
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Kasm deployment domain name | `string` | n/a | yes |
|
||||
| <a name="input_resource_labels"></a> [resource\_labels](#input\_resource\_labels) | Labels to add to all created resources in this project | `map(any)` | `{}` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_certificate_map_id"></a> [certificate\_map\_id](#output\_certificate\_map\_id) | The value of the generated certificate map for use with the external load balancer |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
47
gcp/modules/certificate_manager/certificate_manager.tf
Normal file
47
gcp/modules/certificate_manager/certificate_manager.tf
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
resource "google_certificate_manager_dns_authorization" "cert_auth" {
|
||||
name = var.certificate_dns_authorization_name
|
||||
description = var.certificate_dns_authorization_description
|
||||
domain = var.domain_name
|
||||
labels = var.resource_labels
|
||||
}
|
||||
|
||||
resource "google_dns_record_set" "cert_dns_record" {
|
||||
name = google_certificate_manager_dns_authorization.cert_auth.dns_resource_record[0].name
|
||||
type = "CNAME"
|
||||
ttl = 30
|
||||
managed_zone = var.dns_managed_zone_name
|
||||
rrdatas = [google_certificate_manager_dns_authorization.cert_auth.dns_resource_record[0].data]
|
||||
}
|
||||
|
||||
resource "google_certificate_manager_certificate" "cert" {
|
||||
name = var.certificate_name
|
||||
description = var.certificate_description
|
||||
scope = var.certificate_scope
|
||||
labels = var.resource_labels
|
||||
|
||||
managed {
|
||||
domains = compact([
|
||||
google_certificate_manager_dns_authorization.cert_auth.domain,
|
||||
var.create_wildcard ? "*.${google_certificate_manager_dns_authorization.cert_auth.domain}" : ""
|
||||
])
|
||||
dns_authorizations = [
|
||||
google_certificate_manager_dns_authorization.cert_auth.id
|
||||
]
|
||||
}
|
||||
|
||||
depends_on = [google_dns_record_set.cert_dns_record]
|
||||
}
|
||||
|
||||
resource "google_certificate_manager_certificate_map" "cert_map" {
|
||||
name = var.certificate_map_name
|
||||
description = var.certificate_map_description
|
||||
labels = var.resource_labels
|
||||
}
|
||||
|
||||
resource "google_certificate_manager_certificate_map_entry" "cert_map_entry" {
|
||||
name = "${var.certificate_map_name}-entry"
|
||||
map = google_certificate_manager_certificate_map.cert_map.name
|
||||
certificates = [google_certificate_manager_certificate.cert.id]
|
||||
matcher = "PRIMARY"
|
||||
labels = var.resource_labels
|
||||
}
|
||||
4
gcp/modules/certificate_manager/outputs.tf
Normal file
4
gcp/modules/certificate_manager/outputs.tf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
output "certificate_map_id" {
|
||||
description = "The value of the generated certificate map for use with the external load balancer"
|
||||
value = google_certificate_manager_certificate_map.cert_map.id
|
||||
}
|
||||
9
gcp/modules/certificate_manager/provider.tf
Normal file
9
gcp/modules/certificate_manager/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
81
gcp/modules/certificate_manager/variables.tf
Normal file
81
gcp/modules/certificate_manager/variables.tf
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
variable "domain_name" {
|
||||
description = "Kasm deployment domain name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "dns_managed_zone_name" {
|
||||
description = "The name of the GCP DNS zone"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "certificate_name" {
|
||||
description = "Certificate name in Certificate manager. Must be globally unique."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]{5,63}", var.certificate_name))
|
||||
error_message = "The certificate_name must be globally unique, and can only be between 5-63 characters consisting of only lower case letters, number, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "certificate_dns_authorization_name" {
|
||||
description = "The name of the DNS Authorization job in Certificate Manager"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]{5,63}", var.certificate_dns_authorization_name))
|
||||
error_message = "The certificate_dns_authorization_name must be globally unique, and can only be between 5-63 characters consisting of only lower case letters, number, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "certificate_map_name" {
|
||||
description = "Certificate map name"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]{5,63}", var.certificate_map_name))
|
||||
error_message = "The certificate_map_name must be globally unique, and can only be between 5-63 characters consisting of only lower case letters, number, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
## Pre-set values
|
||||
variable "certificate_description" {
|
||||
description = "Certificate description"
|
||||
type = string
|
||||
default = "Global Load Balancer SSL Certificate"
|
||||
}
|
||||
|
||||
variable "certificate_dns_authorization_description" {
|
||||
description = "Description of the DNS Authorization job in Certificate Manager"
|
||||
type = string
|
||||
default = "Global Load Balancer certificate DNS authorization"
|
||||
}
|
||||
|
||||
variable "certificate_map_description" {
|
||||
description = "Description of the certificate map"
|
||||
type = string
|
||||
default = "Global HTTPS Load Balancer Certificate Map"
|
||||
}
|
||||
|
||||
variable "certificate_scope" {
|
||||
description = "GCP Certificate scope"
|
||||
type = string
|
||||
default = "DEFAULT"
|
||||
|
||||
validation {
|
||||
condition = contains(["DEFAULT", "EDGE_CACHE"], var.certificate_scope)
|
||||
error_message = "The certificate_scope variable can only be one of: DEFAULT or EDGE_CACHE."
|
||||
}
|
||||
}
|
||||
|
||||
variable "create_wildcard" {
|
||||
description = "Add wildcard domain to certificate"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "resource_labels" {
|
||||
description = "Labels to add to all created resources in this project"
|
||||
type = map(any)
|
||||
default = {}
|
||||
}
|
||||
56
gcp/modules/compute_instance/README.md
Normal file
56
gcp/modules/compute_instance/README.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_google"></a> [google](#provider\_google) | 4.70.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [google_compute_instance.kasm_instance](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) | resource |
|
||||
| [google_compute_image.kasm_image](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_image) | data source |
|
||||
| [google_compute_zones.available](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_zones) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_allow_stopping_for_update"></a> [allow\_stopping\_for\_update](#input\_allow\_stopping\_for\_update) | Allow GCP service accounts to stop the instance and initiate an updates | `bool` | `false` | no |
|
||||
| <a name="input_cloud_init_script"></a> [cloud\_init\_script](#input\_cloud\_init\_script) | Startup script used to provision the instance | `list(string)` | n/a | yes |
|
||||
| <a name="input_enable_instance_vtpm"></a> [enable\_instance\_vtpm](#input\_enable\_instance\_vtpm) | Enable the Trusted Platform Module to secure the instance | `bool` | `true` | no |
|
||||
| <a name="input_enable_integrity_monitoring"></a> [enable\_integrity\_monitoring](#input\_enable\_integrity\_monitoring) | Enable instance integrity monitoring | `bool` | `true` | no |
|
||||
| <a name="input_enable_secure_boot"></a> [enable\_secure\_boot](#input\_enable\_secure\_boot) | Enable instance secure boot | `bool` | `null` | no |
|
||||
| <a name="input_instance_delete_protection"></a> [instance\_delete\_protection](#input\_instance\_delete\_protection) | Prevent instance from accidental deletion | `bool` | `true` | no |
|
||||
| <a name="input_instance_details"></a> [instance\_details](#input\_instance\_details) | Instance details to configure for Kasm instance | <pre>object({<br> machine_type = string<br> disk_size_gb = number<br> instance_role = string<br> name = optional(string, "")<br> name_prefix = optional(string, "")<br> disk_auto_delete = optional(bool, true)<br> description = optional(string, null)<br> disk_type = optional(string, "pd-balanced")<br> })</pre> | n/a | yes |
|
||||
| <a name="input_instance_network"></a> [instance\_network](#input\_instance\_network) | VPC Network self\_link where instance is to be deployed. Usually inferred by the subnetwork, however, if subnetwork names overlap, this can create confusion. This value is optional, and required if subnetwork names are reused across VPCs. | `string` | `null` | no |
|
||||
| <a name="input_instance_nic_stack_type"></a> [instance\_nic\_stack\_type](#input\_instance\_nic\_stack\_type) | The default network interface type | `string` | `"IPV4_ONLY"` | no |
|
||||
| <a name="input_instance_nic_type"></a> [instance\_nic\_type](#input\_instance\_nic\_type) | The default network interface type | `string` | `"GVNIC"` | no |
|
||||
| <a name="input_instance_subnetwork"></a> [instance\_subnetwork](#input\_instance\_subnetwork) | Name of subnetwork where to deploy the instance | `string` | n/a | yes |
|
||||
| <a name="input_kasm_region"></a> [kasm\_region](#input\_kasm\_region) | GCP region in which to deploy this Kasm instance | `string` | n/a | yes |
|
||||
| <a name="input_number_of_instances"></a> [number\_of\_instances](#input\_number\_of\_instances) | Number of instances to deploy in this region | `number` | `1` | no |
|
||||
| <a name="input_public_access_config"></a> [public\_access\_config](#input\_public\_access\_config) | Enable public IP access for instance | <pre>list(object({<br> nat_ip = optional(string)<br> public_ptr_domain_name = optional(string)<br> network_tier = optional(string)<br> }))</pre> | n/a | yes |
|
||||
| <a name="input_resource_labels"></a> [resource\_labels](#input\_resource\_labels) | Labels to apply to the instance | `map(any)` | `null` | no |
|
||||
| <a name="input_security_tags"></a> [security\_tags](#input\_security\_tags) | Security tags to use with firewall rules to allow instance access | `list(string)` | n/a | yes |
|
||||
| <a name="input_service_account"></a> [service\_account](#input\_service\_account) | Service account to use for instance auto updates | <pre>list(object({<br> email = optional(string)<br> scopes = list(string)<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_source_image"></a> [source\_image](#input\_source\_image) | The source VM Image information to use for deploying Kasm. Recommended to use Ubuntu 20.04 Minimal. You can either explicitly define the source image to use, or the image project and family so that Terraform always chooses the latest. | <pre>list(object({<br> source_image = optional(string, null)<br> project = optional(string, null)<br> family = optional(string, null)<br> }))</pre> | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_private_ip"></a> [private\_ip](#output\_private\_ip) | Instance private IP address. |
|
||||
| <a name="output_public_ip"></a> [public\_ip](#output\_public\_ip) | Instance public IP address (if applicable) |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
68
gcp/modules/compute_instance/compute.tf
Normal file
68
gcp/modules/compute_instance/compute.tf
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
data "google_compute_image" "kasm_image" {
|
||||
project = var.source_image[0].project
|
||||
family = var.source_image[0].family
|
||||
name = var.source_image[0].source_image
|
||||
}
|
||||
|
||||
data "google_compute_zones" "available" {
|
||||
region = var.kasm_region
|
||||
}
|
||||
|
||||
resource "google_compute_instance" "kasm_instance" {
|
||||
count = var.number_of_instances
|
||||
name = var.instance_details.name == "" ? substr("${var.kasm_region}-${var.instance_details.name_prefix}-0${count.index + 1}", 0, 63) : var.instance_details.name
|
||||
description = var.instance_details.description
|
||||
machine_type = var.instance_details.machine_type
|
||||
deletion_protection = var.instance_details.instance_role == "agent" ? false : var.instance_delete_protection
|
||||
tags = var.security_tags
|
||||
labels = var.resource_labels
|
||||
allow_stopping_for_update = var.allow_stopping_for_update
|
||||
metadata_startup_script = var.cloud_init_script[count.index]
|
||||
zone = data.google_compute_zones.available.names[count.index]
|
||||
|
||||
boot_disk {
|
||||
auto_delete = var.instance_details.disk_auto_delete
|
||||
initialize_params {
|
||||
size = var.instance_details.disk_size_gb
|
||||
type = var.instance_details.disk_type
|
||||
image = data.google_compute_image.kasm_image.self_link
|
||||
labels = var.resource_labels
|
||||
}
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = var.instance_network
|
||||
subnetwork = var.instance_subnetwork
|
||||
nic_type = var.instance_nic_type
|
||||
stack_type = var.instance_nic_stack_type
|
||||
|
||||
dynamic "access_config" {
|
||||
for_each = var.public_access_config
|
||||
content {
|
||||
nat_ip = lookup(access_config.value, "nat_ip", null)
|
||||
public_ptr_domain_name = lookup(access_config.value, "public_ptr_domain_name", null)
|
||||
network_tier = lookup(access_config.value, "network_tier", null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shielded_instance_config {
|
||||
enable_secure_boot = var.enable_secure_boot
|
||||
enable_vtpm = var.enable_instance_vtpm
|
||||
enable_integrity_monitoring = var.enable_integrity_monitoring
|
||||
}
|
||||
|
||||
dynamic "service_account" {
|
||||
for_each = var.service_account
|
||||
content {
|
||||
email = lookup(service_account.value, "email", null)
|
||||
scopes = lookup(service_account.value, "scopes", null)
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
metadata["ssh-keys"]
|
||||
]
|
||||
}
|
||||
}
|
||||
12
gcp/modules/compute_instance/outputs.tf
Normal file
12
gcp/modules/compute_instance/outputs.tf
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
## Deploy Ksam Database
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
output "private_ip" {
|
||||
description = "Instance private IP address."
|
||||
value = google_compute_instance.kasm_instance[*].network_interface[0].network_ip
|
||||
}
|
||||
|
||||
output "public_ip" {
|
||||
description = "Instance public IP address (if applicable)"
|
||||
value = google_compute_instance.kasm_instance[*].network_interface[0].access_config
|
||||
}
|
||||
9
gcp/modules/compute_instance/provider.tf
Normal file
9
gcp/modules/compute_instance/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
152
gcp/modules/compute_instance/variables.tf
Normal file
152
gcp/modules/compute_instance/variables.tf
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
variable "instance_details" {
|
||||
description = "Instance details to configure for Kasm instance"
|
||||
type = object({
|
||||
machine_type = string
|
||||
disk_size_gb = number
|
||||
instance_role = string
|
||||
name = optional(string, "")
|
||||
name_prefix = optional(string, "")
|
||||
disk_auto_delete = optional(bool, true)
|
||||
description = optional(string, null)
|
||||
disk_type = optional(string, "pd-balanced")
|
||||
})
|
||||
|
||||
validation {
|
||||
condition = contains(["database", "webapp", "agent", "cpx"], var.instance_details.instance_role)
|
||||
error_message = "The instance_details name attribute can only be a max of 63 characters consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
validation {
|
||||
condition = var.instance_details.name == "" ? true : can(regex("^[a-z0-9-]{4,63}", var.instance_details.name))
|
||||
error_message = "The instance_details name attribute can only be a max of 63 characters consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
validation {
|
||||
condition = var.instance_details.name_prefix == "" ? true : can(regex("^[a-z0-9-]{4,63}", var.instance_details.name_prefix))
|
||||
error_message = "The instance_details name_prefix attribute can only be a max of 63 characters consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
validation {
|
||||
condition = var.instance_details.disk_size_gb > 30
|
||||
error_message = "The instance_details disk_size_gb should be larger than 30GB to support Kasm, logging, and other required services. Recommended minimum size is 50GB."
|
||||
}
|
||||
validation {
|
||||
condition = contains(["pd-standard", "pd-balanced", "pd-ssd", "pd-extreme"], var.instance_details.disk_type)
|
||||
error_message = "The disk_type can only be one of pd-standard, pd-balanced, pd-extreme, or pd-ssd. Refer to https://cloud.google.com/compute/docs/disks for more details."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_region" {
|
||||
description = "GCP region in which to deploy this Kasm instance"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "security_tags" {
|
||||
description = "Security tags to use with firewall rules to allow instance access"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "cloud_init_script" {
|
||||
description = "Startup script used to provision the instance"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "instance_subnetwork" {
|
||||
description = "Name of subnetwork where to deploy the instance"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "source_image" {
|
||||
description = "The source VM Image information to use for deploying Kasm. Recommended to use Ubuntu 20.04 Minimal. You can either explicitly define the source image to use, or the image project and family so that Terraform always chooses the latest."
|
||||
type = list(object({
|
||||
source_image = optional(string, null)
|
||||
project = optional(string, null)
|
||||
family = optional(string, null)
|
||||
}))
|
||||
}
|
||||
|
||||
## Pre-set values
|
||||
variable "number_of_instances" {
|
||||
description = "Number of instances to deploy in this region"
|
||||
type = number
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "instance_network" {
|
||||
description = "VPC Network self_link where instance is to be deployed. Usually inferred by the subnetwork, however, if subnetwork names overlap, this can create confusion. This value is optional, and required if subnetwork names are reused across VPCs."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "allow_stopping_for_update" {
|
||||
description = "Allow GCP service accounts to stop the instance and initiate an updates"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "instance_delete_protection" {
|
||||
description = "Prevent instance from accidental deletion"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "instance_nic_type" {
|
||||
description = "The default network interface type"
|
||||
type = string
|
||||
default = "GVNIC"
|
||||
|
||||
validation {
|
||||
condition = contains(["GVNIC", "VIRTIO_NET"], var.instance_nic_type)
|
||||
error_message = "The instance_nic_type can only be one of GVNIC or VIRTIO_NET. GVNIC currently offers enhanced performance and capabilities. Refer to this document (https://cloud.google.com/compute/docs/networking/using-gvnic) for more information."
|
||||
}
|
||||
}
|
||||
|
||||
variable "instance_nic_stack_type" {
|
||||
description = "The default network interface type"
|
||||
type = string
|
||||
default = "IPV4_ONLY"
|
||||
|
||||
validation {
|
||||
condition = contains(["IPV4_ONLY", "IPV4_IPV6"], var.instance_nic_stack_type)
|
||||
error_message = "The instance_nic_stack_type can only be one of IPV4_ONLY or IPV4_IPV6. Kasm recommends IPV4_ONLY since IPv6 is supported, but it requires additional, custom configuration by the administrator. Only enable IPv6 if you know what you are doing. Refer to this write up for more information: https://www.reddit.com/r/kasmweb/comments/sg6tv9/guide_enabling_ipv6_on_your_kasmweb_server/."
|
||||
}
|
||||
}
|
||||
|
||||
variable "enable_secure_boot" {
|
||||
description = "Enable instance secure boot"
|
||||
type = bool
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "enable_instance_vtpm" {
|
||||
description = "Enable the Trusted Platform Module to secure the instance"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "enable_integrity_monitoring" {
|
||||
description = "Enable instance integrity monitoring"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_access_config" {
|
||||
description = "Enable public IP access for instance"
|
||||
type = list(object({
|
||||
nat_ip = optional(string)
|
||||
public_ptr_domain_name = optional(string)
|
||||
network_tier = optional(string)
|
||||
}))
|
||||
}
|
||||
|
||||
variable "service_account" {
|
||||
description = "Service account to use for instance auto updates"
|
||||
type = list(object({
|
||||
email = optional(string)
|
||||
scopes = list(string)
|
||||
}))
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "resource_labels" {
|
||||
description = "Labels to apply to the instance"
|
||||
type = map(any)
|
||||
default = null
|
||||
}
|
||||
37
gcp/modules/dns_records/README.md
Normal file
37
gcp/modules/dns_records/README.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_google"></a> [google](#provider\_google) | 4.81.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [google_dns_record_set.records](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_domain"></a> [domain](#input\_domain) | Zone domain, must end with a period. | `string` | n/a | yes |
|
||||
| <a name="input_name"></a> [name](#input\_name) | Zone name, must be unique within the project. | `string` | n/a | yes |
|
||||
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | Project id for the zone. | `string` | n/a | yes |
|
||||
| <a name="input_recordsets"></a> [recordsets](#input\_recordsets) | List of DNS record objects to manage, in the standard terraform dns structure. | <pre>list(object({<br> name = string<br> type = string<br> ttl = number<br> records = list(string)<br> }))</pre> | `[]` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
No outputs.
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
11
gcp/modules/dns_records/dns.tf
Normal file
11
gcp/modules/dns_records/dns.tf
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
resource "google_dns_record_set" "records" {
|
||||
project = var.project_id
|
||||
managed_zone = var.name
|
||||
|
||||
for_each = { for record in var.recordsets : join("/", [record.name, record.type]) => record }
|
||||
name = (each.value.name != "" ? "${each.value.name}.${var.domain}." : "${var.domain}.")
|
||||
type = each.value.type
|
||||
ttl = each.value.ttl
|
||||
|
||||
rrdatas = each.value.records
|
||||
}
|
||||
9
gcp/modules/dns_records/provider.tf
Normal file
9
gcp/modules/dns_records/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
25
gcp/modules/dns_records/variables.tf
Normal file
25
gcp/modules/dns_records/variables.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
variable "project_id" {
|
||||
description = "Project id for the zone."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Zone domain, must end with a period."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Zone name, must be unique within the project."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "recordsets" {
|
||||
type = list(object({
|
||||
name = string
|
||||
type = string
|
||||
ttl = number
|
||||
records = list(string)
|
||||
}))
|
||||
description = "List of DNS record objects to manage, in the standard terraform dns structure."
|
||||
default = []
|
||||
}
|
||||
0
gcp/modules/private_load_balancer/README copy.md
Normal file
0
gcp/modules/private_load_balancer/README copy.md
Normal file
60
gcp/modules/private_load_balancer/README.md
Normal file
60
gcp/modules/private_load_balancer/README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_google"></a> [google](#provider\_google) | 4.81.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [google_compute_forwarding_rule.default](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_forwarding_rule) | resource |
|
||||
| [google_compute_region_backend_service.default](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_backend_service) | resource |
|
||||
| [google_compute_region_health_check.tcp](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_health_check) | resource |
|
||||
| [google_compute_region_target_tcp_proxy.default](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_region_target_tcp_proxy) | resource |
|
||||
| [google_compute_network.network](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_network) | data source |
|
||||
| [google_compute_subnetwork.network](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_subnetwork) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_backend_timeout_sec"></a> [backend\_timeout\_sec](#input\_backend\_timeout\_sec) | Backend timeout | `number` | `30` | no |
|
||||
| <a name="input_backends"></a> [backends](#input\_backends) | List of backends, should be a map of key-value pairs for each backend, must have the 'group' key. | `list(any)` | n/a | yes |
|
||||
| <a name="input_connection_draining_timeout_sec"></a> [connection\_draining\_timeout\_sec](#input\_connection\_draining\_timeout\_sec) | Time for which instance will be drained | `number` | `300` | no |
|
||||
| <a name="input_global_access"></a> [global\_access](#input\_global\_access) | Allow all regions on the same VPC network access. | `bool` | `false` | no |
|
||||
| <a name="input_health_check"></a> [health\_check](#input\_health\_check) | Health check to determine whether instances are responsive and able to do work | <pre>object({<br> type = string<br> check_interval_sec = number<br> healthy_threshold = number<br> timeout_sec = number<br> unhealthy_threshold = number<br> response = string<br> proxy_header = string<br> port = number<br> port_name = string<br> request = string<br> request_path = string<br> host = string<br> enable_log = bool<br> })</pre> | n/a | yes |
|
||||
| <a name="input_ip_protocol"></a> [ip\_protocol](#input\_ip\_protocol) | The IP protocol for the backend and frontend forwarding rule. TCP or UDP. | `string` | `"TCP"` | no |
|
||||
| <a name="input_labels"></a> [labels](#input\_labels) | The labels to attach to resources created by this module. | `map(string)` | `{}` | no |
|
||||
| <a name="input_load_balancing_policy"></a> [load\_balancing\_policy](#input\_load\_balancing\_policy) | The load balancing policy to use | `string` | `"ROUND_ROBIN"` | no |
|
||||
| <a name="input_load_balancing_scheme"></a> [load\_balancing\_scheme](#input\_load\_balancing\_scheme) | The load balancing scheme to use. The default is INTERNAL | `string` | `"INTERNAL_MANAGED"` | no |
|
||||
| <a name="input_name"></a> [name](#input\_name) | Name for the forwarding rule and prefix for supporting resources. | `string` | n/a | yes |
|
||||
| <a name="input_named_port"></a> [named\_port](#input\_named\_port) | Named port to allow access to the LB or resources through the VPC FW | `string` | n/a | yes |
|
||||
| <a name="input_network"></a> [network](#input\_network) | Name of the network to create resources in. | `string` | `"default"` | no |
|
||||
| <a name="input_network_project"></a> [network\_project](#input\_network\_project) | Name of the project for the network. Useful for shared VPC. Default is var.project. | `string` | `""` | no |
|
||||
| <a name="input_port_range"></a> [port\_range](#input\_port\_range) | List of ports range to forward to backend services. Max is 5. | `string` | n/a | yes |
|
||||
| <a name="input_project"></a> [project](#input\_project) | The project to deploy to, if not set the default provider project is used. | `string` | `""` | no |
|
||||
| <a name="input_region"></a> [region](#input\_region) | Region for cloud resources. | `string` | n/a | yes |
|
||||
| <a name="input_session_affinity"></a> [session\_affinity](#input\_session\_affinity) | The session affinity for the backends example: NONE, CLIENT\_IP. Default is `NONE`. | `string` | `"NONE"` | no |
|
||||
| <a name="input_subnetwork"></a> [subnetwork](#input\_subnetwork) | Name of the subnetwork to create resources in. | `string` | `"default"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_forwarding_rule"></a> [forwarding\_rule](#output\_forwarding\_rule) | The forwarding rule self\_link. |
|
||||
| <a name="output_forwarding_rule_id"></a> [forwarding\_rule\_id](#output\_forwarding\_rule\_id) | The forwarding rule id. |
|
||||
| <a name="output_ip_address"></a> [ip\_address](#output\_ip\_address) | The internal IP assigned to the regional forwarding rule. |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
81
gcp/modules/private_load_balancer/load_balancer.tf
Normal file
81
gcp/modules/private_load_balancer/load_balancer.tf
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
data "google_compute_network" "network" {
|
||||
name = var.network
|
||||
project = var.network_project == "" ? var.project : var.network_project
|
||||
}
|
||||
|
||||
data "google_compute_subnetwork" "network" {
|
||||
name = var.subnetwork
|
||||
project = var.network_project == "" ? var.project : var.network_project
|
||||
region = var.region
|
||||
}
|
||||
|
||||
resource "google_compute_forwarding_rule" "default" {
|
||||
project = var.project
|
||||
name = var.name
|
||||
region = var.region
|
||||
network = data.google_compute_network.network.self_link
|
||||
subnetwork = data.google_compute_subnetwork.network.self_link
|
||||
allow_global_access = var.global_access
|
||||
load_balancing_scheme = var.load_balancing_scheme
|
||||
network_tier = "PREMIUM"
|
||||
ip_protocol = var.ip_protocol
|
||||
port_range = var.port_range
|
||||
labels = var.labels
|
||||
target = google_compute_region_target_tcp_proxy.default.self_link
|
||||
}
|
||||
|
||||
resource "google_compute_region_target_tcp_proxy" "default" {
|
||||
region = var.region
|
||||
name = "${var.name}-target-proxy"
|
||||
proxy_header = "NONE"
|
||||
backend_service = google_compute_region_backend_service.default.self_link
|
||||
}
|
||||
|
||||
resource "google_compute_region_backend_service" "default" {
|
||||
project = var.project
|
||||
name = "${var.name}-backend-service"
|
||||
region = var.region
|
||||
protocol = var.ip_protocol
|
||||
locality_lb_policy = var.load_balancing_policy
|
||||
port_name = var.named_port
|
||||
session_affinity = var.session_affinity
|
||||
timeout_sec = var.backend_timeout_sec
|
||||
load_balancing_scheme = "INTERNAL_MANAGED"
|
||||
connection_draining_timeout_sec = var.connection_draining_timeout_sec
|
||||
dynamic "backend" {
|
||||
for_each = var.backends
|
||||
content {
|
||||
group = lookup(backend.value, "group", null)
|
||||
description = lookup(backend.value, "description", null)
|
||||
max_utilization = lookup(backend.value, "max_utilization", null)
|
||||
balancing_mode = lookup(backend.value, "balancing_mode", null)
|
||||
capacity_scaler = lookup(backend.value, "capacity_scaler", null)
|
||||
failover = lookup(backend.value, "failover", null)
|
||||
}
|
||||
}
|
||||
health_checks = [google_compute_region_health_check.tcp.self_link]
|
||||
}
|
||||
|
||||
resource "google_compute_region_health_check" "tcp" {
|
||||
project = var.project
|
||||
name = "${var.name}-hc-tcp"
|
||||
region = var.region
|
||||
timeout_sec = var.health_check["timeout_sec"]
|
||||
check_interval_sec = var.health_check["check_interval_sec"]
|
||||
healthy_threshold = var.health_check["healthy_threshold"]
|
||||
unhealthy_threshold = var.health_check["unhealthy_threshold"]
|
||||
|
||||
https_health_check {
|
||||
port = var.health_check["port"]
|
||||
port_name = var.health_check["port_name"]
|
||||
request_path = var.health_check["request_path"]
|
||||
proxy_header = var.health_check["proxy_header"]
|
||||
}
|
||||
|
||||
dynamic "log_config" {
|
||||
for_each = var.health_check["enable_log"] ? [true] : []
|
||||
content {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
14
gcp/modules/private_load_balancer/outputs.tf
Normal file
14
gcp/modules/private_load_balancer/outputs.tf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
output "ip_address" {
|
||||
description = "The internal IP assigned to the regional forwarding rule."
|
||||
value = google_compute_forwarding_rule.default.ip_address
|
||||
}
|
||||
|
||||
output "forwarding_rule" {
|
||||
description = "The forwarding rule self_link."
|
||||
value = google_compute_forwarding_rule.default.self_link
|
||||
}
|
||||
|
||||
output "forwarding_rule_id" {
|
||||
description = "The forwarding rule id."
|
||||
value = google_compute_forwarding_rule.default.id
|
||||
}
|
||||
9
gcp/modules/private_load_balancer/provider.tf
Normal file
9
gcp/modules/private_load_balancer/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
115
gcp/modules/private_load_balancer/variables.tf
Normal file
115
gcp/modules/private_load_balancer/variables.tf
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
variable "project" {
|
||||
description = "The project to deploy to, if not set the default provider project is used."
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region for cloud resources."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "global_access" {
|
||||
description = "Allow all regions on the same VPC network access."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "network" {
|
||||
description = "Name of the network to create resources in."
|
||||
type = string
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "subnetwork" {
|
||||
description = "Name of the subnetwork to create resources in."
|
||||
type = string
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "network_project" {
|
||||
description = "Name of the project for the network. Useful for shared VPC. Default is var.project."
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Name for the forwarding rule and prefix for supporting resources."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "backends" {
|
||||
description = "List of backends, should be a map of key-value pairs for each backend, must have the 'group' key."
|
||||
type = list(any)
|
||||
}
|
||||
|
||||
variable "backend_timeout_sec" {
|
||||
description = "Backend timeout"
|
||||
type = number
|
||||
default = 30
|
||||
}
|
||||
|
||||
variable "load_balancing_scheme" {
|
||||
description = "The load balancing scheme to use. The default is INTERNAL"
|
||||
type = string
|
||||
default = "INTERNAL_MANAGED"
|
||||
}
|
||||
|
||||
variable "load_balancing_policy" {
|
||||
description = "The load balancing policy to use"
|
||||
type = string
|
||||
default = "ROUND_ROBIN"
|
||||
}
|
||||
|
||||
variable "named_port" {
|
||||
description = "Named port to allow access to the LB or resources through the VPC FW"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "session_affinity" {
|
||||
description = "The session affinity for the backends example: NONE, CLIENT_IP. Default is `NONE`."
|
||||
type = string
|
||||
default = "NONE"
|
||||
}
|
||||
|
||||
variable "port_range" {
|
||||
description = "List of ports range to forward to backend services. Max is 5."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "health_check" {
|
||||
description = "Health check to determine whether instances are responsive and able to do work"
|
||||
type = object({
|
||||
type = string
|
||||
check_interval_sec = number
|
||||
healthy_threshold = number
|
||||
timeout_sec = number
|
||||
unhealthy_threshold = number
|
||||
response = string
|
||||
proxy_header = string
|
||||
port = number
|
||||
port_name = string
|
||||
request = string
|
||||
request_path = string
|
||||
host = string
|
||||
enable_log = bool
|
||||
})
|
||||
}
|
||||
|
||||
variable "ip_protocol" {
|
||||
description = "The IP protocol for the backend and frontend forwarding rule. TCP or UDP."
|
||||
type = string
|
||||
default = "TCP"
|
||||
}
|
||||
|
||||
variable "connection_draining_timeout_sec" {
|
||||
description = "Time for which instance will be drained"
|
||||
default = 300
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "labels" {
|
||||
description = "The labels to attach to resources created by this module."
|
||||
default = {}
|
||||
type = map(string)
|
||||
}
|
||||
36
gcp/modules/random/README.md
Normal file
36
gcp/modules/random/README.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_random"></a> [random](#requirement\_random) | ~> 3.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_kasm_version"></a> [kasm\_version](#input\_kasm\_version) | The version of kasm installed | `string` | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_password"></a> [password](#output\_password) | # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # Auto-generated passwords # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
7
gcp/modules/random/outputs.tf
Normal file
7
gcp/modules/random/outputs.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
## Auto-generated passwords
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
output "password" {
|
||||
value = random_password.password.result
|
||||
sensitive = true
|
||||
}
|
||||
8
gcp/modules/random/password.tf
Normal file
8
gcp/modules/random/password.tf
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
resource "random_password" "password" {
|
||||
keepers = {
|
||||
kasm_version = var.kasm_version
|
||||
}
|
||||
|
||||
length = 30
|
||||
special = false
|
||||
}
|
||||
9
gcp/modules/random/provider.tf
Normal file
9
gcp/modules/random/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
4
gcp/modules/random/variables.tf
Normal file
4
gcp/modules/random/variables.tf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
variable "kasm_version" {
|
||||
description = "The version of kasm installed"
|
||||
type = string
|
||||
}
|
||||
44
gcp/modules/service_account_iam/README.md
Normal file
44
gcp/modules/service_account_iam/README.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.0 |
|
||||
| <a name="requirement_google"></a> [google](#requirement\_google) | ~> 4.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_google"></a> [google](#provider\_google) | 4.81.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
|------|--------|---------|
|
||||
| <a name="module_dns_zone_admin"></a> [dns\_zone\_admin](#module\_dns\_zone\_admin) | terraform-google-modules/iam/google//modules/dns_zones_iam | ~> 7.6 |
|
||||
| <a name="module_service_account_roles"></a> [service\_account\_roles](#module\_service\_account\_roles) | terraform-google-modules/iam/google//modules/member_iam | ~> 7.6 |
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [google_service_account.service_account](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
|
||||
| [google_service_account_key.kasm_key](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_key) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | The account id used to generate the service account email address | `string` | n/a | yes |
|
||||
| <a name="input_display_name"></a> [display\_name](#input\_display\_name) | The service account display name | `string` | `""` | no |
|
||||
| <a name="input_dns_public_zone_name"></a> [dns\_public\_zone\_name](#input\_dns\_public\_zone\_name) | Friendly name of the public DNS zone to manage. Only used if Direct to Agent is enabled. | `string` | `""` | no |
|
||||
| <a name="input_manage_dns"></a> [manage\_dns](#input\_manage\_dns) | Allow the service account to add/delete DNS records for direct-to-agent. | `bool` | `false` | no |
|
||||
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | Project id for the zone. | `string` | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_connect_details"></a> [connect\_details](#output\_connect\_details) | Kasm autoscale service account connect JSON output. NOTE: This contains sensitive data! |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
8
gcp/modules/service_account_iam/outputs.tf
Normal file
8
gcp/modules/service_account_iam/outputs.tf
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
## Service Account details
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
output "connect_details" {
|
||||
description = "Kasm autoscale service account connect JSON output. NOTE: This contains sensitive data!"
|
||||
value = google_service_account_key.kasm_key.private_key
|
||||
sensitive = true
|
||||
}
|
||||
9
gcp/modules/service_account_iam/provider.tf
Normal file
9
gcp/modules/service_account_iam/provider.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
gcp/modules/service_account_iam/service_account.tf
Normal file
34
gcp/modules/service_account_iam/service_account.tf
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
resource "google_service_account" "service_account" {
|
||||
project = var.project_id
|
||||
account_id = var.account_id
|
||||
display_name = var.display_name
|
||||
}
|
||||
|
||||
resource "google_service_account_key" "kasm_key" {
|
||||
service_account_id = google_service_account.service_account.id
|
||||
}
|
||||
|
||||
module "service_account_roles" {
|
||||
source = "terraform-google-modules/iam/google//modules/member_iam"
|
||||
version = "~> 7.6"
|
||||
|
||||
service_account_address = google_service_account.service_account.email
|
||||
project_id = var.project_id
|
||||
project_roles = ["roles/compute.instanceAdmin", "roles/iam.serviceAccountUser"]
|
||||
prefix = "serviceAccount"
|
||||
}
|
||||
|
||||
module "dns_zone_admin" {
|
||||
source = "terraform-google-modules/iam/google//modules/dns_zones_iam"
|
||||
version = "~> 7.6"
|
||||
count = var.manage_dns ? 1 : 0
|
||||
|
||||
project = var.project_id
|
||||
managed_zones = [var.dns_public_zone_name]
|
||||
mode = "additive"
|
||||
bindings = {
|
||||
"roles/dns.admin" = [
|
||||
"serviceAccount:${google_service_account.service_account.email}"
|
||||
]
|
||||
}
|
||||
}
|
||||
33
gcp/modules/service_account_iam/variables.tf
Normal file
33
gcp/modules/service_account_iam/variables.tf
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
variable "project_id" {
|
||||
description = "Project id for the zone."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "account_id" {
|
||||
description = "The account id used to generate the service account email address"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^([a-z]([-a-z0-9]*[a-z0-9]){6,30})", var.account_id))
|
||||
error_message = "The account_id must be between 6-30 characters beginning with a lower case letter, and consisting of lower case letters, numbers, or dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
## Pre-set values
|
||||
variable "display_name" {
|
||||
description = "The service account display name"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "dns_public_zone_name" {
|
||||
description = "Friendly name of the public DNS zone to manage. Only used if Direct to Agent is enabled."
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "manage_dns" {
|
||||
description = "Allow the service account to add/delete DNS records for direct-to-agent."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
21
gcp/outputs.tf
Normal file
21
gcp/outputs.tf
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
## Service Account details
|
||||
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
||||
output "kasm_sa_account" {
|
||||
description = "Kasm Service Account connection details"
|
||||
value = var.show_sa_credentials ? module.kasm_autoscale_service_account[*].connect_details : null
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "kasm_passwords" {
|
||||
description = "Kasm login passwords"
|
||||
value = var.show_passwords ? {
|
||||
kasm_admin_password = local.admin_password
|
||||
kasm_user_password = local.user_password
|
||||
kasm_database_password = local.database_password
|
||||
kasm_redis_password = local.redis_password
|
||||
kasm_service_token = local.service_token
|
||||
kasm_manager_token = local.manager_token
|
||||
} : null
|
||||
sensitive = true
|
||||
}
|
||||
31
gcp/provider.tf
Normal file
31
gcp/provider.tf
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
terraform {
|
||||
required_version = "~> 1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 4.64, < 6"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
tls = {
|
||||
source = "hashicorp/tls"
|
||||
version = "~> 2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "google" {
|
||||
project = var.project_id
|
||||
credentials = local.gcp_credentials
|
||||
}
|
||||
|
||||
provider "google-beta" {
|
||||
project = var.project_id
|
||||
credentials = local.gcp_credentials
|
||||
}
|
||||
69
gcp/terraform.tfvars
Normal file
69
gcp/terraform.tfvars
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
## Connection variables
|
||||
project_id = ""
|
||||
google_credential_file_path = "./gcp_credentials.json"
|
||||
|
||||
## VPC and deployment environment variables
|
||||
vpc_name = ""
|
||||
kasm_vpc_subnet = "10.0.0.0/16"
|
||||
|
||||
## Ensure the desired Database region is the first value in the list
|
||||
kasm_deployment_regions = ["us-east1"] # Use only one region for Multi-Server (single-region)
|
||||
#kasm_deployment_regions = ["us-west2", "asia-southeast1"] # Use multiple regions for Multi-Region deployment
|
||||
|
||||
## DNS Zone settings
|
||||
create_public_dns_zone = true
|
||||
public_dns_friendly_name = "kasm-public-dns-zone"
|
||||
private_dns_friendly_name = "kasm-private-dns-zone"
|
||||
|
||||
## Additional Kasm services or GCP features to deploy
|
||||
create_kasm_autoscale_service_account = true
|
||||
service_account_name = "kasm-autoscale"
|
||||
show_passwords = true
|
||||
|
||||
## Kasm variables
|
||||
kasm_domain_name = "example.kasmweb.com"
|
||||
kasm_project_name = ""
|
||||
deployment_type = "Multi-Region" # Valid values Multi-Region or Multi-Server
|
||||
kasm_version = "1.15.0"
|
||||
kasm_download_url = "https://github.com/kasmtech/kasm-install-wizard/releases/download/1.15.0/kasm_release.tar.gz"
|
||||
|
||||
## Kasm VM instance configurations
|
||||
# Webapp
|
||||
webapp_vm_instance_config = {
|
||||
machine_type = "e2-standard-2"
|
||||
disk_size_gb = "50"
|
||||
disk_type = "pd-standard"
|
||||
}
|
||||
|
||||
# Database
|
||||
database_vm_instance_config = {
|
||||
name = "kasm-database"
|
||||
machine_type = "e2-standard-2"
|
||||
disk_size_gb = 50
|
||||
description = "Kasm database with Terraform"
|
||||
disk_auto_delete = true
|
||||
disk_type = "pd-balanced"
|
||||
instance_role = "database"
|
||||
}
|
||||
|
||||
# Agent
|
||||
number_of_agents_per_region = 1
|
||||
enable_agent_nat_gateway = false
|
||||
agent_vm_instance_config = {
|
||||
name_prefix = "kasm-static-agent"
|
||||
machine_type = "e2-standard-2"
|
||||
disk_size_gb = 100
|
||||
description = "Kasm Static agent with Terraform"
|
||||
disk_auto_delete = true
|
||||
disk_type = "pd-balanced"
|
||||
instance_role = "agent"
|
||||
}
|
||||
|
||||
# Connection Proxy (Guac)
|
||||
deploy_connection_proxy = false
|
||||
deploy_windows_hosts = false ## NOTE: This only creates the Windows subnet and firewall rules, it does NOT deploy Windows VMs
|
||||
cpx_vm_instance_config = {
|
||||
machine_type = "e2-standard-2"
|
||||
disk_size_gb = "50"
|
||||
disk_type = "pd-standard"
|
||||
}
|
||||
61
gcp/userdata/agent_bootstrap.sh
Normal file
61
gcp/userdata/agent_bootstrap.sh
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/bash
|
||||
|
||||
## Download Kasm
|
||||
cd /tmp
|
||||
wget ${KASM_DOWNLOAD_URL}
|
||||
tar xvf kasm_*.tar.gz
|
||||
|
||||
## Create Swap partition
|
||||
fallocate -l 8g /mnt/kasm.swap
|
||||
chmod 600 /mnt/kasm.swap
|
||||
mkswap /mnt/kasm.swap
|
||||
swapon /mnt/kasm.swap
|
||||
echo '/mnt/kasm.swap swap swap defaults 0 0' | tee -a /etc/fstab
|
||||
apt update && apt install iputils-ping dnsutils netcat -y
|
||||
|
||||
## Verify connectivity with the webapp private load balancer
|
||||
while ! (curl -k https://${PRIVATE_LB_HOSTNAME}/api/__healthcheck 2>/dev/null | grep -q true)
|
||||
do
|
||||
echo "Waiting for API server..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
## Get Agent Private IP for Kasm registration
|
||||
connect_ip="`hostname -I | cut -d' ' -f1`"
|
||||
|
||||
## Install Kasm
|
||||
## Kasm install arguments used:
|
||||
## -S = Kasm role - agent in this case
|
||||
## -H = Don't check for swap (since we created it already)
|
||||
## -e = accept EULA
|
||||
## -p = Agent IP address or hostname
|
||||
## -m = Webapp private load balancer hostname
|
||||
## -M = Manager token to use to register the agent
|
||||
## Useful additional arguments:
|
||||
## -O = use Rolling images (ensures the most up-to-date containers are used)
|
||||
bash kasm_release/install.sh -S agent -H -e -p $${connect_ip} -m ${PRIVATE_LB_HOSTNAME} -M ${KASM_MANAGER_TOKEN} ${ADDITIONAL_AGENT_INSTALL_ARGS}
|
||||
|
||||
## Install Nvidia drivers if this is a GPU-enabled agent.
|
||||
if [[ "${GPU_ENABLED}" == "1" ]]
|
||||
then
|
||||
apt-get update && apt-get upgrade -y
|
||||
apt-get install -y gcc make linux-headers-$(uname -r) linux-aws awscli
|
||||
cat << EOF | tee --append /etc/modprobe.d/blacklist.conf
|
||||
blacklist vga16fb
|
||||
blacklist nouveau
|
||||
blacklist rivafb
|
||||
blacklist nvidiafb
|
||||
blacklist rivatv
|
||||
EOF
|
||||
echo 'GRUB_CMDLINE_LINUX="rdblacklist=nouveau"' | tee --append /etc/default/grub
|
||||
update-grub
|
||||
aws s3 cp --no-sign-request --recursive s3://ec2-linux-nvidia-drivers/latest/ .
|
||||
chmod +x NVIDIA-Linux-x86_64*.run
|
||||
/bin/sh ./NVIDIA-Linux-x86_64*.run -s
|
||||
curl -fsSL "https://nvidia.github.io/nvidia-docker/gpgkey" | gpg --dearmor | tee /etc/apt/trusted.gpg.d/nvidia.gpg > /dev/null
|
||||
curl -s -L "https://nvidia.github.io/nvidia-docker/$(source /etc/os-release;echo $ID$VERSION_ID)/nvidia-docker.list" -o /etc/apt/sources.list.d/nvidia-docker.list
|
||||
apt-get update
|
||||
apt-get install -y nvidia-docker2
|
||||
systemctl restart docker
|
||||
docker restart kasm_agent
|
||||
fi
|
||||
39
gcp/userdata/cpx_bootstrap.sh
Normal file
39
gcp/userdata/cpx_bootstrap.sh
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
|
||||
## Download Kasm
|
||||
cd /tmp
|
||||
wget ${KASM_DOWNLOAD_URL}
|
||||
tar xvf kasm_*.tar.gz
|
||||
|
||||
## Create Swap partition
|
||||
fallocate -l 2g /mnt/kasm.swap
|
||||
chmod 600 /mnt/kasm.swap
|
||||
mkswap /mnt/kasm.swap
|
||||
swapon /mnt/kasm.swap
|
||||
echo '/mnt/kasm.swap swap swap defaults 0 0' | tee -a /etc/fstab
|
||||
|
||||
## Install useful packages
|
||||
apt update && apt install iputils-ping dnsutils netcat -y
|
||||
|
||||
## Make sure the CPX node can access the private load balancer
|
||||
while ! (curl -k https://${PRIVATE_LB_HOSTNAME}/api/__healthcheck 2>/dev/null | grep -q true)
|
||||
do
|
||||
echo "Waiting for API server..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
## Get CPX Private IP for Kasm registration
|
||||
connect_ip="`hostname -I | cut -d' ' -f1`"
|
||||
|
||||
## Install Kasm
|
||||
## Kasm install arguments used:
|
||||
## -S = Kasm role - guac in this case
|
||||
## -H = Don't check for swap (since we created it already)
|
||||
## -e = accept EULA
|
||||
## -n = Private Load balancer URL for Kasm webapps
|
||||
## -p = CPX Node private IP so webapp can connect to CPX
|
||||
## -k = Service registration token required to register the CPX with Kasm
|
||||
## -z = The Zone name to register the CPX node with
|
||||
## Useful additional arguments:
|
||||
## -O = use Rolling images (ensures the most up-to-date containers are used)
|
||||
bash kasm_release/install.sh -S guac -H -e -n ${PRIVATE_LB_HOSTNAME} -p $${connect_ip} -k ${KASM_SERVICE_TOKEN} -z ${KASM_ZONE_NAME} ${ADDITIONAL_CPX_INSTALL_ARGS}
|
||||
31
gcp/userdata/database_bootstrap.sh
Normal file
31
gcp/userdata/database_bootstrap.sh
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
|
||||
## Download Kasm
|
||||
cd /tmp
|
||||
wget ${KASM_DOWNLOAD_URL}
|
||||
tar xvf kasm_*.tar.gz
|
||||
|
||||
## Create swap partition
|
||||
fallocate -l 8g /mnt/kasm.swap
|
||||
chmod 600 /mnt/kasm.swap
|
||||
mkswap /mnt/kasm.swap
|
||||
swapon /mnt/kasm.swap
|
||||
echo '/mnt/kasm.swap swap swap defaults 0 0' | tee -a /etc/fstab
|
||||
|
||||
## Install useful packages
|
||||
apt update && apt install iputils-ping dnsutils netcat -y
|
||||
|
||||
## Install Kasm
|
||||
## Kasm install arguments used:
|
||||
## -S = Kasm role - db in this case
|
||||
## -H = Don't check for swap (since we created it already)
|
||||
## -e = accept EULA
|
||||
## -Q = Database password
|
||||
## -R = Redis password
|
||||
## -U = Password to use for user@kasm.local built-in account
|
||||
## -P = Password to use for admin@kasm.local built-in admin account
|
||||
## -M = Management token to use for agent registration
|
||||
## -k = Service registration token to use for Connection Proxy (Guac) registration
|
||||
## Useful additional arguments:
|
||||
## -O = use Rolling images (ensures the most up-to-date containers are used)
|
||||
bash kasm_release/install.sh -S db -e -Q ${KASM_DB_PASS} -R ${KASM_REDIS_PASS} -U ${KASM_USER_PASS} -P ${KASM_ADMIN_PASS} -M ${KASM_MANAGER_TOKEN} -k ${KASM_SERVICE_TOKEN} ${ADDITIONAL_DATABASE_INSTALL_ARGS}
|
||||
48
gcp/userdata/remote_db_init.sh
Normal file
48
gcp/userdata/remote_db_init.sh
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/bin/bash
|
||||
|
||||
## Download Kasm
|
||||
cd /tmp
|
||||
wget ${KASM_DOWNLOAD_URL}
|
||||
tar xvf kasm_*.tar.gz
|
||||
|
||||
## Create swap partition
|
||||
fallocate -l 2g /mnt/kasm.swap
|
||||
chmod 600 /mnt/kasm.swap
|
||||
mkswap /mnt/kasm.swap
|
||||
swapon /mnt/kasm.swap
|
||||
echo '/mnt/kasm.swap swap swap defaults 0 0' | tee -a /etc/fstab
|
||||
|
||||
## Install useful packages
|
||||
apt update && apt install iputils-ping dnsutils netcat -y
|
||||
|
||||
## Ensure connection to remote database before installing
|
||||
while ! nc -w 1 -z ${DATABASE_IP} 5432
|
||||
do
|
||||
echo "Waiting for DB connection..."
|
||||
sleep 10
|
||||
done
|
||||
|
||||
## Ensure connection to remote Redis before installing
|
||||
while ! nc -w 1 -z ${REDIS_IP} 6379
|
||||
do
|
||||
echo "Waiting for Redis connection..."
|
||||
sleep 10
|
||||
done
|
||||
|
||||
## Install Kasm
|
||||
## Kasm install arguments used:
|
||||
## -S = Kasm role - init_remote_db in this case
|
||||
## -H = Don't check for swap (since we created it already)
|
||||
## -e = accept EULA
|
||||
## -q = Database IP or Hostname
|
||||
## -Q = Database password
|
||||
## -o = Redis IP or Hostname
|
||||
## -R = Redis password
|
||||
## -U = Password to use for user@kasm.local built-in account
|
||||
## -P = Password to use for admin@kasm.local built-in admin account
|
||||
## -M = Management token to use for agent registration
|
||||
## -k = Service registration token to use for Connection Proxy (Guac) registration
|
||||
## Useful additional arguments:
|
||||
## -O = use Rolling images (ensures the most up-to-date containers are used)
|
||||
bash kasm_release/install_dependencies.sh
|
||||
bash kasm_release/install.sh -S init_remote_db -e -H -q ${DATABASE_IP} -Q ${KASM_DB_PASS} -U ${KASM_USER_PASS} -P ${KASM_ADMIN_PASS} -o ${REDIS_IP} -R ${KASM_REDIS_PASS} -M ${KASM_SERVICE_TOKEN} -g ${DB_MASTER_USER} -G ${DB_MASTER_PASSWORD} -k ${KASM_SERVICE_TOKEN} ${ADDITIONAL_DATABASE_INSTALL_ARGS}
|
||||
43
gcp/userdata/webapp_bootstrap.sh
Normal file
43
gcp/userdata/webapp_bootstrap.sh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/bash
|
||||
|
||||
## Download Kasm
|
||||
cd /tmp
|
||||
wget ${KASM_DOWNLOAD_URL}
|
||||
tar xvf kasm_*.tar.gz
|
||||
|
||||
## Create Swap partition
|
||||
fallocate -l 2g /mnt/kasm.swap
|
||||
chmod 600 /mnt/kasm.swap
|
||||
mkswap /mnt/kasm.swap
|
||||
swapon /mnt/kasm.swap
|
||||
echo '/mnt/kasm.swap swap swap defaults 0 0' | tee -a /etc/fstab
|
||||
|
||||
## Install useful packages
|
||||
apt update && apt install iputils-ping dnsutils netcat -y
|
||||
|
||||
## Test Database connectivity before installing
|
||||
while ! nc -w 1 -z ${DB_PRIVATE_IP} 5432
|
||||
do
|
||||
echo "Waiting for DB connection..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
## Test Redis connectivity before installing
|
||||
while ! nc -w 1 -z ${DB_PRIVATE_IP} 6379
|
||||
do
|
||||
echo "Waiting for Redis connection..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
## Install Kasm
|
||||
## Kasm install arguments used:
|
||||
## -S = Kasm role - webapp in this case
|
||||
## -H = Don't check for swap (since we created it already)
|
||||
## -e = accept EULA
|
||||
## -q = Database Server IP
|
||||
## -Q = Database password
|
||||
## -R = Redis password
|
||||
## -z = The Zone name to use for the webapp
|
||||
## Useful additional arguments:
|
||||
## -O = use Rolling images (ensures the most up-to-date containers are used)
|
||||
bash kasm_release/install.sh -S app -H -e -z ${KASM_ZONE_NAME} -q ${DB_PRIVATE_IP} -Q ${KASM_DB_PASS} -R ${KASM_REDIS_PASS} ${ADDITIONAL_WEBAPP_INSTALL_ARGS}
|
||||
852
gcp/variables.tf
Normal file
852
gcp/variables.tf
Normal file
|
|
@ -0,0 +1,852 @@
|
|||
## Connection variables
|
||||
variable "project_id" {
|
||||
description = "GCP Project ID where to deploy Kasm"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]", var.project_id))
|
||||
error_message = "The project_id variable should be a valid GCP Project ID and can only consist of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "google_credential_file_path" {
|
||||
description = "File path to GCP account authentication file"
|
||||
type = string
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.google_credential_file_path == "" ? true : fileexists(var.google_credential_file_path)
|
||||
error_message = "The variable google_credential_file_path must point to a valid GCP credential file."
|
||||
}
|
||||
validation {
|
||||
condition = var.google_credential_file_path == "" ? true : !can(regex("replaceme", file(var.google_credential_file_path)))
|
||||
error_message = "You must add valid GCP credentials in JSON format in the google_credential_file_path file."
|
||||
}
|
||||
}
|
||||
|
||||
## Network variables
|
||||
variable "vpc_name" {
|
||||
description = "Name for Kasm VPC"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.vpc_name))
|
||||
error_message = "The vpc_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_vpc_subnet" {
|
||||
description = "VPC Subnet CIDR range. All other Subnets will be automatically calculated from this seed value."
|
||||
type = string
|
||||
default = "10.0.0.0/16"
|
||||
|
||||
validation {
|
||||
condition = can(cidrhost(var.kasm_vpc_subnet, 0))
|
||||
error_message = "The kasm_vpc_subnet variable must be a valid IPv4 CIDR Subnet in the format x.x.x.x/x, and the default is 10.0.0.0/16."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_deployment_regions" {
|
||||
description = "Kasm regions to deploy into"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
## Kasm variables
|
||||
variable "kasm_download_url" {
|
||||
description = "Download URL for Kasm Workspaces installer"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "kasm_domain_name" {
|
||||
description = "Public DNS domain name to use for Kasm deployment"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6}", var.kasm_domain_name))
|
||||
error_message = "There are invalid characters in the kasm_domain_name - it must be a valid domain name."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_project_name" {
|
||||
description = "Kasm deployment project name (separate from GCP Project id or Project Name)"
|
||||
type = string
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_project_name == "" ? true : can(regex("^[a-z0-9-]{2,25}", var.kasm_project_name))
|
||||
error_message = "The kasm_project_name is used in labels and "
|
||||
}
|
||||
}
|
||||
|
||||
variable "deployment_type" {
|
||||
description = "The deployment type - Single-Server, Multi-Server, or Multi-Region"
|
||||
type = string
|
||||
default = "Multi-Server"
|
||||
|
||||
validation {
|
||||
condition = contains(["Single-Server", "Multi-Server", "Multi-Region", ""], var.deployment_type)
|
||||
error_message = "The deployment_type variable declares the deployment type and can only consisit of one of the values Single-Server, Multi-Server, or Multi-Region."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_version" {
|
||||
description = "Kasm version to deploy"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "kasm_database_password" {
|
||||
description = "The password for the database. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_database_password == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_database_password))
|
||||
error_message = "The Kasm Database should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_redis_password" {
|
||||
description = "The password for the Redis server. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_redis_password == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_redis_password))
|
||||
error_message = "The Kasm Redis should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_user_password" {
|
||||
description = "The standard (non administrator) user password. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_user_password == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_user_password))
|
||||
error_message = "The Kasm User should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_admin_password" {
|
||||
description = "The administrative user password. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_admin_password == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_admin_password))
|
||||
error_message = "The Kasm Admin should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_manager_token" {
|
||||
description = "The manager token value for Agents to authenticate to webapps. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_manager_token == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_manager_token))
|
||||
error_message = "The Manager Token should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_service_token" {
|
||||
description = "The service registration token value for Guac RDP servers to authenticate to webapps. No special characters"
|
||||
type = string
|
||||
sensitive = true
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = var.kasm_service_token == "" ? true : can(regex("^[a-zA-Z0-9]{12,40}", var.kasm_service_token))
|
||||
error_message = "The Service Registration Token should be a string between 12 and 40 letters or numbers with no special characters."
|
||||
}
|
||||
}
|
||||
|
||||
variable "show_passwords" {
|
||||
description = "Show Kasm passwords in root Terraform output"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "show_sa_credentials" {
|
||||
description = "Show GCP Service account credential file in output"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
## SSL Certificate variables
|
||||
variable "use_gcp_certificate_manager" {
|
||||
description = "Use Certificate Manager to create and manage the Kasm public SSL certificate"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "kasm_certificate_base_name" {
|
||||
description = "Name to use for Kasm Global SSL certificate"
|
||||
type = string
|
||||
default = "kasm-global-tls-certificate"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]{4,63}", var.kasm_certificate_base_name))
|
||||
error_message = "The kasm_certificate_base_name variable can only be a max of 63 characters consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_certificate_dns_auth_base_name" {
|
||||
description = "Name to use for Kasm SSL DNS authorization service"
|
||||
type = string
|
||||
default = "kasm-global-certificate-dns-authorization"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.kasm_certificate_dns_auth_base_name))
|
||||
error_message = "The kasm_certificate_dns_auth_base_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kasm_cert_map_base_name" {
|
||||
description = "Name to use for Kasm Global SSL certificate map"
|
||||
type = string
|
||||
default = "kasm-global-certificate-map"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.kasm_cert_map_base_name))
|
||||
error_message = "The kasm_cert_map_base_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
## Webapp variables
|
||||
variable "webapp_vm_instance_config" {
|
||||
description = "Webapp Compute instance configuration settings"
|
||||
type = object({
|
||||
machine_type = string
|
||||
disk_size_gb = string
|
||||
disk_type = string
|
||||
})
|
||||
|
||||
validation {
|
||||
condition = tonumber(var.webapp_vm_instance_config.disk_size_gb) > 30
|
||||
error_message = "The webapp_vm_instance_config disk_size_gb should be larger than 30GB to support Kasm and other required services. Recommended minimum size is 50GB."
|
||||
}
|
||||
validation {
|
||||
condition = contains(["pd-standard", "pd-ssd", "local-ssd", "pd-extreme"], var.webapp_vm_instance_config.disk_type)
|
||||
error_message = "The webapp_vm_instance_config disk_type attribute can only be one of pd-standard, pd-ssd, pd-extreme, or local-ssd."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_named_ports" {
|
||||
description = "Webapp named ports for firewall and Google service connectivity"
|
||||
type = list(object({
|
||||
name = string
|
||||
port = number
|
||||
}))
|
||||
default = [
|
||||
{
|
||||
name = "https"
|
||||
port = 443
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
variable "webapp_hostname_prefix" {
|
||||
description = "Webapp hostname prefix to use for instance group"
|
||||
type = string
|
||||
default = "webapp"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.webapp_hostname_prefix))
|
||||
error_message = "The webapp_hostname_prefix variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_autoscale_min_instances" {
|
||||
description = "Webapp Autoscale minimum number of instances"
|
||||
type = number
|
||||
default = 2
|
||||
|
||||
validation {
|
||||
condition = var.webapp_autoscale_min_instances >= 1
|
||||
error_message = "The webapp_autoscale_min_instances should be 3 at a minimum since that is the typical number of availability domains for a region."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_autoscale_max_instances" {
|
||||
description = "Webapp Autoscale maximum number of instances"
|
||||
type = number
|
||||
default = 5
|
||||
|
||||
validation {
|
||||
condition = var.webapp_autoscale_max_instances >= 1
|
||||
error_message = "The webapp_autoscale_max_instances should be larger than the webapp_autoscale_min_instances value."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_autoscale_cool_down_period" {
|
||||
description = "Time in seconds for the autoscale group to wait before evaluating the health of the webapp"
|
||||
type = number
|
||||
default = 600
|
||||
|
||||
validation {
|
||||
condition = var.webapp_autoscale_cool_down_period >= 300
|
||||
error_message = "The webapp_autoscale_cool_down_periodc should be greater than 300 to allow webapps to be fully available before being evaluated with health checks. Kasm recommends around 600 or more."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_autoscale_scale_out_cpu" {
|
||||
description = "Webapp Autoscale CPU percent to scale up webapps"
|
||||
type = list(object({
|
||||
target = number
|
||||
predictive_method = string
|
||||
}))
|
||||
|
||||
default = [{
|
||||
target = 0.6
|
||||
predictive_method = "NONE"
|
||||
}]
|
||||
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_autoscale_scale_out_cpu : value.target >= 0.5])
|
||||
error_message = "The webapp_autoscale_scale_out_cpu target attribute should be 0.5 at a minimum to prevent GCP from scaling webapps too aggressively."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_autoscale_scale_out_cpu : contains(["NONE", "OPTIMIZE_AVAILABILITY"], value.predictive_method)])
|
||||
error_message = "The webapp_autoscale_scale_out_cpu predictive_method attribute can only be one of NONE or OPTIMIZE_AVAILABILITY."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_autoscale_scale_in_settings" {
|
||||
description = "Webapp Autoscale scale-in settings"
|
||||
type = object({
|
||||
fixed_replicas = number
|
||||
time_window_sec = number
|
||||
percent_replicas = optional(number, null)
|
||||
})
|
||||
default = {
|
||||
fixed_replicas = 1
|
||||
time_window_sec = 600
|
||||
}
|
||||
|
||||
validation {
|
||||
condition = var.webapp_autoscale_scale_in_settings.fixed_replicas >= 1
|
||||
error_message = "The webapp_instance_group_scale_settings fixed_replicas should be 1 or more."
|
||||
}
|
||||
validation {
|
||||
condition = var.webapp_autoscale_scale_in_settings.time_window_sec >= 300
|
||||
error_message = "The webapp_instance_group_scale_settings time_window_sec should be greater than 300 to allow webapps to be fully available before being evaluated with health checks. Kasm recommends around 600 or more."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_health_check_name" {
|
||||
description = "Name of Webapp Managed Instance Group healthcheck"
|
||||
type = string
|
||||
default = "webapp-healthcheck"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.webapp_health_check_name))
|
||||
error_message = "The webapp_health_check_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_health_check" {
|
||||
description = "HTTPS Managed Instance Group healthcheck for webapps."
|
||||
type = object({
|
||||
type = string
|
||||
initial_delay_sec = number
|
||||
check_interval_sec = number
|
||||
healthy_threshold = number
|
||||
timeout_sec = number
|
||||
unhealthy_threshold = number
|
||||
port = number
|
||||
port_name = string
|
||||
request_path = string
|
||||
response = optional(string, "")
|
||||
proxy_header = optional(string, "NONE")
|
||||
request = optional(string, "")
|
||||
host = optional(string, "")
|
||||
enable_log = optional(bool, false)
|
||||
enable_logging = optional(string, false)
|
||||
})
|
||||
default = {
|
||||
type = "https"
|
||||
initial_delay_sec = 600
|
||||
check_interval_sec = 30
|
||||
healthy_threshold = 2
|
||||
timeout_sec = 10
|
||||
unhealthy_threshold = 5
|
||||
port = 443
|
||||
port_name = "https"
|
||||
request_path = "/api/__healthcheck"
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_instance_update_policy" {
|
||||
description = "The Instance group rolling update policy"
|
||||
type = list(object({
|
||||
instance_redistribution_type = string
|
||||
min_ready_sec = number
|
||||
replacement_method = string
|
||||
minimal_action = string
|
||||
type = string
|
||||
max_surge_fixed = optional(number, null)
|
||||
max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances
|
||||
max_unavailable_fixed = optional(number, null)
|
||||
max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances
|
||||
}))
|
||||
default = [{
|
||||
minimal_action = "REFRESH"
|
||||
type = "PROACTIVE" # Update automatically
|
||||
max_surge_fixed = 3 # Max new instances to startup
|
||||
max_unavailable_fixed = 0 # Max instances to take offline before new ones available
|
||||
instance_redistribution_type = "PROACTIVE" # Maintain even distribution across availability zones
|
||||
replacement_method = "SUBSTITUTE" # Start new ones before taking any offline
|
||||
min_ready_sec = 600 # Wait time before instance is ready
|
||||
}]
|
||||
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_instance_update_policy : contains(["PROACTIVE", "OPPORTUNISTIC"], value.type)])
|
||||
error_message = "The webapp_instance_update_policy type setting only accepts PROACTIVE or OPPORTUNISTIC."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_instance_update_policy : contains(["PROACTIVE", "OPPORTUNISTIC"], value.instance_redistribution_type)])
|
||||
error_message = "The webapp_instance_update_policy instance_redistribution_type setting only accepts PROACTIVE or OPPORTUNISTIC."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_instance_update_policy : contains(["RECREATE", "SUBSTITUTE"], value.replacement_method)])
|
||||
error_message = "The webapp_instance_update_policy replacement_method setting only accepts RECREATE or SUBSTITUTE."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.webapp_instance_update_policy : value.min_ready_sec >= 300])
|
||||
error_message = "The webapp_instance_update_policy min_ready_sec should be greater than or equal to 300 seconds (5 min). Ideally, this should be around 600 seconds (10 min) to allow all install actions to take place."
|
||||
}
|
||||
}
|
||||
|
||||
variable "public_load_balancer_name" {
|
||||
description = "GCP name for Global Public HTTPS Load balancer"
|
||||
type = string
|
||||
default = "webapp-global-load-balancer"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.public_load_balancer_name))
|
||||
error_message = "The public_load_balancer_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "webapp_lb_health_check" {
|
||||
description = "HTTPS Load balancer and healthcheck for webapps."
|
||||
type = object({
|
||||
check_interval_sec = optional(number)
|
||||
timeout_sec = optional(number)
|
||||
healthy_threshold = optional(number)
|
||||
unhealthy_threshold = optional(number)
|
||||
request_path = optional(string)
|
||||
port = optional(number)
|
||||
host = optional(string)
|
||||
logging = optional(bool)
|
||||
})
|
||||
default = {
|
||||
check_interval_sec = 30
|
||||
timeout_sec = 10
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 3
|
||||
request_path = "/api/__healthcheck"
|
||||
port = 443
|
||||
}
|
||||
}
|
||||
|
||||
## Database instance variables
|
||||
variable "database_vm_instance_config" {
|
||||
description = "Database Compute instance configuration settings"
|
||||
type = object({
|
||||
machine_type = string
|
||||
disk_size_gb = number
|
||||
instance_role = string
|
||||
name = optional(string)
|
||||
name_prefix = optional(string)
|
||||
disk_auto_delete = optional(bool)
|
||||
description = optional(string)
|
||||
disk_type = optional(string)
|
||||
})
|
||||
}
|
||||
|
||||
## Agent instance variables
|
||||
variable "agent_vm_instance_config" {
|
||||
description = "Agent Compute instance configuration settings"
|
||||
type = object({
|
||||
machine_type = string
|
||||
disk_size_gb = number
|
||||
instance_role = string
|
||||
name = optional(string)
|
||||
name_prefix = optional(string)
|
||||
disk_auto_delete = optional(bool)
|
||||
description = optional(string)
|
||||
disk_type = optional(string)
|
||||
})
|
||||
}
|
||||
|
||||
variable "number_of_agents_per_region" {
|
||||
description = "The number of static Kasm agents to deploy in each region. Set this to 0 to "
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "enable_agent_nat_gateway" {
|
||||
description = "Deploy Kasm Agent behind a NAT gateway"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "agent_gpu_enabled" {
|
||||
description = "Whether or not to automatically install GPU libraries. NOTE: This is useless unless you deploy Kasm agents using a GPU-based instance."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
## Connection Proxy (Guac) variables
|
||||
variable "cpx_vm_instance_config" {
|
||||
description = "CPX Compute instance configuration settings"
|
||||
type = object({
|
||||
machine_type = string
|
||||
disk_size_gb = string
|
||||
disk_type = string
|
||||
})
|
||||
|
||||
validation {
|
||||
condition = tonumber(var.cpx_vm_instance_config.disk_size_gb) > 30
|
||||
error_message = "The cpx_vm_instance_config disk_size_gb should be larger than 30GB to support Kasm and other required services. Recommended minimum size is 50GB."
|
||||
}
|
||||
validation {
|
||||
condition = contains(["pd-standard", "pd-ssd", "local-ssd", "pd-extreme"], var.cpx_vm_instance_config.disk_type)
|
||||
error_message = "The cpx_vm_instance_config disk_type attribute can only be one of pd-standard, pd-ssd, pd-extreme, or local-ssd."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_named_ports" {
|
||||
description = "CPX named ports for firewall and Google service connectivity"
|
||||
type = list(object({
|
||||
name = string
|
||||
port = number
|
||||
}))
|
||||
default = [
|
||||
{
|
||||
name = "https"
|
||||
port = 443
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
variable "cpx_hostname_prefix" {
|
||||
description = "CPX hostname prefix to use for instance group"
|
||||
type = string
|
||||
default = "cpx"
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z0-9-]{3,63}", var.cpx_hostname_prefix))
|
||||
error_message = "The cpx_hostname_prefix variable can only be a max of 63 characters consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_autoscale_min_instances" {
|
||||
description = "CPX Autoscale minimum number of instances"
|
||||
type = number
|
||||
default = 1
|
||||
|
||||
validation {
|
||||
condition = var.cpx_autoscale_min_instances >= 1
|
||||
error_message = "The cpx_autoscale_min_instances should be 1 at a minimum to create the instance group."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_autoscale_max_instances" {
|
||||
description = "CPX Autoscale maximum number of instances"
|
||||
type = number
|
||||
default = 5
|
||||
|
||||
validation {
|
||||
condition = var.cpx_autoscale_max_instances >= 2
|
||||
error_message = "The cpx_autoscale_max_instances should be 3 at a minimum since that is the typical number of availability domains for a region."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_autoscale_cool_down_period" {
|
||||
description = "Time in seconds for the autoscale group to wait before evaluating the health of the webapp"
|
||||
type = number
|
||||
default = 600
|
||||
|
||||
validation {
|
||||
condition = var.cpx_autoscale_cool_down_period >= 300
|
||||
error_message = "The cpx_autoscale_cool_down_periodc should be greater than 300 to allow webapps to be fully available before being evaluated with health checks. Kasm recommends around 600 or more."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_autoscale_scale_out_cpu" {
|
||||
description = "CPX Autoscale CPU percent to scale up webapps"
|
||||
type = list(object({
|
||||
target = number
|
||||
predictive_method = optional(string, "NONE")
|
||||
}))
|
||||
|
||||
default = [{
|
||||
target = 0.6
|
||||
}]
|
||||
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_autoscale_scale_out_cpu : value.target >= 0.5])
|
||||
error_message = "The cpx_autoscale_scale_out_cpu target attribute should be 0.5 at a minimum to prevent GCP from scaling webapps too aggressively."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_autoscale_scale_out_cpu : contains(["NONE", "OPTIMIZE_AVAILABILITY"], value.predictive_method)])
|
||||
error_message = "The cpx_autoscale_scale_out_cpu predictive_method attribute can only be one of NONE or OPTIMIZE_AVAILABILITY."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_autoscale_scale_in_settings" {
|
||||
description = "CPX Autoscale scale-in settings"
|
||||
type = object({
|
||||
fixed_replicas = number
|
||||
time_window_sec = number
|
||||
percent_replicas = optional(number, null)
|
||||
})
|
||||
default = {
|
||||
fixed_replicas = 1
|
||||
time_window_sec = 600
|
||||
}
|
||||
|
||||
validation {
|
||||
condition = var.cpx_autoscale_scale_in_settings.fixed_replicas >= 1
|
||||
error_message = "The cpx_instance_group_scale_settings fixed_replicas should be 1 or more."
|
||||
}
|
||||
validation {
|
||||
condition = var.cpx_autoscale_scale_in_settings.time_window_sec >= 300
|
||||
error_message = "The cpx_instance_group_scale_settings time_window_sec should be greater than 300 to allow webapps to be fully available before being evaluated with health checks. Kasm recommends around 600 or more."
|
||||
}
|
||||
}
|
||||
|
||||
variable "cpx_instance_update_policy" {
|
||||
description = "The CPX Instance group rolling update policy"
|
||||
type = list(object({
|
||||
instance_redistribution_type = string
|
||||
min_ready_sec = number
|
||||
replacement_method = string
|
||||
minimal_action = string
|
||||
type = string
|
||||
max_surge_fixed = optional(number, null)
|
||||
max_surge_percent = optional(number, null) # Can only use if you run 10 or more instances
|
||||
max_unavailable_fixed = optional(number, null)
|
||||
max_unavailable_percent = optional(number, null) # Can only use if you run 10 or more instances
|
||||
}))
|
||||
default = [{
|
||||
minimal_action = "REFRESH"
|
||||
type = "PROACTIVE" # Update automatically
|
||||
max_surge_fixed = 3 # Max new instances to startup
|
||||
max_unavailable_fixed = 0 # Max instances to take offline before new ones available
|
||||
instance_redistribution_type = "PROACTIVE" # Automatically distribute nodes across availability zones
|
||||
replacement_method = "SUBSTITUTE" # Start new ones before taking any offline
|
||||
min_ready_sec = 600 # Wait time before instance is ready
|
||||
}]
|
||||
|
||||
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_instance_update_policy : contains(["PROACTIVE", "OPPORTUNISTIC"], value.type)])
|
||||
error_message = "The cpx_instance_update_policy instance_redistribution_type setting only accepts PROACTIVE or OPPORTUNISTIC."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_instance_update_policy : contains(["PROACTIVE", "OPPORTUNISTIC"], value.instance_redistribution_type)])
|
||||
error_message = "The cpx_instance_update_policy instance_redistribution_type setting only accepts PROACTIVE or OPPORTUNISTIC."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_instance_update_policy : contains(["RECREATE", "SUBSTITUTE"], value.replacement_method)])
|
||||
error_message = "The cpx_instance_update_policy replacement_method setting only accepts RECREATE or SUBSTITUTE."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for value in var.cpx_instance_update_policy : value.min_ready_sec >= 300])
|
||||
error_message = "The cpx_instance_update_policy min_ready_sec should be greater than or equal to 300 seconds (5 min). Ideally, this should be around 600 seconds (10 min) to allow all install actions to take place."
|
||||
}
|
||||
}
|
||||
|
||||
## DNS variables
|
||||
variable "create_public_dns_zone" {
|
||||
description = "Set to true if you wish to create a public DNS zone for this Kasm instance. If not, the public_dns_friendly_name should belong to an existing DNS zone."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_dns_friendly_name" {
|
||||
description = "Public DNS Zone resource name. If not creating a new DNS Zone, make sure the desired DNS zone already exists."
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.public_dns_friendly_name))
|
||||
error_message = "The public_dns_friendly_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
variable "private_dns_friendly_name" {
|
||||
description = "Private DNS Zone resource name"
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-z][a-z0-9-]{3,63}", var.private_dns_friendly_name))
|
||||
error_message = "The private_dns_friendly_name variable can only be a max of 63 characters beginning with a lower case letter, and consisting of lower case letters, numbers, and dash (-)."
|
||||
}
|
||||
}
|
||||
|
||||
## Kasm default image source
|
||||
variable "kasm_source_image" {
|
||||
description = "The source VM Image information to use for deploying Kasm. Recommended to use Ubuntu 20.04 Minimal. You can either explicitly define the source image to use, or the image project and family so that Terraform always chooses the latest."
|
||||
type = object({
|
||||
source_image = optional(string, null)
|
||||
project = optional(string, null)
|
||||
family = optional(string, null)
|
||||
})
|
||||
|
||||
default = {
|
||||
project = "ubuntu-os-cloud"
|
||||
family = "ubuntu-minimal-2004-lts"
|
||||
}
|
||||
}
|
||||
|
||||
## GCP Service account used autoscaling and instance updates
|
||||
variable "compute_service_account" {
|
||||
description = "Compute service account to use for CPX autoscaling"
|
||||
type = object({
|
||||
email = optional(string)
|
||||
scopes = list(string)
|
||||
})
|
||||
|
||||
default = {
|
||||
email = ""
|
||||
scopes = ["cloud-platform"]
|
||||
}
|
||||
}
|
||||
|
||||
## Additional install options
|
||||
variable "additional_kasm_install_options" {
|
||||
description = "Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details."
|
||||
type = list(string)
|
||||
default = ["-O"]
|
||||
}
|
||||
|
||||
variable "additional_webapp_install_options" {
|
||||
description = "Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "additional_database_install_options" {
|
||||
description = "Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "additional_agent_install_options" {
|
||||
description = "Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "additional_cpx_install_options" {
|
||||
description = "Additional global Kasm install options. Refer to the install.sh file in the Kasm installer for additional details."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
## Additional Kasm features
|
||||
variable "deploy_connection_proxy" {
|
||||
description = "Deploy Kasm Guacamole Server for RDP/SSH access to physical servers"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "deploy_windows_hosts" {
|
||||
description = "Create a subnet and Firewall rules for Windows hosts. These hosts must be deployed manually, or you'll need to add your own compute entry for Windows hosts."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
## Kasm Autoscale Service Account
|
||||
variable "create_kasm_autoscale_service_account" {
|
||||
description = "Create a GCP service account capable of managing Kasm Cloud Autoscaling for GCP agents"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "service_account_name" {
|
||||
description = "Account name to use for Kasm Autoscaling service account"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
## Firewall rules
|
||||
variable "kasm_firewall_security_tags" {
|
||||
description = "Firewall tags to use for Kasm CPX firewall rules"
|
||||
type = object({
|
||||
webapp = list(string)
|
||||
database = list(string)
|
||||
agent = list(string)
|
||||
cpx = optional(list(string), [])
|
||||
windows = optional(list(string), [])
|
||||
})
|
||||
default = {
|
||||
webapp = ["webapp"]
|
||||
database = ["database"]
|
||||
agent = ["kasm-agent"]
|
||||
cpx = ["kasm-cpx"]
|
||||
windows = ["kasm-windows"]
|
||||
}
|
||||
}
|
||||
|
||||
variable "custom_firewall_rules" {
|
||||
description = "Additional, custom firewall rules"
|
||||
type = list(object({
|
||||
name = string
|
||||
description = optional(string, null)
|
||||
direction = optional(string, null)
|
||||
priority = optional(number, null)
|
||||
ranges = optional(list(string), null)
|
||||
source_tags = optional(list(string), null)
|
||||
source_service_accounts = optional(list(string), null)
|
||||
target_tags = optional(list(string), null)
|
||||
target_service_accounts = optional(list(string), null)
|
||||
allow = optional(list(object({
|
||||
protocol = string
|
||||
ports = optional(list(string))
|
||||
})), null)
|
||||
deny = optional(list(object({
|
||||
protocol = string
|
||||
ports = optional(list(string))
|
||||
})), null)
|
||||
log_config = optional(object({
|
||||
metadata = string
|
||||
}), null)
|
||||
}))
|
||||
default = []
|
||||
}
|
||||
|
||||
## Add any required custom routes to match your environment
|
||||
variable "custom_kasm_routes" {
|
||||
description = "Custom routes to add to VPC"
|
||||
type = list(object({
|
||||
name = string
|
||||
destination_range = string
|
||||
description = optional(string, null)
|
||||
priority = optional(number, null)
|
||||
next_hop_internet = optional(bool, false)
|
||||
next_hop_ip = optional(string, null)
|
||||
next_hop_instance = optional(string, null)
|
||||
next_hop_instance_zone = optional(string, null)
|
||||
next_hop_vpn_tunnel = optional(string, null)
|
||||
next_hop_ilb = optional(string, null)
|
||||
tags = optional(list(string), [])
|
||||
}))
|
||||
default = []
|
||||
}
|
||||
|
||||
## Default labels to apply to all resources
|
||||
variable "resource_labels" {
|
||||
description = "Default tags to add to Terraform-deployed Kasm services"
|
||||
type = map(any)
|
||||
default = null
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue