MIG and ILB modules (#61)
* preliminary net-ilb module, untested * outputs * fix basic mistakes, add initial test * test variable defaults on all resources * README stub * net-ilb module fixes and example * compute-vm module fixes * fix test * remove mig from compute vm module * split out mig from compute-vm (untested) * split out mig from compute-vm (untested) * fix mig versions * small fixes and examples for mig module * Update README.md * Update README.md * switch mig to using a single variable for both region and zone
This commit is contained in:
parent
5088ed61ff
commit
be3c461cf9
|
@ -0,0 +1,188 @@
|
|||
# GCE Managed Instance Group module
|
||||
|
||||
This module allows creating a managed instance group supporting one or more application versions via instance templates. A health check and an autoscaler can also be optionally created.
|
||||
|
||||
This module can be coupled with the [`compute-vm`](../compute-vm) module which can manage instance templates, and the [`net-ilb`](../net-ilb) module to assign the MIG to a backend wired to an Internal Load Balancer. The first use case is shown in the examples below.
|
||||
|
||||
## Examples
|
||||
|
||||
This example shows how to manage a simple MIG that leverages the `compute-vm` module to manage the underlying instance template. The following sub-examples will only show how to enable specific features of this module, and won't replicate the combined setup.
|
||||
|
||||
```hcl
|
||||
module "cos-nginx" {
|
||||
source = "./modules/cloud-config-container/nginx"
|
||||
}
|
||||
|
||||
module "nginx-template" {
|
||||
source = "./modules/compute-vm"
|
||||
project_id = "my-project"
|
||||
region = "europe-west1"
|
||||
zone = "europe-west1-b"
|
||||
name = "ilb-test"
|
||||
network_interfaces = [{
|
||||
network = local.network_self_link,
|
||||
subnetwork = local.subnetwork_self_link,
|
||||
nat = false,
|
||||
addresses = null
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
tags = ["http-server", "ssh"]
|
||||
use_instance_template = true
|
||||
metadata = {
|
||||
user-data = module.cos-nginx.cloud_config
|
||||
}
|
||||
}
|
||||
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 2
|
||||
default_version = {
|
||||
instance_template = module.nginx-template.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple versions
|
||||
|
||||
If multiple versions are desired, use more `compute-vm` instances for the additional templates used in each version (not shown here), and reference them like this:
|
||||
|
||||
```hcl
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template-default.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
versions = {
|
||||
canary = {
|
||||
instance_template = module.nginx-template-default.template.self_link
|
||||
target_type = "fixed"
|
||||
target_size = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Health check and autohealing policies
|
||||
|
||||
Autohealing policies can use an externally defined health check, or have this module auto-create one:
|
||||
|
||||
```hcl
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template-default.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
auto_healing_policies = {
|
||||
health_check = module.nginx-mig.health_check.self_link
|
||||
initial_delay_sec = 30
|
||||
}
|
||||
health_check_config = {
|
||||
type = "http"
|
||||
check = { port = 80 }
|
||||
config = {}
|
||||
logging = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Autoscaling
|
||||
|
||||
The module can create and manage an autoscaler associated with the MIG. When using autoscaling do not set the `target_size` variable or set it to `null`. Here we show a CPU utilization autoscaler, the other available modes are load balancing utilization and custom metric, like the underlying autoscaler resource.
|
||||
|
||||
```hcl
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template-default.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
autoscaler_config = {
|
||||
max_replicas = 3
|
||||
min_replicas = 1
|
||||
cooldown_period = 30
|
||||
cpu_utilization_target = 0.65
|
||||
load_balancing_utilization_target = null
|
||||
metric = null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update policy
|
||||
|
||||
```hcl
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template-default.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
update_policy = {
|
||||
type = "PROACTIVE"
|
||||
minimal_action = "REPLACE"
|
||||
min_ready_sec = 30
|
||||
max_surge_type = "fixed"
|
||||
max_surge = 1
|
||||
max_unavailable_type = null
|
||||
max_unavailable = null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---: |:---:|:---:|
|
||||
| default_version | Default application version template. Additional versions can be specified via the `versions` variable. | <code title="object({ instance_template = string name = string })">object({...})</code> | ✓ | |
|
||||
| location | Compute zone, or region if `regional` is set to true. | <code title="">string</code> | ✓ | |
|
||||
| name | Managed group name. | <code title="">string</code> | ✓ | |
|
||||
| project_id | Project id. | <code title="">string</code> | ✓ | |
|
||||
| *auto_healing_policies* | Auto-healing policies for this group. | <code title="object({ health_check = string initial_delay_sec = number })">object({...})</code> | | <code title="">null</code> |
|
||||
| *autoscaler_config* | Optional autoscaler configuration. Only one of 'cpu_utilization_target' 'load_balancing_utilization_target' or 'metric' can be not null. | <code title="object({ max_replicas = number min_replicas = number cooldown_period = number cpu_utilization_target = number load_balancing_utilization_target = number metric = object({ name = string single_instance_assignment = number target = number type = string # GAUGE, DELTA_PER_SECOND, DELTA_PER_MINUTE filter = string }) })">object({...})</code> | | <code title="">null</code> |
|
||||
| *health_check_config* | Optional auto-created helth check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | <code title="object({ type = string # http https tcp ssl http2 check = map(any) # actual health check block attributes config = map(number) # interval, thresholds, timeout logging = bool })">object({...})</code> | | <code title="">null</code> |
|
||||
| *named_ports* | Named ports. | <code title="map(number)">map(number)</code> | | <code title="">null</code> |
|
||||
| *regional* | Use regional instance group. When set, `location` should be set to the region. | <code title="">bool</code> | | <code title="">false</code> |
|
||||
| *target_pools* | Optional list of URLs for target pools to which new instances in the group are added. | <code title="list(string)">list(string)</code> | | <code title="">[]</code> |
|
||||
| *target_size* | Group target size, leave null when using an autoscaler. | <code title="">number</code> | | <code title="">null</code> |
|
||||
| *update_policy* | Update policy. Type can be 'OPPORTUNISTIC' or 'PROACTIVE', action 'REPLACE' or 'restart', surge type 'fixed' or 'percent'. | <code title="object({ type = string # OPPORTUNISTIC | PROACTIVE minimal_action = string # REPLACE | RESTART min_ready_sec = number max_surge_type = string # fixed | percent max_surge = number max_unavailable_type = string max_unavailable = number })">object({...})</code> | | <code title="">null</code> |
|
||||
| *versions* | Additional application versions, target_type is either 'fixed' or 'percent'. | <code title="map(object({ instance_template = string target_type = string # fixed | percent target_size = number }))">map(object({...}))</code> | | <code title="">null</code> |
|
||||
| *wait_for_instances* | Wait for all instances to be created/updated before returning. | <code title="">bool</code> | | <code title="">null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| autoscaler | Auto-created autoscaler resource. | |
|
||||
| group_manager | Instance group resource. | |
|
||||
| health_check | Auto-created health-check resource. | |
|
||||
<!-- END TFDOC -->
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] add support for instance groups
|
|
@ -0,0 +1,367 @@
|
|||
/**
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
resource "google_compute_autoscaler" "default" {
|
||||
provider = google-beta
|
||||
count = var.regional || var.autoscaler_config == null ? 0 : 1
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
zone = var.location
|
||||
target = google_compute_instance_group_manager.default.0.id
|
||||
|
||||
autoscaling_policy {
|
||||
max_replicas = var.autoscaler_config.max_replicas
|
||||
min_replicas = var.autoscaler_config.min_replicas
|
||||
cooldown_period = var.autoscaler_config.cooldown_period
|
||||
|
||||
dynamic cpu_utilization {
|
||||
for_each = (
|
||||
var.autoscaler_config.cpu_utilization_target == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
target = var.autoscaler_config.cpu_utilization_target
|
||||
}
|
||||
}
|
||||
|
||||
dynamic load_balancing_utilization {
|
||||
for_each = (
|
||||
var.autoscaler_config.load_balancing_utilization_target == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
target = var.autoscaler_config.load_balancing_utilization_target
|
||||
}
|
||||
}
|
||||
|
||||
dynamic metric {
|
||||
for_each = (
|
||||
var.autoscaler_config.metric == null
|
||||
? []
|
||||
: [var.autoscaler_config.metric]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
name = config.value.name
|
||||
single_instance_assignment = config.value.single_instance_assignment
|
||||
target = config.value.target
|
||||
type = config.value.type
|
||||
filter = config.value.filter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "google_compute_instance_group_manager" "default" {
|
||||
provider = google-beta
|
||||
count = var.regional ? 0 : 1
|
||||
project = var.project_id
|
||||
zone = var.location
|
||||
name = var.name
|
||||
base_instance_name = var.name
|
||||
description = "Terraform-managed."
|
||||
target_size = var.target_size
|
||||
target_pools = var.target_pools
|
||||
wait_for_instances = var.wait_for_instances
|
||||
dynamic auto_healing_policies {
|
||||
for_each = var.auto_healing_policies == null ? [] : [var.auto_healing_policies]
|
||||
iterator = config
|
||||
content {
|
||||
health_check = config.value.health_check
|
||||
initial_delay_sec = config.value.initial_delay_sec
|
||||
}
|
||||
}
|
||||
dynamic update_policy {
|
||||
for_each = var.update_policy == null ? [] : [var.update_policy]
|
||||
iterator = config
|
||||
content {
|
||||
type = config.value.type
|
||||
minimal_action = config.value.minimal_action
|
||||
min_ready_sec = config.value.min_ready_sec
|
||||
max_surge_fixed = (
|
||||
config.value.max_surge_type == "fixed" ? config.value.max_surge : null
|
||||
)
|
||||
max_surge_percent = (
|
||||
config.value.max_surge_type == "percent" ? config.value.max_surge : null
|
||||
)
|
||||
max_unavailable_fixed = (
|
||||
config.value.max_unavailable_type == "fixed" ? config.value.max_unavailable : null
|
||||
)
|
||||
max_unavailable_percent = (
|
||||
config.value.max_unavailable_type == "percent" ? config.value.max_unavailable : null
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic named_port {
|
||||
for_each = var.named_ports == null ? {} : var.named_ports
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
version {
|
||||
instance_template = var.default_version.instance_template
|
||||
name = var.default_version.name
|
||||
}
|
||||
dynamic version {
|
||||
for_each = var.versions == null ? {} : var.versions
|
||||
iterator = version
|
||||
content {
|
||||
name = version.key
|
||||
instance_template = version.value.instance_template
|
||||
target_size {
|
||||
fixed = (
|
||||
version.value.target_type == "fixed" ? version.value.target_size : null
|
||||
)
|
||||
percent = (
|
||||
version.value.target_type == "percent" ? version.value.target_size : null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "google_compute_region_autoscaler" "default" {
|
||||
provider = google-beta
|
||||
count = var.regional && var.autoscaler_config != null ? 1 : 0
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
region = var.location
|
||||
target = google_compute_region_instance_group_manager.default.0.id
|
||||
|
||||
autoscaling_policy {
|
||||
max_replicas = var.autoscaler_config.max_replicas
|
||||
min_replicas = var.autoscaler_config.min_replicas
|
||||
cooldown_period = var.autoscaler_config.cooldown_period
|
||||
|
||||
dynamic cpu_utilization {
|
||||
for_each = (
|
||||
var.autoscaler_config.cpu_utilization_target == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
target = var.autoscaler_config.cpu_utilization_target
|
||||
}
|
||||
}
|
||||
|
||||
dynamic load_balancing_utilization {
|
||||
for_each = (
|
||||
var.autoscaler_config.load_balancing_utilization_target == null ? [] : [""]
|
||||
)
|
||||
content {
|
||||
target = var.autoscaler_config.load_balancing_utilization_target
|
||||
}
|
||||
}
|
||||
|
||||
dynamic metric {
|
||||
for_each = (
|
||||
var.autoscaler_config.metric == null
|
||||
? []
|
||||
: [var.autoscaler_config.metric]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
name = config.value.name
|
||||
single_instance_assignment = config.value.single_instance_assignment
|
||||
target = config.value.target
|
||||
type = config.value.type
|
||||
filter = config.value.filter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "google_compute_region_instance_group_manager" "default" {
|
||||
provider = google-beta
|
||||
count = var.regional ? 1 : 0
|
||||
project = var.project_id
|
||||
region = var.location
|
||||
name = var.name
|
||||
base_instance_name = var.name
|
||||
description = "Terraform-managed."
|
||||
target_size = var.target_size
|
||||
target_pools = var.target_pools
|
||||
wait_for_instances = var.wait_for_instances
|
||||
dynamic auto_healing_policies {
|
||||
for_each = var.auto_healing_policies == null ? [] : [var.auto_healing_policies]
|
||||
iterator = config
|
||||
content {
|
||||
health_check = config.value.health_check
|
||||
initial_delay_sec = config.value.initial_delay_sec
|
||||
}
|
||||
}
|
||||
dynamic update_policy {
|
||||
for_each = var.update_policy == null ? [] : [var.update_policy]
|
||||
iterator = config
|
||||
content {
|
||||
type = config.value.type
|
||||
minimal_action = config.value.minimal_action
|
||||
min_ready_sec = config.value.min_ready_sec
|
||||
max_surge_fixed = (
|
||||
config.value.max_surge_type == "fixed" ? config.value.max_surge : null
|
||||
)
|
||||
max_surge_percent = (
|
||||
config.value.max_surge_type == "percent" ? config.value.max_surge : null
|
||||
)
|
||||
max_unavailable_fixed = (
|
||||
config.value.max_unavailable_type == "fixed" ? config.value.max_unavailable : null
|
||||
)
|
||||
max_unavailable_percent = (
|
||||
config.value.max_unavailable_type == "percent" ? config.value.max_unavailable : null
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic named_port {
|
||||
for_each = var.named_ports == null ? {} : var.named_ports
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
version {
|
||||
instance_template = var.default_version.instance_template
|
||||
name = var.default_version.name
|
||||
}
|
||||
dynamic version {
|
||||
for_each = var.versions == null ? {} : var.versions
|
||||
iterator = version
|
||||
content {
|
||||
name = version.key
|
||||
instance_template = version.value.instance_template
|
||||
target_size {
|
||||
fixed = (
|
||||
version.value.target_type == "fixed" ? version.value.target_size : null
|
||||
)
|
||||
percent = (
|
||||
version.value.target_type == "percent" ? version.value.target_size : null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_health_check" "default" {
|
||||
provider = google-beta
|
||||
count = var.health_check_config == null ? 0 : 1
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
|
||||
check_interval_sec = try(var.health_check_config.config.check_interval_sec, null)
|
||||
healthy_threshold = try(var.health_check_config.config.healthy_threshold, null)
|
||||
timeout_sec = try(var.health_check_config.config.timeout_sec, null)
|
||||
unhealthy_threshold = try(var.health_check_config.config.unhealthy_threshold, null)
|
||||
|
||||
dynamic http_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "http"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic https_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "https"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic tcp_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "tcp"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request = try(check.value.request, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic ssl_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "ssl"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request = try(check.value.request, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic http2_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "http2"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic log_config {
|
||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
||||
content {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
output "autoscaler" {
|
||||
description = "Auto-created autoscaler resource."
|
||||
value = var.autoscaler_config == null ? null : try(
|
||||
google_compute_autoscaler.default.0,
|
||||
google_compute_region_autoscaler.default.0,
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
output "group_manager" {
|
||||
description = "Instance group resource."
|
||||
value = try(
|
||||
google_compute_instance_group_manager.default.0,
|
||||
google_compute_region_instance_group_manager.default.0,
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
output "health_check" {
|
||||
description = "Auto-created health-check resource."
|
||||
value = var.health_check_config == null ? null : try(
|
||||
google_compute_health_check.default.0, {}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "autoscaler_config" {
|
||||
description = "Optional autoscaler configuration. Only one of 'cpu_utilization_target' 'load_balancing_utilization_target' or 'metric' can be not null."
|
||||
type = object({
|
||||
max_replicas = number
|
||||
min_replicas = number
|
||||
cooldown_period = number
|
||||
cpu_utilization_target = number
|
||||
load_balancing_utilization_target = number
|
||||
metric = object({
|
||||
name = string
|
||||
single_instance_assignment = number
|
||||
target = number
|
||||
type = string # GAUGE, DELTA_PER_SECOND, DELTA_PER_MINUTE
|
||||
filter = string
|
||||
})
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "auto_healing_policies" {
|
||||
description = "Auto-healing policies for this group."
|
||||
type = object({
|
||||
health_check = string
|
||||
initial_delay_sec = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_version" {
|
||||
description = "Default application version template. Additional versions can be specified via the `versions` variable."
|
||||
type = object({
|
||||
instance_template = string
|
||||
name = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "health_check_config" {
|
||||
description = "Optional auto-created helth check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage."
|
||||
type = object({
|
||||
type = string # http https tcp ssl http2
|
||||
check = map(any) # actual health check block attributes
|
||||
config = map(number) # interval, thresholds, timeout
|
||||
logging = bool
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
description = "Compute zone, or region if `regional` is set to true."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Managed group name."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "named_ports" {
|
||||
description = "Named ports."
|
||||
type = map(number)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "regional" {
|
||||
description = "Use regional instance group. When set, `location` should be set to the region."
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "target_pools" {
|
||||
description = "Optional list of URLs for target pools to which new instances in the group are added."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "target_size" {
|
||||
description = "Group target size, leave null when using an autoscaler."
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "update_policy" {
|
||||
description = "Update policy. Type can be 'OPPORTUNISTIC' or 'PROACTIVE', action 'REPLACE' or 'restart', surge type 'fixed' or 'percent'."
|
||||
type = object({
|
||||
type = string # OPPORTUNISTIC | PROACTIVE
|
||||
minimal_action = string # REPLACE | RESTART
|
||||
min_ready_sec = number
|
||||
max_surge_type = string # fixed | percent
|
||||
max_surge = number
|
||||
max_unavailable_type = string
|
||||
max_unavailable = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "versions" {
|
||||
description = "Additional application versions, target_type is either 'fixed' or 'percent'."
|
||||
type = map(object({
|
||||
instance_template = string
|
||||
target_type = string # fixed | percent
|
||||
target_size = number
|
||||
}))
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "wait_for_instances" {
|
||||
description = "Wait for all instances to be created/updated before returning."
|
||||
type = bool
|
||||
default = null
|
||||
}
|
|
@ -1,6 +1,11 @@
|
|||
# Google Compute Engine VM module
|
||||
|
||||
This module allows creating one or multiple instances or an instance template for a specific configuration. A service account is optionally created and assigned if not specified.
|
||||
This module can operate in two distinct modes:
|
||||
|
||||
- instance creation, with optional unmanaged group
|
||||
- instance template creation
|
||||
|
||||
In both modes, an optional service account can be created and assigned to either instances or template. If you need a managed instance group when using the module in template mode, refer to the [`compute-mig`](../compute-mig) module.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -57,9 +62,9 @@ module "debian-test" {
|
|||
}
|
||||
```
|
||||
|
||||
### Managed instance group
|
||||
### Instance group
|
||||
|
||||
This example shows a basic instance where the module is used to create an instance template, and the template is associated to a basic managed instance group with no autohealing or autoscaling configuration. Instance group support is meant for prototyping, or in those situations where there's no need to manage multiple application versions.
|
||||
If an instance group is needed when operating in instance mode, simply set the `group` variable to a non null map. The map can contain named port declarations, or be empty if named ports are not needed.
|
||||
|
||||
```hcl
|
||||
module "instance-group" {
|
||||
|
@ -85,16 +90,7 @@ module "instance-group" {
|
|||
metadata = {
|
||||
user-data = local.cloud_config
|
||||
}
|
||||
group_manager = {
|
||||
auto_healing_policies = null
|
||||
options = null
|
||||
update_policy = null
|
||||
named_ports = {}
|
||||
regional = false
|
||||
target_size = 2
|
||||
versions = []
|
||||
default = module.instance-group.template.self_link
|
||||
}
|
||||
group = {}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -112,8 +108,7 @@ module "instance-group" {
|
|||
| *attached_disk_defaults* | Defaults for attached disks options. | <code title="object({ auto_delete = bool mode = string type = string source = string })">object({...})</code> | | <code title="{ auto_delete = true source = null mode = "READ_WRITE" type = "pd-ssd" }">...</code> |
|
||||
| *attached_disks* | Additional disks, if options is null defaults will be used in its place. | <code title="list(object({ name = string image = string size = string options = object({ auto_delete = bool mode = string source = string type = string }) }))">list(object({...}))</code> | | <code title="">[]</code> |
|
||||
| *boot_disk* | Boot disk properties. | <code title="object({ image = string size = number type = string })">object({...})</code> | | <code title="{ image = "projects/debian-cloud/global/images/family/debian-10" type = "pd-ssd" size = 10 }">...</code> |
|
||||
| *group* | Instance group (for instance use). | <code title="object({ named_ports = map(number) })">object({...})</code> | | <code title="">null</code> |
|
||||
| *group_manager* | Instance group manager (for template use). | <code title="object({ auto_healing_policies = object({ health_check = string initial_delay_sec = number }) named_ports = map(number) options = object({ target_pools = list(string) wait_for_instances = bool }) regional = bool target_size = number update_policy = object({ type = string # OPPORTUNISTIC | PROACTIVE minimal_action = string # REPLACE | RESTART min_ready_sec = number max_surge_type = string # fixed | percent max_surge = number max_unavailable_type = string max_unavailable = number }) versions = list(object({ name = string instance_template = string target_type = string # fixed | percent target_size = number })) })">object({...})</code> | | <code title="">null</code> |
|
||||
| *group* | Define this variable to create an instance group for instances. Disabled for template use. | <code title="object({ named_ports = map(number) })">object({...})</code> | | <code title="">null</code> |
|
||||
| *hostname* | Instance FQDN name. | <code title="">string</code> | | <code title="">null</code> |
|
||||
| *instance_count* | Number of instances to create (only for non-template usage). | <code title="">number</code> | | <code title="">1</code> |
|
||||
| *instance_type* | Instance type. | <code title="">string</code> | | <code title="">f1-micro</code> |
|
||||
|
@ -134,7 +129,6 @@ module "instance-group" {
|
|||
|---|---|:---:|
|
||||
| external_ips | Instance main interface external IP addresses. | |
|
||||
| group | Instance group resource. | |
|
||||
| group_manager | Instance group resource. | |
|
||||
| instances | Instance resources. | |
|
||||
| internal_ips | Instance main interface internal IP addresses. | |
|
||||
| names | Instance names. | |
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/**
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
resource "google_compute_instance_group" "unmanaged" {
|
||||
count = (
|
||||
var.group != null && ! var.use_instance_template ? 1 : 0
|
||||
)
|
||||
project = var.project_id
|
||||
network = (
|
||||
length(var.network_interfaces) > 0
|
||||
? var.network_interfaces.0.network
|
||||
: ""
|
||||
)
|
||||
zone = var.zone
|
||||
name = var.name
|
||||
description = "Terraform-managed."
|
||||
instances = [
|
||||
for name, instance in google_compute_instance.default : instance.self_link
|
||||
]
|
||||
dynamic named_port {
|
||||
for_each = var.group.named_ports != null ? var.group.named_ports : {}
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "managed" {
|
||||
count = (
|
||||
var.group_manager != null && var.use_instance_template
|
||||
? var.group_manager.regional ? 0 : 1
|
||||
: 0
|
||||
)
|
||||
project = var.project_id
|
||||
zone = var.zone
|
||||
name = var.name
|
||||
base_instance_name = var.name
|
||||
description = "Terraform-managed."
|
||||
target_size = var.group_manager.target_size
|
||||
target_pools = (
|
||||
var.group_manager.options == null
|
||||
? null
|
||||
: var.group_manager.options.target_pools
|
||||
)
|
||||
wait_for_instances = (
|
||||
var.group_manager.options == null
|
||||
? null
|
||||
: var.group_manager.options.wait_for_instances
|
||||
)
|
||||
dynamic auto_healing_policies {
|
||||
for_each = (
|
||||
var.group_manager.auto_healing_policies == null
|
||||
? []
|
||||
: [var.group_manager.auto_healing_policies]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
health_check = config.value.health_check
|
||||
initial_delay_sec = config.value.initial_delay_sec
|
||||
}
|
||||
}
|
||||
dynamic update_policy {
|
||||
for_each = (
|
||||
var.group_manager.update_policy == null
|
||||
? []
|
||||
: [var.group_manager.update_policy]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
type = config.value.type
|
||||
minimal_action = config.value.minimal_action
|
||||
min_ready_sec = config.value.min_ready_sec
|
||||
max_surge_fixed = (
|
||||
config.value.max_surge_type == "fixed" ? config.value.max_surge : null
|
||||
)
|
||||
max_surge_percent = (
|
||||
config.value.max_surge_type == "percent" ? config.value.max_surge : null
|
||||
)
|
||||
max_unavailable_fixed = (
|
||||
config.value.max_unavailable_type == "fixed" ? config.value.max_unavailable : null
|
||||
)
|
||||
max_unavailable_percent = (
|
||||
config.value.max_unavailable_type == "percent" ? config.value.max_unavailable : null
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic named_port {
|
||||
for_each = var.group_manager.named_ports != null ? var.group_manager.named_ports : {}
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
version {
|
||||
name = "${var.name}-default"
|
||||
instance_template = google_compute_instance_template.default.0.self_link
|
||||
}
|
||||
dynamic version {
|
||||
for_each = (
|
||||
var.group_manager.versions == null ? [] : var.group_manager.versions
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
name = config.value.name
|
||||
instance_template = config.value.instance_template
|
||||
target_size {
|
||||
fixed = config.value.target_type == "fixed" ? config.value.target_size : null
|
||||
percent = config.value.target_type == "percent" ? config.value.target_size : null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_region_instance_group_manager" "managed" {
|
||||
count = (
|
||||
var.group_manager != null && var.use_instance_template
|
||||
? var.group_manager.regional ? 1 : 0
|
||||
: 0
|
||||
)
|
||||
project = var.project_id
|
||||
region = var.region
|
||||
name = var.name
|
||||
base_instance_name = var.name
|
||||
description = "Terraform-managed."
|
||||
target_size = var.group_manager.target_size
|
||||
target_pools = (
|
||||
var.group_manager.options == null
|
||||
? null
|
||||
: var.group_manager.options.target_pools
|
||||
)
|
||||
wait_for_instances = (
|
||||
var.group_manager.options == null
|
||||
? null
|
||||
: var.group_manager.options.wait_for_instances
|
||||
)
|
||||
dynamic auto_healing_policies {
|
||||
for_each = (
|
||||
var.group_manager.auto_healing_policies == null
|
||||
? []
|
||||
: [var.group_manager.auto_healing_policies]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
health_check = config.value.health_check
|
||||
initial_delay_sec = config.value.initial_delay_sec
|
||||
}
|
||||
}
|
||||
dynamic update_policy {
|
||||
for_each = (
|
||||
var.group_manager.update_policy == null
|
||||
? []
|
||||
: [var.group_manager.update_policy]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
type = config.value.type
|
||||
minimal_action = config.value.minimal_action
|
||||
min_ready_sec = config.value.min_ready_sec
|
||||
max_surge_fixed = (
|
||||
config.value.max_surge_type == "fixed" ? config.value.max_surge : null
|
||||
)
|
||||
max_surge_percent = (
|
||||
config.value.max_surge_type == "percent" ? config.value.max_surge : null
|
||||
)
|
||||
max_unavailable_fixed = (
|
||||
config.value.max_unavailable_type == "fixed" ? config.value.max_unavailable : null
|
||||
)
|
||||
max_unavailable_percent = (
|
||||
config.value.max_unavailable_type == "percent" ? config.value.max_unavailable : null
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic named_port {
|
||||
for_each = var.group.named_ports
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
version {
|
||||
name = "${var.name}-default"
|
||||
instance_template = google_compute_instance_template.default.0.self_link
|
||||
}
|
||||
dynamic version {
|
||||
for_each = (
|
||||
var.group_manager.versions == null ? [] : [var.group_manager.versions]
|
||||
)
|
||||
iterator = config
|
||||
content {
|
||||
name = config.value.name
|
||||
instance_template = config.value.instance_template
|
||||
target_size {
|
||||
fixed = config.value.target_type == "fixed" ? config.value.target_size : null
|
||||
percent = config.value.target_type == "percent" ? config.value.target_size : null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -218,6 +218,32 @@ resource "google_compute_instance_template" "default" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group" "unmanaged" {
|
||||
count = (
|
||||
var.group != null && ! var.use_instance_template ? 1 : 0
|
||||
)
|
||||
project = var.project_id
|
||||
network = (
|
||||
length(var.network_interfaces) > 0
|
||||
? var.network_interfaces.0.network
|
||||
: ""
|
||||
)
|
||||
zone = var.zone
|
||||
name = var.name
|
||||
description = "Terraform-managed."
|
||||
instances = [
|
||||
for name, instance in google_compute_instance.default : instance.self_link
|
||||
]
|
||||
dynamic named_port {
|
||||
for_each = var.group.named_ports != null ? var.group.named_ports : {}
|
||||
iterator = config
|
||||
content {
|
||||
name = config.key
|
||||
port = config.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_service_account" "service_account" {
|
||||
count = var.service_account_create ? 1 : 0
|
||||
project = var.project_id
|
||||
|
|
|
@ -28,24 +28,7 @@ output "external_ips" {
|
|||
|
||||
output "group" {
|
||||
description = "Instance group resource."
|
||||
value = (
|
||||
length(google_compute_instance_group.unmanaged) > 0
|
||||
? google_compute_instance_group.unmanaged.0
|
||||
: null
|
||||
)
|
||||
}
|
||||
|
||||
output "group_manager" {
|
||||
description = "Instance group resource."
|
||||
value = (
|
||||
length(google_compute_instance_group_manager.managed) > 0
|
||||
? google_compute_instance_group_manager.managed.0
|
||||
: (
|
||||
length(google_compute_region_instance_group_manager.managed) > 0
|
||||
? google_compute_region_instance_group_manager.managed.0
|
||||
: null
|
||||
)
|
||||
)
|
||||
value = try(google_compute_instance_group.unmanaged.0, null)
|
||||
}
|
||||
|
||||
output "instances" {
|
||||
|
|
|
@ -61,46 +61,13 @@ variable "boot_disk" {
|
|||
}
|
||||
|
||||
variable "group" {
|
||||
description = "Instance group (for instance use)."
|
||||
description = "Define this variable to create an instance group for instances. Disabled for template use."
|
||||
type = object({
|
||||
named_ports = map(number)
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "group_manager" {
|
||||
description = "Instance group manager (for template use)."
|
||||
type = object({
|
||||
auto_healing_policies = object({
|
||||
health_check = string
|
||||
initial_delay_sec = number
|
||||
})
|
||||
named_ports = map(number)
|
||||
options = object({
|
||||
target_pools = list(string)
|
||||
wait_for_instances = bool
|
||||
})
|
||||
regional = bool
|
||||
target_size = number
|
||||
update_policy = object({
|
||||
type = string # OPPORTUNISTIC | PROACTIVE
|
||||
minimal_action = string # REPLACE | RESTART
|
||||
min_ready_sec = number
|
||||
max_surge_type = string # fixed | percent
|
||||
max_surge = number
|
||||
max_unavailable_type = string
|
||||
max_unavailable = number
|
||||
})
|
||||
versions = list(object({
|
||||
name = string
|
||||
instance_template = string
|
||||
target_type = string # fixed | percent
|
||||
target_size = number
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Instance FQDN name."
|
||||
type = string
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
# Internal Load Balancer Module
|
||||
|
||||
This module allows managing a GCE Internal Load Balancer and integrates the forwarding rule, regional backend, and optional health check resources. It's designed to be a simple match for the [`compute-vm`](../compute-vm) module, which can be used to manage instance templates and instance groups.
|
||||
|
||||
## Issues
|
||||
|
||||
TODO(ludoo): check if this is still the case after splitting out MIG from compute-vm
|
||||
|
||||
There are some corner cases (eg when switching the instance template from internal service account to an externally managed one) where Terraform raises a cycle error on apply. In these situations, run successive applies targeting resources used in the template first then the template itself, and the cycle should be fixed.
|
||||
|
||||
One other issue is a `Provider produced inconsistent final plan` error which is sometimes raised when switching template version. This seems to be related to this [open provider issue](https://github.com/terraform-providers/terraform-provider-google/issues/3937), but it's relatively harmless since the resource is updated, and subsequent applies raise no errors.
|
||||
|
||||
## Example
|
||||
|
||||
This example spins up a simple HTTP server and combines four modules:
|
||||
|
||||
- [`nginx`](../cloud-config-container/nginx) from the `cloud-config-container` collection, to manage instance configuration
|
||||
- [`compute-vm`](../compute-vm) to manage the instance template and unmanaged instance group
|
||||
- this module to create an Internal Load Balancer in front of the managed instance group
|
||||
|
||||
Note that the example uses the GCE default service account. You might want to create an ad-hoc service account by combining the [`iam-service-accounts`](../iam-service-accounts) module, or by having the GCE VM module create one for you. In both cases, remember to set at least logging write permissions for the service account, or the container on the instances won't be able to start.
|
||||
|
||||
```hcl
|
||||
module "cos-nginx" {
|
||||
source = "./modules/cloud-config-container/nginx"
|
||||
}
|
||||
|
||||
module "instance-group" {
|
||||
source = "./modules/compute-vm"
|
||||
project_id = "my-project"
|
||||
region = "europe-west1"
|
||||
zone = "europe-west1-b"
|
||||
name = "ilb-test"
|
||||
network_interfaces = [{
|
||||
network = local.network_self_link,
|
||||
subnetwork = local.subnetwork_self_link,
|
||||
nat = false,
|
||||
addresses = null
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
tags = ["http-server", "ssh"]
|
||||
metadata = {
|
||||
user-data = module.cos-nginx.cloud_config
|
||||
}
|
||||
group = {}
|
||||
}
|
||||
|
||||
module "ilb" {
|
||||
source = "./modules/net-ilb"
|
||||
project_id = "my-project"
|
||||
region = "europe-west1"
|
||||
name = "ilb-test"
|
||||
service_label = "ilb-test"
|
||||
network = local.network_self_link
|
||||
subnetwork = local.subnetwork_self_link
|
||||
ports = [80]
|
||||
backends = [{
|
||||
failover = false
|
||||
group = module.instance-group.group.self_link
|
||||
balancing_mode = "CONNECTION"
|
||||
}]
|
||||
health_check_config = {
|
||||
type = "http", check = { port = 80 }, config = {}, logging = true
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---: |:---:|:---:|
|
||||
| backends | Load balancer backends, balancing mode is one of 'CONNECTION' or 'UTILIZATION'. | <code title="list(object({ failover = bool group = string balancing_mode = string }))">list(object({...}))</code> | ✓ | |
|
||||
| name | Name used for all resources. | <code title="">string</code> | ✓ | |
|
||||
| network | Network used for resources. | <code title="">string</code> | ✓ | |
|
||||
| project_id | Project id where resources will be created. | <code title="">string</code> | ✓ | |
|
||||
| region | GCP region. | <code title="">string</code> | ✓ | |
|
||||
| subnetwork | Subnetwork used for the forwarding rule. | <code title="">string</code> | ✓ | |
|
||||
| *address* | Optional IP address used for the forwarding rule. | <code title="">string</code> | | <code title="">null</code> |
|
||||
| *backend_config* | Optional backend configuration. | <code title="object({ session_affinity = string timeout_sec = number connection_draining_timeout_sec = number })">object({...})</code> | | <code title="">null</code> |
|
||||
| *failover_config* | Optional failover configuration. | <code title="object({ disable_connection_drain = bool drop_traffic_if_unhealthy = bool ratio = number })">object({...})</code> | | <code title="">null</code> |
|
||||
| *global_access* | Global access, defaults to false if not set. | <code title="">bool</code> | | <code title="">null</code> |
|
||||
| *health_check* | Name of existing health check to use, disables auto-created health check. | <code title="">string</code> | | <code title="">null</code> |
|
||||
| *health_check_config* | Configuration of the auto-created helth check. | <code title="object({ type = string # http https tcp ssl http2 check = map(any) # actual health check block attributes config = map(number) # interval, thresholds, timeout })">object({...})</code> | | <code title="{ type = "http" check = { port_specification = "USE_SERVING_PORT" } config = {} }">...</code> |
|
||||
| *labels* | Labels set on resources. | <code title="map(string)">map(string)</code> | | <code title="">{}</code> |
|
||||
| *log_sample_rate* | Set a value between 0 and 1 to enable logging for resources, and set the sampling rate for backend logging. | <code title="">number</code> | | <code title="">null</code> |
|
||||
| *ports* | Comma-separated ports, leave null to use all ports. | <code title="list(string)">list(string)</code> | | <code title="">null</code> |
|
||||
| *protocol* | IP protocol used, defaults to TCP. | <code title="">string</code> | | <code title="">TCP</code> |
|
||||
| *service_label* | Optional prefix of the fully qualified forwarding rule name. | <code title="">string</code> | | <code title="">null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| backend | Backend resource. | |
|
||||
| backend_id | Backend id. | |
|
||||
| backend_self_link | Backend self link. | |
|
||||
| forwarding_rule | Forwarding rule resource. | |
|
||||
| forwarding_rule_address | Forwarding rule address. | |
|
||||
| forwarding_rule_id | Forwarding rule id. | |
|
||||
| forwarding_rule_self_link | Forwarding rule self link. | |
|
||||
| health_check | Auto-created health-check resource. | |
|
||||
| health_check_self_id | Auto-created health-check self id. | |
|
||||
| health_check_self_link | Auto-created health-check self link. | |
|
||||
<!-- END TFDOC -->
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
locals {
|
||||
health_check = (
|
||||
var.health_check == null
|
||||
? try(google_compute_health_check.default.0.self_link, null)
|
||||
: var.health_check
|
||||
)
|
||||
}
|
||||
|
||||
resource "google_compute_forwarding_rule" "default" {
|
||||
provider = google-beta
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
load_balancing_scheme = "INTERNAL"
|
||||
region = var.region
|
||||
network = var.network
|
||||
subnetwork = var.subnetwork
|
||||
ip_address = var.address
|
||||
ip_protocol = var.protocol # TCP | UDP
|
||||
ports = var.ports # "nnnnn" or "nnnnn,nnnnn,nnnnn" max 5
|
||||
service_label = var.service_label
|
||||
all_ports = var.ports == null ? true : null
|
||||
allow_global_access = var.global_access
|
||||
backend_service = google_compute_region_backend_service.default.self_link
|
||||
# is_mirroring_collector = false
|
||||
labels = var.labels
|
||||
}
|
||||
|
||||
resource "google_compute_region_backend_service" "default" {
|
||||
provider = google-beta
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
load_balancing_scheme = "INTERNAL"
|
||||
region = var.region
|
||||
network = var.network
|
||||
health_checks = [local.health_check]
|
||||
protocol = var.protocol
|
||||
|
||||
session_affinity = try(var.backend_config.session_affinity, null)
|
||||
timeout_sec = try(var.backend_config.timeout_sec, null)
|
||||
connection_draining_timeout_sec = try(var.backend_config.connection_draining_timeout_sec, null)
|
||||
|
||||
dynamic backend {
|
||||
for_each = { for b in var.backends : b.group => b }
|
||||
iterator = backend
|
||||
content {
|
||||
balancing_mode = backend.value.balancing_mode
|
||||
description = "Terraform managed."
|
||||
failover = backend.value.failover
|
||||
group = backend.key
|
||||
}
|
||||
}
|
||||
|
||||
dynamic failover_policy {
|
||||
for_each = var.failover_config == null ? [] : [var.failover_config]
|
||||
iterator = config
|
||||
content {
|
||||
disable_connection_drain_on_failover = config.value.disable_connection_drain
|
||||
drop_traffic_if_unhealthy = config.value.drop_traffic_if_unhealthy
|
||||
failover_ratio = config.value.ratio
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "google_compute_health_check" "default" {
|
||||
provider = google-beta
|
||||
count = var.health_check == null ? 1 : 0
|
||||
project = var.project_id
|
||||
name = var.name
|
||||
description = "Terraform managed."
|
||||
|
||||
check_interval_sec = try(var.health_check_config.config.check_interval_sec, null)
|
||||
healthy_threshold = try(var.health_check_config.config.healthy_threshold, null)
|
||||
timeout_sec = try(var.health_check_config.config.timeout_sec, null)
|
||||
unhealthy_threshold = try(var.health_check_config.config.unhealthy_threshold, null)
|
||||
|
||||
dynamic http_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "http"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic https_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "https"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic tcp_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "tcp"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request = try(check.value.request, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic ssl_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "ssl"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request = try(check.value.request, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic http2_health_check {
|
||||
for_each = (
|
||||
try(var.health_check_config.type, null) == "http2"
|
||||
? [var.health_check_config.check]
|
||||
: []
|
||||
)
|
||||
iterator = check
|
||||
content {
|
||||
host = try(check.value.host, null)
|
||||
port = try(check.value.port, null)
|
||||
port_name = try(check.value.port_name, null)
|
||||
port_specification = try(check.value.port_specification, null)
|
||||
proxy_header = try(check.value.proxy_header, null)
|
||||
request_path = try(check.value.request_path, null)
|
||||
response = try(check.value.response, null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic log_config {
|
||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
||||
content {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
output "backend" {
|
||||
description = "Backend resource."
|
||||
value = google_compute_region_backend_service.default
|
||||
}
|
||||
|
||||
output "backend_id" {
|
||||
description = "Backend id."
|
||||
value = google_compute_region_backend_service.default.id
|
||||
}
|
||||
|
||||
output "backend_self_link" {
|
||||
description = "Backend self link."
|
||||
value = google_compute_region_backend_service.default.self_link
|
||||
}
|
||||
|
||||
output "forwarding_rule" {
|
||||
description = "Forwarding rule resource."
|
||||
value = google_compute_forwarding_rule.default
|
||||
}
|
||||
|
||||
output "forwarding_rule_address" {
|
||||
description = "Forwarding rule address."
|
||||
value = google_compute_forwarding_rule.default.ip_address
|
||||
}
|
||||
|
||||
output "forwarding_rule_id" {
|
||||
description = "Forwarding rule id."
|
||||
value = google_compute_forwarding_rule.default.id
|
||||
}
|
||||
|
||||
output "forwarding_rule_self_link" {
|
||||
description = "Forwarding rule self link."
|
||||
value = google_compute_forwarding_rule.default.self_link
|
||||
}
|
||||
|
||||
output "health_check" {
|
||||
description = "Auto-created health-check resource."
|
||||
value = try(google_compute_health_check.default.0, {})
|
||||
}
|
||||
|
||||
output "health_check_self_id" {
|
||||
description = "Auto-created health-check self id."
|
||||
value = try(google_compute_health_check.default.0.id, null)
|
||||
}
|
||||
|
||||
output "health_check_self_link" {
|
||||
description = "Auto-created health-check self link."
|
||||
value = try(google_compute_health_check.default.0.self_link, null)
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "address" {
|
||||
description = "Optional IP address used for the forwarding rule."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "backends" {
|
||||
description = "Load balancer backends, balancing mode is one of 'CONNECTION' or 'UTILIZATION'."
|
||||
type = list(object({
|
||||
failover = bool
|
||||
group = string
|
||||
balancing_mode = string
|
||||
}))
|
||||
}
|
||||
|
||||
variable "backend_config" {
|
||||
description = "Optional backend configuration."
|
||||
type = object({
|
||||
session_affinity = string
|
||||
timeout_sec = number
|
||||
connection_draining_timeout_sec = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "failover_config" {
|
||||
description = "Optional failover configuration."
|
||||
type = object({
|
||||
disable_connection_drain = bool
|
||||
drop_traffic_if_unhealthy = bool
|
||||
ratio = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "global_access" {
|
||||
description = "Global access, defaults to false if not set."
|
||||
type = bool
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "health_check" {
|
||||
description = "Name of existing health check to use, disables auto-created health check."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "health_check_config" {
|
||||
description = "Configuration of the auto-created helth check."
|
||||
type = object({
|
||||
type = string # http https tcp ssl http2
|
||||
check = map(any) # actual health check block attributes
|
||||
config = map(number) # interval, thresholds, timeout
|
||||
logging = bool
|
||||
})
|
||||
default = {
|
||||
type = "http"
|
||||
check = {
|
||||
port_specification = "USE_SERVING_PORT"
|
||||
}
|
||||
config = {}
|
||||
logging = false
|
||||
}
|
||||
}
|
||||
|
||||
variable "labels" {
|
||||
description = "Labels set on resources."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Name used for all resources."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "network" {
|
||||
description = "Network used for resources."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id where resources will be created."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ports" {
|
||||
description = "Comma-separated ports, leave null to use all ports."
|
||||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "protocol" {
|
||||
description = "IP protocol used, defaults to TCP."
|
||||
type = string
|
||||
default = "TCP"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "GCP region."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "service_label" {
|
||||
description = "Optional prefix of the fully qualified forwarding rule name."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "subnetwork" {
|
||||
description = "Subnetwork used for the forwarding rule."
|
||||
type = string
|
||||
}
|
|
@ -30,5 +30,4 @@ module "test" {
|
|||
instance_count = var.instance_count
|
||||
use_instance_template = var.use_instance_template
|
||||
group = var.group
|
||||
group_manager = var.group_manager
|
||||
}
|
||||
|
|
|
@ -19,11 +19,6 @@ variable "group" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "group_manager" {
|
||||
type = any
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
type = number
|
||||
default = 1
|
||||
|
|
|
@ -44,3 +44,12 @@ def test_template(plan_runner):
|
|||
assert len(resources) == 1
|
||||
assert resources[0]['type'] == 'google_compute_instance_template'
|
||||
assert resources[0]['values']['name_prefix'] == 'test-'
|
||||
|
||||
|
||||
def test_group(plan_runner):
|
||||
plan, resources = plan_runner(FIXTURES_DIR, instance_count=2,
|
||||
group='{named_ports={}}')
|
||||
assert len(resources) == 3
|
||||
assert set(r['type'] for r in resources) == set([
|
||||
'google_compute_instance_group', 'google_compute_instance'
|
||||
])
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture')
|
||||
|
||||
|
||||
def test_unmanaged(plan_runner):
|
||||
plan, resources = plan_runner(FIXTURES_DIR, instance_count=2,
|
||||
group='{named_ports={}}')
|
||||
assert len(resources) == 3
|
||||
assert set(r['type'] for r in resources) == set([
|
||||
'google_compute_instance_group', 'google_compute_instance'
|
||||
])
|
||||
|
||||
|
||||
def test_managed(plan_runner):
|
||||
plan, resources = plan_runner(
|
||||
FIXTURES_DIR, use_instance_template='true', group_manager=(
|
||||
'{ '
|
||||
'auto_healing_policies=null, named_ports={}, options=null, '
|
||||
'regional=false, target_size=1, update_policy=null, versions=null'
|
||||
' }'
|
||||
)
|
||||
)
|
||||
assert len(resources) == 2
|
||||
assert set(r['type'] for r in resources) == set([
|
||||
'google_compute_instance_group_manager', 'google_compute_instance_template'
|
||||
])
|
|
@ -0,0 +1,13 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module "test" {
|
||||
source = "../../../../modules/net-ilb"
|
||||
project_id = "my-project"
|
||||
region = "europe-west1"
|
||||
network = "default"
|
||||
subnetwork = "default"
|
||||
name = "ilb-test"
|
||||
labels = {}
|
||||
address = var.address
|
||||
backends = var.backends
|
||||
backend_config = var.backend_config
|
||||
failover_config = var.failover_config
|
||||
global_access = var.global_access
|
||||
health_check = var.health_check
|
||||
health_check_config = var.health_check_config
|
||||
ports = var.ports
|
||||
protocol = var.protocol
|
||||
service_label = var.service_label
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "address" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "backends" {
|
||||
type = list(object({
|
||||
failover = bool
|
||||
group = string
|
||||
balancing_mode = string
|
||||
}))
|
||||
}
|
||||
|
||||
variable "backend_config" {
|
||||
type = object({
|
||||
session_affinity = string
|
||||
timeout_sec = number
|
||||
connection_draining_timeout_sec = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "failover_config" {
|
||||
type = object({
|
||||
disable_connection_drain = bool
|
||||
drop_traffic_if_unhealthy = bool
|
||||
ratio = number
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "global_access" {
|
||||
type = bool
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "health_check" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "health_check_config" {
|
||||
type = object({
|
||||
type = string # http https tcp ssl http2
|
||||
check = map(any) # actual health check block attributes
|
||||
config = map(number) # interval, thresholds, timeout
|
||||
logging = bool
|
||||
})
|
||||
default = {
|
||||
type = "http"
|
||||
check = {
|
||||
port_specification = "USE_SERVING_PORT"
|
||||
}
|
||||
config = {}
|
||||
logging = false
|
||||
}
|
||||
}
|
||||
|
||||
variable "ports" {
|
||||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "protocol" {
|
||||
type = string
|
||||
default = "TCP"
|
||||
}
|
||||
|
||||
variable "service_label" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture')
|
||||
|
||||
_BACKENDS = '[{balancing_mode="CONNECTION", group="foo", failover=false}]'
|
||||
|
||||
|
||||
def test_defaults(plan_runner):
|
||||
"Test variable defaults."
|
||||
_, resources = plan_runner(FIXTURES_DIR, backends=_BACKENDS)
|
||||
assert len(resources) == 3
|
||||
resources = dict((r['type'], r['values']) for r in resources)
|
||||
fwd_rule = resources['google_compute_forwarding_rule']
|
||||
assert fwd_rule['load_balancing_scheme'] == 'INTERNAL'
|
||||
assert fwd_rule['all_ports']
|
||||
assert fwd_rule['allow_global_access'] is None
|
||||
backend = resources['google_compute_region_backend_service']
|
||||
assert len(backend['backend']) == 1
|
||||
assert backend['backend'][0]['group'] == 'foo'
|
||||
health_check = resources['google_compute_health_check']
|
||||
for k, v in health_check.items():
|
||||
if k == 'http_health_check':
|
||||
assert len(v) == 1
|
||||
assert v[0]['port_specification'] == 'USE_SERVING_PORT'
|
||||
elif k.endswith('_health_check'):
|
||||
assert len(v) == 0
|
||||
|
||||
|
||||
def test_forwarding_rule(plan_runner):
|
||||
"Test forwarding rule variables."
|
||||
_, resources = plan_runner(
|
||||
FIXTURES_DIR, backends=_BACKENDS, global_access='true', ports="[80]")
|
||||
assert len(resources) == 3
|
||||
values = [r['values'] for r in resources if r['type']
|
||||
== 'google_compute_forwarding_rule'][0]
|
||||
assert not values['all_ports']
|
||||
assert values['ports'] == ['80']
|
||||
assert values['allow_global_access']
|
Loading…
Reference in New Issue