Refactor compute-mig module for Terraform 1.3 (#931)
* wip: autoscaler * wip: fix autoscaler * wip: health check * wip: untested * wip: tests and examples missing * wip: examples * wip: consumers * blueprint tests * fast
This commit is contained in:
parent
d7e0af75b2
commit
a30c186f1f
|
@ -165,33 +165,31 @@ module "squid-vm" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "squid-mig" {
|
module "squid-mig" {
|
||||||
count = var.mig ? 1 : 0
|
count = var.mig ? 1 : 0
|
||||||
source = "../../../modules/compute-mig"
|
source = "../../../modules/compute-mig"
|
||||||
project_id = module.project-host.project_id
|
project_id = module.project-host.project_id
|
||||||
location = "${var.region}-b"
|
location = "${var.region}-b"
|
||||||
name = "squid-mig"
|
name = "squid-mig"
|
||||||
target_size = 1
|
instance_template = module.squid-vm.template.self_link
|
||||||
autoscaler_config = {
|
target_size = 1
|
||||||
max_replicas = 10
|
auto_healing_policies = {
|
||||||
min_replicas = 1
|
initial_delay_sec = 60
|
||||||
cooldown_period = 30
|
|
||||||
cpu_utilization_target = 0.65
|
|
||||||
load_balancing_utilization_target = null
|
|
||||||
metric = null
|
|
||||||
}
|
}
|
||||||
default_version = {
|
autoscaler_config = {
|
||||||
instance_template = module.squid-vm.template.self_link
|
max_replicas = 10
|
||||||
name = "default"
|
min_replicas = 1
|
||||||
|
cooldown_period = 30
|
||||||
|
scaling_signals = {
|
||||||
|
cpu_utilization = {
|
||||||
|
target = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
health_check_config = {
|
health_check_config = {
|
||||||
type = "tcp"
|
enable_logging = true
|
||||||
check = { port = 3128 }
|
tcp = {
|
||||||
config = {}
|
port = 3128
|
||||||
logging = true
|
}
|
||||||
}
|
|
||||||
auto_healing_policies = {
|
|
||||||
health_check = module.squid-mig.0.health_check.self_link
|
|
||||||
initial_delay_sec = 60
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,22 +153,20 @@ module "vm_siege" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "mig_ew1" {
|
module "mig_ew1" {
|
||||||
source = "../../../modules/compute-mig"
|
source = "../../../modules/compute-mig"
|
||||||
project_id = module.project.project_id
|
project_id = module.project.project_id
|
||||||
location = "europe-west1"
|
location = "europe-west1"
|
||||||
name = "${local.prefix}europe-west1-mig"
|
name = "${local.prefix}europe-west1-mig"
|
||||||
regional = true
|
instance_template = module.instance_template_ew1.template.self_link
|
||||||
default_version = {
|
|
||||||
instance_template = module.instance_template_ew1.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
autoscaler_config = {
|
autoscaler_config = {
|
||||||
max_replicas = 5
|
max_replicas = 5
|
||||||
min_replicas = 1
|
min_replicas = 1
|
||||||
cooldown_period = 45
|
cooldown_period = 45
|
||||||
cpu_utilization_target = 0.8
|
scaling_signals = {
|
||||||
load_balancing_utilization_target = null
|
cpu_utilization = {
|
||||||
metric = null
|
target = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
named_ports = {
|
named_ports = {
|
||||||
http = 80
|
http = 80
|
||||||
|
@ -179,22 +177,20 @@ module "mig_ew1" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "mig_ue1" {
|
module "mig_ue1" {
|
||||||
source = "../../../modules/compute-mig"
|
source = "../../../modules/compute-mig"
|
||||||
project_id = module.project.project_id
|
project_id = module.project.project_id
|
||||||
location = "us-east1"
|
location = "us-east1"
|
||||||
name = "${local.prefix}us-east1-mig"
|
name = "${local.prefix}us-east1-mig"
|
||||||
regional = true
|
instance_template = module.instance_template_ue1.template.self_link
|
||||||
default_version = {
|
|
||||||
instance_template = module.instance_template_ue1.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
autoscaler_config = {
|
autoscaler_config = {
|
||||||
max_replicas = 5
|
max_replicas = 5
|
||||||
min_replicas = 1
|
min_replicas = 1
|
||||||
cooldown_period = 45
|
cooldown_period = 45
|
||||||
cpu_utilization_target = 0.8
|
scaling_signals = {
|
||||||
load_balancing_utilization_target = null
|
cpu_utilization = {
|
||||||
metric = null
|
target = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
named_ports = {
|
named_ports = {
|
||||||
http = 80
|
http = 80
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
# routing_config should be aligned to the NVA network interfaces - i.e.
|
# routing_config should be aligned to the NVA network interfaces - i.e.
|
||||||
# local.routing_config[0] sets up the first interface, and so on.
|
# local.routing_config[0] sets up the first interface, and so on.
|
||||||
routing_config = [
|
routing_config = [
|
||||||
{
|
{
|
||||||
|
@ -94,27 +94,21 @@ module "nva-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nva-mig" {
|
module "nva-mig" {
|
||||||
for_each = local.nva_locality
|
for_each = local.nva_locality
|
||||||
source = "../../../modules/compute-mig"
|
source = "../../../modules/compute-mig"
|
||||||
project_id = module.landing-project.project_id
|
project_id = module.landing-project.project_id
|
||||||
regional = true
|
location = each.value.region
|
||||||
location = each.value.region
|
name = "nva-cos-${each.value.trigram}-${each.value.zone}"
|
||||||
name = "nva-cos-${each.value.trigram}-${each.value.zone}"
|
instance_template = module.nva-template[each.key].template.self_link
|
||||||
target_size = 1
|
target_size = 1
|
||||||
# FIXME: cycle
|
auto_healing_policies = {
|
||||||
# auto_healing_policies = {
|
initial_delay_sec = 30
|
||||||
# health_check = module.nva-mig[each.key].health_check.self_link
|
|
||||||
# initial_delay_sec = 30
|
|
||||||
# }
|
|
||||||
health_check_config = {
|
|
||||||
type = "tcp"
|
|
||||||
check = { port = 22 }
|
|
||||||
config = {}
|
|
||||||
logging = true
|
|
||||||
}
|
}
|
||||||
default_version = {
|
health_check_config = {
|
||||||
instance_template = module.nva-template[each.key].template.self_link
|
enable_logging = true
|
||||||
name = "default"
|
tcp = {
|
||||||
|
port = 22
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
This module allows creating a managed instance group supporting one or more application versions via instance templates. Optionally, a health check and an autoscaler can be created, and the managed instance group can be configured to be stateful.
|
This module allows creating a managed instance group supporting one or more application versions via instance templates. Optionally, a health check and an autoscaler can be created, and the managed instance group can be configured to be stateful.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Stateful disks can be created directly, as shown in the last example below.
|
Stateful disks can be created directly, as shown in the last example below.
|
||||||
|
|
||||||
|
@ -39,15 +39,12 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 2
|
target_size = 2
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=2
|
# tftest modules=2 resources=2
|
||||||
```
|
```
|
||||||
|
@ -85,20 +82,18 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
versions = {
|
versions = {
|
||||||
canary = {
|
canary = {
|
||||||
instance_template = module.nginx-template.template.self_link
|
instance_template = module.nginx-template.template.self_link
|
||||||
target_type = "fixed"
|
target_size = {
|
||||||
target_size = 1
|
fixed = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,24 +133,20 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
auto_healing_policies = {
|
auto_healing_policies = {
|
||||||
health_check = module.nginx-mig.health_check.self_link
|
|
||||||
initial_delay_sec = 30
|
initial_delay_sec = 30
|
||||||
}
|
}
|
||||||
health_check_config = {
|
health_check_config = {
|
||||||
type = "http"
|
enable_logging = true
|
||||||
check = { port = 80 }
|
http = {
|
||||||
config = {}
|
port = 80
|
||||||
logging = true
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=3
|
# tftest modules=2 resources=3
|
||||||
|
@ -194,22 +185,21 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
autoscaler_config = {
|
autoscaler_config = {
|
||||||
max_replicas = 3
|
max_replicas = 3
|
||||||
min_replicas = 1
|
min_replicas = 1
|
||||||
cooldown_period = 30
|
cooldown_period = 30
|
||||||
cpu_utilization_target = 0.65
|
scaling_signals = {
|
||||||
load_balancing_utilization_target = null
|
cpu_utilization = {
|
||||||
metric = null
|
target = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=3
|
# tftest modules=2 resources=3
|
||||||
|
@ -246,23 +236,19 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
update_policy = {
|
update_policy = {
|
||||||
type = "PROACTIVE"
|
|
||||||
minimal_action = "REPLACE"
|
minimal_action = "REPLACE"
|
||||||
|
type = "PROACTIVE"
|
||||||
min_ready_sec = 30
|
min_ready_sec = 30
|
||||||
max_surge_type = "fixed"
|
max_surge = {
|
||||||
max_surge = 1
|
fixed = 1
|
||||||
max_unavailable_type = null
|
}
|
||||||
max_unavailable = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=2
|
# tftest modules=2 resources=2
|
||||||
|
@ -270,7 +256,7 @@ module "nginx-mig" {
|
||||||
|
|
||||||
### Stateful MIGs - MIG Config
|
### Stateful MIGs - MIG Config
|
||||||
|
|
||||||
Stateful MIGs have some limitations documented [here](https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-migs#limitations). Enforcement of these requirements is the responsibility of users of this module.
|
Stateful MIGs have some limitations documented [here](https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-migs#limitations). Enforcement of these requirements is the responsibility of users of this module.
|
||||||
|
|
||||||
You can configure a disk defined in the instance template to be stateful for all instances in the MIG by configuring in the MIG's stateful policy, using the `stateful_disk_mig` variable. Alternatively, you can also configure stateful persistent disks individually per instance of the MIG by setting the `stateful_disk_instance` variable. A discussion on these scenarios can be found in the [docs](https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-disks-in-migs).
|
You can configure a disk defined in the instance template to be stateful for all instances in the MIG by configuring in the MIG's stateful policy, using the `stateful_disk_mig` variable. Alternatively, you can also configure stateful persistent disks individually per instance of the MIG by setting the `stateful_disk_instance` variable. A discussion on these scenarios can be found in the [docs](https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-disks-in-migs).
|
||||||
|
|
||||||
|
@ -278,7 +264,6 @@ An example using only the configuration at the MIG level can be seen below.
|
||||||
|
|
||||||
Note that when referencing the stateful disk, you use `device_name` and not `disk_name`.
|
Note that when referencing the stateful disk, you use `device_name` and not `disk_name`.
|
||||||
|
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
module "cos-nginx" {
|
module "cos-nginx" {
|
||||||
source = "./fabric/modules/cloud-config-container/nginx"
|
source = "./fabric/modules/cloud-config-container/nginx"
|
||||||
|
@ -319,40 +304,33 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
autoscaler_config = {
|
autoscaler_config = {
|
||||||
max_replicas = 3
|
max_replicas = 3
|
||||||
min_replicas = 1
|
min_replicas = 1
|
||||||
cooldown_period = 30
|
cooldown_period = 30
|
||||||
cpu_utilization_target = 0.65
|
scaling_signals = {
|
||||||
load_balancing_utilization_target = null
|
cpu_utilization = {
|
||||||
metric = null
|
target = 0.65
|
||||||
}
|
|
||||||
stateful_config = {
|
|
||||||
per_instance_config = {},
|
|
||||||
mig_config = {
|
|
||||||
stateful_disks = {
|
|
||||||
repd-1 = {
|
|
||||||
delete_rule = "NEVER"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stateful_disks = {
|
||||||
|
repd-1 = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=2 resources=3
|
# tftest modules=2 resources=3
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stateful MIGs - Instance Config
|
### Stateful MIGs - Instance Config
|
||||||
Here is an example defining the stateful config at the instance level.
|
|
||||||
|
Here is an example defining the stateful config at the instance level.
|
||||||
|
|
||||||
Note that you will need to know the instance name in order to use this configuration.
|
Note that you will need to know the instance name in order to use this configuration.
|
||||||
|
|
||||||
|
@ -396,46 +374,36 @@ module "nginx-template" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "nginx-mig" {
|
module "nginx-mig" {
|
||||||
source = "./fabric/modules/compute-mig"
|
source = "./fabric/modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1-b"
|
location = "europe-west1-b"
|
||||||
name = "mig-test"
|
name = "mig-test"
|
||||||
target_size = 3
|
target_size = 3
|
||||||
default_version = {
|
instance_template = module.nginx-template.template.self_link
|
||||||
instance_template = module.nginx-template.template.self_link
|
|
||||||
name = "default"
|
|
||||||
}
|
|
||||||
autoscaler_config = {
|
autoscaler_config = {
|
||||||
max_replicas = 3
|
max_replicas = 3
|
||||||
min_replicas = 1
|
min_replicas = 1
|
||||||
cooldown_period = 30
|
cooldown_period = 30
|
||||||
cpu_utilization_target = 0.65
|
scaling_signals = {
|
||||||
load_balancing_utilization_target = null
|
cpu_utilization = {
|
||||||
metric = null
|
target = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stateful_config = {
|
stateful_config = {
|
||||||
per_instance_config = {
|
# name needs to match a MIG instance name
|
||||||
# note that this needs to be the name of an existing instance within the Managed Instance Group
|
instance-1 = {
|
||||||
instance-1 = {
|
minimal_action = "NONE",
|
||||||
stateful_disks = {
|
most_disruptive_allowed_action = "REPLACE"
|
||||||
|
preserved_state = {
|
||||||
|
disks = {
|
||||||
persistent-disk-1 = {
|
persistent-disk-1 = {
|
||||||
source = "test-disk",
|
source = "test-disk",
|
||||||
mode = "READ_ONLY",
|
}
|
||||||
delete_rule= "NEVER",
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
metadata = {
|
metadata = {
|
||||||
foo = "bar"
|
foo = "bar"
|
||||||
},
|
}
|
||||||
update_config = {
|
|
||||||
minimal_action = "NONE",
|
|
||||||
most_disruptive_allowed_action = "REPLACE",
|
|
||||||
remove_instance_state_on_destroy = false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mig_config = {
|
|
||||||
stateful_disks = {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,21 +417,25 @@ module "nginx-mig" {
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [default_version](variables.tf#L45) | Default application version template. Additional versions can be specified via the `versions` variable. | <code title="object({ instance_template = string name = string })">object({…})</code> | ✓ | |
|
| [instance_template](variables.tf#L150) | Instance template for the default version. | <code>string</code> | ✓ | |
|
||||||
| [location](variables.tf#L64) | Compute zone, or region if `regional` is set to true. | <code>string</code> | ✓ | |
|
| [location](variables.tf#L155) | Compute zone or region. | <code>string</code> | ✓ | |
|
||||||
| [name](variables.tf#L68) | Managed group name. | <code>string</code> | ✓ | |
|
| [name](variables.tf#L160) | Managed group name. | <code>string</code> | ✓ | |
|
||||||
| [project_id](variables.tf#L79) | Project id. | <code>string</code> | ✓ | |
|
| [project_id](variables.tf#L171) | Project id. | <code>string</code> | ✓ | |
|
||||||
| [auto_healing_policies](variables.tf#L17) | Auto-healing policies for this group. | <code title="object({ health_check = string initial_delay_sec = number })">object({…})</code> | | <code>null</code> |
|
| [all_instances_config](variables.tf#L17) | Metadata and labels set to all instances in the group. | <code title="object({ labels = optional(map(string)) metadata = optional(map(string)) })">object({…})</code> | | <code>null</code> |
|
||||||
| [autoscaler_config](variables.tf#L26) | 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>null</code> |
|
| [auto_healing_policies](variables.tf#L26) | Auto-healing policies for this group. | <code title="object({ health_check = optional(string) initial_delay_sec = number })">object({…})</code> | | <code>null</code> |
|
||||||
| [health_check_config](variables.tf#L53) | Optional auto-created health 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>null</code> |
|
| [autoscaler_config](variables.tf#L35) | Optional autoscaler configuration. | <code title="object({ max_replicas = number min_replicas = number cooldown_period = optional(number) mode = optional(string) # OFF, ONLY_UP, ON scaling_control = optional(object({ down = optional(object({ max_replicas_fixed = optional(number) max_replicas_percent = optional(number) time_window_sec = optional(number) })) in = optional(object({ max_replicas_fixed = optional(number) max_replicas_percent = optional(number) time_window_sec = optional(number) })) }), {}) scaling_signals = optional(object({ cpu_utilization = optional(object({ target = number optimize_availability = optional(bool) })) load_balancing_utilization = optional(object({ target = number })) metrics = optional(list(object({ name = string type = string # GAUGE, DELTA_PER_SECOND, DELTA_PER_MINUTE target_value = number single_instance_assignment = optional(number) time_series_filter = optional(string) }))) schedules = optional(list(object({ duration_sec = number name = string min_required_replicas = number cron_schedule = string description = optional(bool) timezone = optional(string) disabled = optional(bool) }))) }), {}) })">object({…})</code> | | <code>null</code> |
|
||||||
| [named_ports](variables.tf#L73) | Named ports. | <code>map(number)</code> | | <code>null</code> |
|
| [default_version_name](variables.tf#L83) | Name used for the default version. | <code>string</code> | | <code>"default"</code> |
|
||||||
| [regional](variables.tf#L84) | Use regional instance group. When set, `location` should be set to the region. | <code>bool</code> | | <code>false</code> |
|
| [description](variables.tf#L89) | Optional description used for all resources managed by this module. | <code>string</code> | | <code>"Terraform managed."</code> |
|
||||||
| [stateful_config](variables.tf#L90) | Stateful configuration can be done by individual instances or for all instances in the MIG. They key in per_instance_config is the name of the specific instance. The key of the stateful_disks is the 'device_name' field of the resource. Please note that device_name is defined at the OS mount level, unlike the disk name. | <code title="object({ per_instance_config = map(object({ stateful_disks = map(object({ source = string mode = string # READ_WRITE | READ_ONLY delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION })) metadata = map(string) update_config = object({ minimal_action = string # NONE | REPLACE | RESTART | REFRESH most_disruptive_allowed_action = string # REPLACE | RESTART | REFRESH | NONE remove_instance_state_on_destroy = bool }) })) mig_config = object({ stateful_disks = map(object({ delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION })) }) })">object({…})</code> | | <code>null</code> |
|
| [distribution_policy](variables.tf#L95) | DIstribution policy for regional MIG. | <code title="object({ target_shape = optional(string) zones = optional(list(string)) })">object({…})</code> | | <code>null</code> |
|
||||||
| [target_pools](variables.tf#L121) | Optional list of URLs for target pools to which new instances in the group are added. | <code>list(string)</code> | | <code>[]</code> |
|
| [health_check_config](variables.tf#L104) | Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | <code title="object({ check_interval_sec = optional(number) description = optional(string, "Terraform managed.") enable_logging = optional(bool, false) healthy_threshold = optional(number) timeout_sec = optional(number) unhealthy_threshold = optional(number) grpc = optional(object({ port = optional(number) port_name = optional(string) port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT service_name = optional(string) })) http = optional(object({ host = optional(string) port = optional(number) port_name = optional(string) port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT proxy_header = optional(string) request_path = optional(string) response = optional(string) use_protocol = optional(string, "http") # http http2 https })) tcp = optional(object({ port = optional(number) port_name = optional(string) port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT proxy_header = optional(string) request = optional(string) response = optional(string) use_ssl = optional(bool, false) })) })">object({…})</code> | | <code>null</code> |
|
||||||
| [target_size](variables.tf#L127) | Group target size, leave null when using an autoscaler. | <code>number</code> | | <code>null</code> |
|
| [named_ports](variables.tf#L165) | Named ports. | <code>map(number)</code> | | <code>null</code> |
|
||||||
| [update_policy](variables.tf#L133) | Update policy. Type can be 'OPPORTUNISTIC' or 'PROACTIVE', action 'REPLACE' or 'restart', surge type 'fixed' or 'percent'. | <code title="object({ instance_redistribution_type = optional(string, "PROACTIVE") # NONE | PROACTIVE. The attribute is ignored if regional is set to false. max_surge_type = string # fixed | percent max_surge = number max_unavailable_type = string max_unavailable = number minimal_action = string # REPLACE | RESTART min_ready_sec = number type = string # OPPORTUNISTIC | PROACTIVE })">object({…})</code> | | <code>null</code> |
|
| [stateful_config](variables.tf#L183) | Stateful configuration for individual instances. | <code title="map(object({ minimal_action = optional(string) most_disruptive_action = optional(string) remove_state_on_destroy = optional(bool) preserved_state = optional(object({ disks = optional(map(object({ source = string delete_on_instance_deletion = optional(bool) read_only = optional(bool) }))) metadata = optional(map(string)) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [versions](variables.tf#L148) | 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>null</code> |
|
| [stateful_disks](variables.tf#L176) | Stateful disk configuration applied at the MIG level to all instances, in device name => on permanent instance delete rule as boolean. | <code>map(bool)</code> | | <code>{}</code> |
|
||||||
| [wait_for_instances](variables.tf#L158) | Wait for all instances to be created/updated before returning. | <code>bool</code> | | <code>null</code> |
|
| [target_pools](variables.tf#L202) | Optional list of URLs for target pools to which new instances in the group are added. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
|
| [target_size](variables.tf#L208) | Group target size, leave null when using an autoscaler. | <code>number</code> | | <code>null</code> |
|
||||||
|
| [update_policy](variables.tf#L214) | Update policy. Minimal action and type are required. | <code title="object({ minimal_action = string type = string max_surge = optional(object({ fixed = optional(number) percent = optional(number) })) max_unavailable = optional(object({ fixed = optional(number) percent = optional(number) })) min_ready_sec = optional(number) most_disruptive_action = optional(string) regional_redistribution_type = optional(string) replacement_method = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||||
|
| [versions](variables.tf#L235) | Additional application versions, target_size is optional. | <code title="map(object({ instance_template = string target_size = optional(object({ fixed = optional(number) percent = optional(number) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
|
| [wait_for_instances](variables.tf#L248) | Wait for all instances to be created/updated before returning. | <code title="object({ enabled = bool status = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,229 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# tfdoc:file:description Autoscaler resource.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
as_enabled = true
|
||||||
|
as_scaling = try(var.autoscaler_config.scaling_control, null)
|
||||||
|
as_signals = try(var.autoscaler_config.scaling_signals, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_autoscaler" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
count = local.is_regional || var.autoscaler_config == null ? 0 : 1
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
zone = var.location
|
||||||
|
description = var.description
|
||||||
|
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 "scale_down_control" {
|
||||||
|
for_each = local.as_scaling.down == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
time_window_sec = local.as_scaling.down.time_window_sec
|
||||||
|
dynamic "max_scaled_down_replicas" {
|
||||||
|
for_each = (
|
||||||
|
local.as_scaling.down.max_replicas_fixed == null &&
|
||||||
|
local.as_scaling.down.max_replicas_percent == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
fixed = local.as_scaling.down.max_replicas_fixed
|
||||||
|
percent = local.as_scaling.down.max_replicas_percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "scale_in_control" {
|
||||||
|
for_each = local.as_scaling.in == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
time_window_sec = local.as_scaling.in.time_window_sec
|
||||||
|
dynamic "max_scaled_in_replicas" {
|
||||||
|
for_each = (
|
||||||
|
local.as_scaling.in.max_replicas_fixed == null &&
|
||||||
|
local.as_scaling.in.max_replicas_percent == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
fixed = local.as_scaling.in.max_replicas_fixed
|
||||||
|
percent = local.as_scaling.in.max_replicas_percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "cpu_utilization" {
|
||||||
|
for_each = local.as_signals.cpu_utilization == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
target = local.as_signals.cpu_utilization.target
|
||||||
|
predictive_method = (
|
||||||
|
local.as_signals.cpu_utilization.optimize_availability == true
|
||||||
|
? "OPTIMIZE_AVAILABILITY"
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "load_balancing_utilization" {
|
||||||
|
for_each = local.as_signals.load_balancing_utilization == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
target = local.as_signals.load_balancing_utilization.target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "metric" {
|
||||||
|
for_each = toset(
|
||||||
|
local.as_signals.metrics == null ? [] : local.as_signals.metrics
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
name = metric.value.name
|
||||||
|
type = metric.value.type
|
||||||
|
target = metric.value.target_value
|
||||||
|
single_instance_assignment = metric.value.single_instance_assignment
|
||||||
|
filter = metric.value.time_series_filter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "scaling_schedules" {
|
||||||
|
for_each = toset(
|
||||||
|
local.as_signals.schedules == null ? [] : local.as_signals.schedules
|
||||||
|
)
|
||||||
|
iterator = schedule
|
||||||
|
content {
|
||||||
|
duration_sec = schedule.value.duration_sec
|
||||||
|
min_required_replicas = schedule.value.min_required_replicas
|
||||||
|
name = schedule.value.name
|
||||||
|
schedule = schedule.value.cron_schedule
|
||||||
|
description = schedule.value.description
|
||||||
|
disabled = schedule.value.disabled
|
||||||
|
time_zone = schedule.value.timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_region_autoscaler" "default" {
|
||||||
|
provider = google-beta
|
||||||
|
count = local.is_regional && var.autoscaler_config != null ? 1 : 0
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
region = var.location
|
||||||
|
description = var.description
|
||||||
|
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 "scale_down_control" {
|
||||||
|
for_each = local.as_scaling.down == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
time_window_sec = local.as_scaling.down.time_window_sec
|
||||||
|
dynamic "max_scaled_down_replicas" {
|
||||||
|
for_each = (
|
||||||
|
local.as_scaling.down.max_replicas_fixed == null &&
|
||||||
|
local.as_scaling.down.max_replicas_percent == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
fixed = local.as_scaling.down.max_replicas_fixed
|
||||||
|
percent = local.as_scaling.down.max_replicas_percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "scale_in_control" {
|
||||||
|
for_each = local.as_scaling.in == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
time_window_sec = local.as_scaling.in.time_window_sec
|
||||||
|
dynamic "max_scaled_in_replicas" {
|
||||||
|
for_each = (
|
||||||
|
local.as_scaling.in.max_replicas_fixed == null &&
|
||||||
|
local.as_scaling.in.max_replicas_percent == null
|
||||||
|
? []
|
||||||
|
: [""]
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
fixed = local.as_scaling.in.max_replicas_fixed
|
||||||
|
percent = local.as_scaling.in.max_replicas_percent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "cpu_utilization" {
|
||||||
|
for_each = local.as_signals.cpu_utilization == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
target = local.as_signals.cpu_utilization.target
|
||||||
|
predictive_method = (
|
||||||
|
local.as_signals.cpu_utilization.optimize_availability == true
|
||||||
|
? "OPTIMIZE_AVAILABILITY"
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "load_balancing_utilization" {
|
||||||
|
for_each = local.as_signals.load_balancing_utilization == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
target = local.as_signals.load_balancing_utilization.target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "metric" {
|
||||||
|
for_each = toset(
|
||||||
|
local.as_signals.metrics == null ? [] : local.as_signals.metrics
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
name = metric.value.name
|
||||||
|
type = metric.value.type
|
||||||
|
target = metric.value.target_value
|
||||||
|
single_instance_assignment = metric.value.single_instance_assignment
|
||||||
|
filter = metric.value.time_series_filter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "scaling_schedules" {
|
||||||
|
for_each = toset(
|
||||||
|
local.as_signals.schedules == null ? [] : local.as_signals.schedules
|
||||||
|
)
|
||||||
|
iterator = schedule
|
||||||
|
content {
|
||||||
|
duration_sec = schedule.value.duration_sec
|
||||||
|
min_required_replicas = schedule.value.min_required_replicas
|
||||||
|
name = schedule.value.name
|
||||||
|
schedule = schedule.cron_schedule
|
||||||
|
description = schedule.value.description
|
||||||
|
disabled = schedule.value.disabled
|
||||||
|
time_zone = schedule.value.timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# tfdoc:file:description Health check resource.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
hc = var.health_check_config
|
||||||
|
hc_grpc = try(local.hc.grpc, null) != null
|
||||||
|
hc_http = (
|
||||||
|
try(local.hc.http, null) != null &&
|
||||||
|
lower(try(local.hc.http.use_protocol, "")) == "http"
|
||||||
|
)
|
||||||
|
hc_http2 = (
|
||||||
|
try(local.hc.http, null) != null &&
|
||||||
|
lower(try(local.hc.http.use_protocol, "")) == "http2"
|
||||||
|
)
|
||||||
|
hc_https = (
|
||||||
|
try(local.hc.http, null) != null &&
|
||||||
|
lower(try(local.hc.http.use_protocol, "")) == "https"
|
||||||
|
)
|
||||||
|
hc_ssl = try(local.hc.tcp.use_ssl, null) == true
|
||||||
|
hc_tcp = try(local.hc.tcp, null) != null && !local.hc_ssl
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_health_check" "autohealing" {
|
||||||
|
provider = google-beta
|
||||||
|
count = local.hc != null ? 1 : 0
|
||||||
|
project = var.project_id
|
||||||
|
name = var.name
|
||||||
|
description = local.hc.description
|
||||||
|
check_interval_sec = local.hc.check_interval_sec
|
||||||
|
healthy_threshold = local.hc.healthy_threshold
|
||||||
|
timeout_sec = local.hc.timeout_sec
|
||||||
|
unhealthy_threshold = local.hc.unhealthy_threshold
|
||||||
|
|
||||||
|
dynamic "grpc_health_check" {
|
||||||
|
for_each = local.hc_grpc ? [""] : []
|
||||||
|
content {
|
||||||
|
port = local.hc.grpc.port
|
||||||
|
port_name = local.hc.grpc.port_name
|
||||||
|
port_specification = local.hc.grpc.port_specification
|
||||||
|
grpc_service_name = local.hc.grpc.service_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "http_health_check" {
|
||||||
|
for_each = local.hc_http ? [""] : []
|
||||||
|
content {
|
||||||
|
host = local.hc.http.host
|
||||||
|
port = local.hc.http.port
|
||||||
|
port_name = local.hc.http.port_name
|
||||||
|
port_specification = local.hc.http.port_specification
|
||||||
|
proxy_header = local.hc.http.proxy_header
|
||||||
|
request_path = local.hc.http.request_path
|
||||||
|
response = local.hc.http.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "http2_health_check" {
|
||||||
|
for_each = local.hc_http2 ? [""] : []
|
||||||
|
content {
|
||||||
|
host = local.hc.http.host
|
||||||
|
port = local.hc.http.port
|
||||||
|
port_name = local.hc.http.port_name
|
||||||
|
port_specification = local.hc.http.port_specification
|
||||||
|
proxy_header = local.hc.http.proxy_header
|
||||||
|
request_path = local.hc.http.request_path
|
||||||
|
response = local.hc.http.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "https_health_check" {
|
||||||
|
for_each = local.hc_https ? [""] : []
|
||||||
|
content {
|
||||||
|
host = local.hc.http.host
|
||||||
|
port = local.hc.http.port
|
||||||
|
port_name = local.hc.http.port_name
|
||||||
|
port_specification = local.hc.http.port_specification
|
||||||
|
proxy_header = local.hc.http.proxy_header
|
||||||
|
request_path = local.hc.http.request_path
|
||||||
|
response = local.hc.http.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "ssl_health_check" {
|
||||||
|
for_each = local.hc_ssl ? [""] : []
|
||||||
|
content {
|
||||||
|
port = local.hc.tcp.port
|
||||||
|
port_name = local.hc.tcp.port_name
|
||||||
|
port_specification = local.hc.tcp.port_specification
|
||||||
|
proxy_header = local.hc.tcp.proxy_header
|
||||||
|
request = local.hc.tcp.request
|
||||||
|
response = local.hc.tcp.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "tcp_health_check" {
|
||||||
|
for_each = local.hc_tcp ? [""] : []
|
||||||
|
content {
|
||||||
|
port = local.hc.tcp.port
|
||||||
|
port_name = local.hc.tcp.port_name
|
||||||
|
port_specification = local.hc.tcp.port_specification
|
||||||
|
proxy_header = local.hc.tcp.proxy_header
|
||||||
|
request = local.hc.tcp.request
|
||||||
|
response = local.hc.tcp.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "log_config" {
|
||||||
|
for_each = try(local.hc.enable_logging, null) == true ? [""] : []
|
||||||
|
content {
|
||||||
|
enable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,105 +14,50 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
resource "google_compute_autoscaler" "default" {
|
locals {
|
||||||
provider = google-beta
|
health_check = (
|
||||||
count = var.regional || var.autoscaler_config == null ? 0 : 1
|
try(var.auto_healing_policies.health_check, null) == null
|
||||||
project = var.project_id
|
? try(google_compute_health_check.autohealing.0.self_link, null)
|
||||||
name = var.name
|
: try(var.auto_healing_policies.health_check, null)
|
||||||
description = "Terraform managed."
|
)
|
||||||
zone = var.location
|
instance_group_manager = (
|
||||||
target = google_compute_instance_group_manager.default.0.id
|
local.is_regional ?
|
||||||
|
google_compute_region_instance_group_manager.default :
|
||||||
autoscaling_policy {
|
google_compute_instance_group_manager.default
|
||||||
max_replicas = var.autoscaler_config.max_replicas
|
)
|
||||||
min_replicas = var.autoscaler_config.min_replicas
|
is_regional = length(split("-", var.location)) == 2
|
||||||
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" {
|
resource "google_compute_instance_group_manager" "default" {
|
||||||
provider = google-beta
|
provider = google-beta
|
||||||
count = var.regional ? 0 : 1
|
count = local.is_regional ? 0 : 1
|
||||||
project = var.project_id
|
project = var.project_id
|
||||||
zone = var.location
|
zone = var.location
|
||||||
name = var.name
|
name = var.name
|
||||||
base_instance_name = var.name
|
base_instance_name = var.name
|
||||||
description = "Terraform-managed."
|
description = var.description
|
||||||
target_size = var.target_size
|
target_size = var.target_size
|
||||||
target_pools = var.target_pools
|
target_pools = var.target_pools
|
||||||
wait_for_instances = var.wait_for_instances
|
wait_for_instances = try(var.wait_for_instances.enabled, null)
|
||||||
|
wait_for_instances_status = try(var.wait_for_instances.status, null)
|
||||||
|
|
||||||
|
dynamic "all_instances_config" {
|
||||||
|
for_each = var.all_instances_config == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
labels = try(var.all_instances_config.labels, null)
|
||||||
|
metadata = try(var.all_instances_config.metadata, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dynamic "auto_healing_policies" {
|
dynamic "auto_healing_policies" {
|
||||||
for_each = var.auto_healing_policies == null ? [] : [var.auto_healing_policies]
|
for_each = var.auto_healing_policies == null ? [] : [""]
|
||||||
iterator = config
|
iterator = config
|
||||||
content {
|
content {
|
||||||
health_check = config.value.health_check
|
health_check = local.health_check
|
||||||
initial_delay_sec = config.value.initial_delay_sec
|
initial_delay_sec = var.auto_healing_policies.initial_delay_sec
|
||||||
}
|
|
||||||
}
|
|
||||||
dynamic "stateful_disk" {
|
|
||||||
for_each = try(var.stateful_config.mig_config.stateful_disks, {})
|
|
||||||
iterator = config
|
|
||||||
content {
|
|
||||||
device_name = config.key
|
|
||||||
delete_rule = config.value.delete_rule
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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" {
|
dynamic "named_port" {
|
||||||
for_each = var.named_ports == null ? {} : var.named_ports
|
for_each = var.named_ports == null ? {} : var.named_ports
|
||||||
iterator = config
|
iterator = config
|
||||||
|
@ -121,167 +66,88 @@ resource "google_compute_instance_group_manager" "default" {
|
||||||
port = config.value
|
port = config.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
version {
|
|
||||||
instance_template = var.default_version.instance_template
|
dynamic "stateful_disk" {
|
||||||
name = var.default_version.name
|
for_each = var.stateful_disks
|
||||||
|
content {
|
||||||
|
device_name = stateful_disk.key
|
||||||
|
delete_rule = stateful_disk.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dynamic "update_policy" {
|
||||||
|
for_each = var.update_policy == null ? [] : [var.update_policy]
|
||||||
|
iterator = p
|
||||||
|
content {
|
||||||
|
minimal_action = p.value.minimal_action
|
||||||
|
type = p.value.type
|
||||||
|
max_surge_fixed = try(p.value.max_surge.fixed, null)
|
||||||
|
max_surge_percent = try(p.value.max_surge.percent, null)
|
||||||
|
max_unavailable_fixed = try(p.value.max_unavailable.fixed, null)
|
||||||
|
max_unavailable_percent = try(p.value.max_unavailable.percent, null)
|
||||||
|
min_ready_sec = p.value.min_ready_sec
|
||||||
|
most_disruptive_allowed_action = p.value.most_disruptive_action
|
||||||
|
replacement_method = p.value.replacement_method
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
version {
|
||||||
|
instance_template = var.instance_template
|
||||||
|
name = var.default_version_name
|
||||||
|
}
|
||||||
|
|
||||||
dynamic "version" {
|
dynamic "version" {
|
||||||
for_each = var.versions == null ? {} : var.versions
|
for_each = var.versions
|
||||||
iterator = version
|
|
||||||
content {
|
content {
|
||||||
name = version.key
|
name = version.key
|
||||||
instance_template = version.value.instance_template
|
instance_template = version.value.instance_template
|
||||||
target_size {
|
dynamic "target_size" {
|
||||||
fixed = (
|
for_each = version.value.target_size == null ? [] : [""]
|
||||||
version.value.target_type == "fixed" ? version.value.target_size : null
|
content {
|
||||||
)
|
fixed = version.value.target_size.fixed
|
||||||
percent = (
|
percent = version.value.target_size.percent
|
||||||
version.value.target_type == "percent" ? version.value.target_size : null
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
|
||||||
instance_group_manager = (
|
|
||||||
var.regional ?
|
|
||||||
google_compute_region_instance_group_manager.default :
|
|
||||||
google_compute_instance_group_manager.default
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_per_instance_config" "default" {
|
|
||||||
for_each = try(var.stateful_config.per_instance_config, {})
|
|
||||||
#for_each = var.stateful_config && var.stateful_config.per_instance_config == null ? {} : length(var.stateful_config.per_instance_config)
|
|
||||||
zone = var.location
|
|
||||||
# terraform error, solved with locals
|
|
||||||
#instance_group_manager = var.regional ? google_compute_region_instance_group_manager.default : google_compute_instance_group_manager.default
|
|
||||||
instance_group_manager = local.instance_group_manager[0].id
|
|
||||||
name = each.key
|
|
||||||
project = var.project_id
|
|
||||||
minimal_action = try(each.value.update_config.minimal_action, null)
|
|
||||||
most_disruptive_allowed_action = try(each.value.update_config.most_disruptive_allowed_action, null)
|
|
||||||
remove_instance_state_on_destroy = try(each.value.update_config.remove_instance_state_on_destroy, null)
|
|
||||||
preserved_state {
|
|
||||||
|
|
||||||
metadata = each.value.metadata
|
|
||||||
|
|
||||||
dynamic "disk" {
|
|
||||||
for_each = try(each.value.stateful_disks, {})
|
|
||||||
#for_each = var.stateful_config.mig_config.stateful_disks == null ? {} : var.stateful_config.mig_config.stateful_disks
|
|
||||||
iterator = config
|
|
||||||
content {
|
|
||||||
device_name = config.key
|
|
||||||
source = config.value.source
|
|
||||||
mode = config.value.mode
|
|
||||||
delete_rule = config.value.delete_rule
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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" {
|
resource "google_compute_region_instance_group_manager" "default" {
|
||||||
provider = google-beta
|
provider = google-beta
|
||||||
count = var.regional ? 1 : 0
|
count = local.is_regional ? 1 : 0
|
||||||
project = var.project_id
|
project = var.project_id
|
||||||
region = var.location
|
region = var.location
|
||||||
name = var.name
|
name = var.name
|
||||||
base_instance_name = var.name
|
base_instance_name = var.name
|
||||||
description = "Terraform-managed."
|
description = var.description
|
||||||
target_size = var.target_size
|
distribution_policy_target_shape = try(
|
||||||
target_pools = var.target_pools
|
var.distribution_policy.target_shape, null
|
||||||
wait_for_instances = var.wait_for_instances
|
)
|
||||||
dynamic "auto_healing_policies" {
|
distribution_policy_zones = try(
|
||||||
for_each = var.auto_healing_policies == null ? [] : [var.auto_healing_policies]
|
var.distribution_policy.zones, null
|
||||||
iterator = config
|
)
|
||||||
|
target_size = var.target_size
|
||||||
|
target_pools = var.target_pools
|
||||||
|
wait_for_instances = try(var.wait_for_instances.enabled, null)
|
||||||
|
wait_for_instances_status = try(var.wait_for_instances.status, null)
|
||||||
|
|
||||||
|
dynamic "all_instances_config" {
|
||||||
|
for_each = var.all_instances_config == null ? [] : [""]
|
||||||
content {
|
content {
|
||||||
health_check = config.value.health_check
|
labels = try(var.all_instances_config.labels, null)
|
||||||
initial_delay_sec = config.value.initial_delay_sec
|
metadata = try(var.all_instances_config.metadata, null)
|
||||||
}
|
|
||||||
}
|
|
||||||
dynamic "stateful_disk" {
|
|
||||||
for_each = try(var.stateful_config.mig_config.stateful_disks, {})
|
|
||||||
iterator = config
|
|
||||||
content {
|
|
||||||
device_name = config.key
|
|
||||||
delete_rule = config.value.delete_rule
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "update_policy" {
|
dynamic "auto_healing_policies" {
|
||||||
for_each = var.update_policy == null ? [] : [var.update_policy]
|
for_each = var.auto_healing_policies == null ? [] : [""]
|
||||||
iterator = config
|
iterator = config
|
||||||
content {
|
content {
|
||||||
instance_redistribution_type = config.value.instance_redistribution_type
|
health_check = local.health_check
|
||||||
type = config.value.type
|
initial_delay_sec = var.auto_healing_policies.initial_delay_sec
|
||||||
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" {
|
dynamic "named_port" {
|
||||||
for_each = var.named_ports == null ? {} : var.named_ports
|
for_each = var.named_ports == null ? {} : var.named_ports
|
||||||
iterator = config
|
iterator = config
|
||||||
|
@ -290,172 +156,49 @@ resource "google_compute_region_instance_group_manager" "default" {
|
||||||
port = config.value
|
port = config.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
version {
|
|
||||||
instance_template = var.default_version.instance_template
|
dynamic "stateful_disk" {
|
||||||
name = var.default_version.name
|
for_each = var.stateful_disks
|
||||||
|
content {
|
||||||
|
device_name = stateful_disk.key
|
||||||
|
delete_rule = stateful_disk.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dynamic "update_policy" {
|
||||||
|
for_each = var.update_policy == null ? [] : [var.update_policy]
|
||||||
|
iterator = p
|
||||||
|
content {
|
||||||
|
minimal_action = p.value.minimal_action
|
||||||
|
type = p.value.type
|
||||||
|
instance_redistribution_type = p.value.regional_redistribution_type
|
||||||
|
max_surge_fixed = try(p.value.max_surge.fixed, null)
|
||||||
|
max_surge_percent = try(p.value.max_surge.percent, null)
|
||||||
|
max_unavailable_fixed = try(p.value.max_unavailable.fixed, null)
|
||||||
|
max_unavailable_percent = try(p.value.max_unavailable.percent, null)
|
||||||
|
min_ready_sec = p.value.min_ready_sec
|
||||||
|
most_disruptive_allowed_action = p.value.most_disruptive_action
|
||||||
|
replacement_method = p.value.replacement_method
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
version {
|
||||||
|
instance_template = var.instance_template
|
||||||
|
name = var.default_version_name
|
||||||
|
}
|
||||||
|
|
||||||
dynamic "version" {
|
dynamic "version" {
|
||||||
for_each = var.versions == null ? {} : var.versions
|
for_each = var.versions
|
||||||
iterator = version
|
|
||||||
content {
|
content {
|
||||||
name = version.key
|
name = version.key
|
||||||
instance_template = version.value.instance_template
|
instance_template = version.value.instance_template
|
||||||
target_size {
|
dynamic "target_size" {
|
||||||
fixed = (
|
for_each = version.value.target_size == null ? [] : [""]
|
||||||
version.value.target_type == "fixed" ? version.value.target_size : null
|
content {
|
||||||
)
|
fixed = version.value.target_size.fixed
|
||||||
percent = (
|
percent = version.value.target_size.percent
|
||||||
version.value.target_type == "percent" ? version.value.target_size : null
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_compute_health_check" "http" {
|
|
||||||
provider = google-beta
|
|
||||||
count = try(var.health_check_config.type, null) == "http" ? 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)
|
|
||||||
|
|
||||||
http_health_check {
|
|
||||||
host = try(var.health_check_config.check.host, null)
|
|
||||||
port = try(var.health_check_config.check.port, null)
|
|
||||||
port_name = try(var.health_check_config.check.port_name, null)
|
|
||||||
port_specification = try(var.health_check_config.check.port_specification, null)
|
|
||||||
proxy_header = try(var.health_check_config.check.proxy_header, null)
|
|
||||||
request_path = try(var.health_check_config.check.request_path, null)
|
|
||||||
response = try(var.health_check_config.check.response, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic "log_config" {
|
|
||||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
|
||||||
content {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_health_check" "https" {
|
|
||||||
provider = google-beta
|
|
||||||
count = try(var.health_check_config.type, null) == "https" ? 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)
|
|
||||||
|
|
||||||
https_health_check {
|
|
||||||
host = try(var.health_check_config.check.host, null)
|
|
||||||
port = try(var.health_check_config.check.port, null)
|
|
||||||
port_name = try(var.health_check_config.check.port_name, null)
|
|
||||||
port_specification = try(var.health_check_config.check.port_specification, null)
|
|
||||||
proxy_header = try(var.health_check_config.check.proxy_header, null)
|
|
||||||
request_path = try(var.health_check_config.check.request_path, null)
|
|
||||||
response = try(var.health_check_config.check.response, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic "log_config" {
|
|
||||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
|
||||||
content {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_health_check" "tcp" {
|
|
||||||
provider = google-beta
|
|
||||||
count = try(var.health_check_config.type, null) == "tcp" ? 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)
|
|
||||||
|
|
||||||
tcp_health_check {
|
|
||||||
port = try(var.health_check_config.check.port, null)
|
|
||||||
port_name = try(var.health_check_config.check.port_name, null)
|
|
||||||
port_specification = try(var.health_check_config.check.port_specification, null)
|
|
||||||
proxy_header = try(var.health_check_config.check.proxy_header, null)
|
|
||||||
request = try(var.health_check_config.check.request, null)
|
|
||||||
response = try(var.health_check_config.check.response, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic "log_config" {
|
|
||||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
|
||||||
content {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_health_check" "ssl" {
|
|
||||||
provider = google-beta
|
|
||||||
count = try(var.health_check_config.type, null) == "ssl" ? 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)
|
|
||||||
|
|
||||||
ssl_health_check {
|
|
||||||
port = try(var.health_check_config.check.port, null)
|
|
||||||
port_name = try(var.health_check_config.check.port_name, null)
|
|
||||||
port_specification = try(var.health_check_config.check.port_specification, null)
|
|
||||||
proxy_header = try(var.health_check_config.check.proxy_header, null)
|
|
||||||
request = try(var.health_check_config.check.request, null)
|
|
||||||
response = try(var.health_check_config.check.response, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic "log_config" {
|
|
||||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
|
||||||
content {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "google_compute_health_check" "http2" {
|
|
||||||
provider = google-beta
|
|
||||||
count = try(var.health_check_config.type, null) == "http2" ? 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)
|
|
||||||
|
|
||||||
http2_health_check {
|
|
||||||
host = try(var.health_check_config.check.host, null)
|
|
||||||
port = try(var.health_check_config.check.port, null)
|
|
||||||
port_name = try(var.health_check_config.check.port_name, null)
|
|
||||||
port_specification = try(var.health_check_config.check.port_specification, null)
|
|
||||||
proxy_header = try(var.health_check_config.check.proxy_header, null)
|
|
||||||
request_path = try(var.health_check_config.check.request_path, null)
|
|
||||||
response = try(var.health_check_config.check.response, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic "log_config" {
|
|
||||||
for_each = try(var.health_check_config.logging, false) ? [""] : []
|
|
||||||
content {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,13 +37,6 @@ output "health_check" {
|
||||||
value = (
|
value = (
|
||||||
var.health_check_config == null
|
var.health_check_config == null
|
||||||
? null
|
? null
|
||||||
: try(
|
: google_compute_health_check.autohealing.0
|
||||||
google_compute_health_check.http.0,
|
|
||||||
google_compute_health_check.https.0,
|
|
||||||
google_compute_health_check.tcp.0,
|
|
||||||
google_compute_health_check.ssl.0,
|
|
||||||
google_compute_health_check.http2.0,
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# tfdoc:file:description Instance-level stateful configuration resources.
|
||||||
|
|
||||||
|
resource "google_compute_per_instance_config" "default" {
|
||||||
|
for_each = local.is_regional ? {} : var.stateful_config
|
||||||
|
project = var.project_id
|
||||||
|
zone = var.location
|
||||||
|
name = each.key
|
||||||
|
instance_group_manager = try(
|
||||||
|
google_compute_instance_group_manager.default.0.id, null
|
||||||
|
)
|
||||||
|
minimal_action = each.value.minimal_action
|
||||||
|
most_disruptive_allowed_action = each.value.most_disruptive_action
|
||||||
|
remove_instance_state_on_destroy = each.value.remove_state_on_destroy
|
||||||
|
|
||||||
|
dynamic "preserved_state" {
|
||||||
|
for_each = each.value.preserved_state == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
metadata = each.value.preserved_state.metadata
|
||||||
|
dynamic "disk" {
|
||||||
|
for_each = (
|
||||||
|
each.value.preserved_state.disks == null
|
||||||
|
? {}
|
||||||
|
: each.value.preserved_state.disks
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
device_name = disk.key
|
||||||
|
source = disk.value.source
|
||||||
|
delete_rule = (
|
||||||
|
disk.value.delete_on_instance_deletion == true
|
||||||
|
? "ON_PERMANENT_INSTANCE_DELETION"
|
||||||
|
: "NEVER"
|
||||||
|
)
|
||||||
|
mode = disk.value.read_only == true ? "READ_ONLY" : "READ_WRITE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_region_per_instance_config" "default" {
|
||||||
|
for_each = local.is_regional ? var.stateful_config : {}
|
||||||
|
project = var.project_id
|
||||||
|
region = var.location
|
||||||
|
name = each.key
|
||||||
|
region_instance_group_manager = try(
|
||||||
|
google_compute_region_instance_group_manager.default.0.id, null
|
||||||
|
)
|
||||||
|
minimal_action = each.value.minimal_action
|
||||||
|
most_disruptive_allowed_action = each.value.most_disruptive_action
|
||||||
|
remove_instance_state_on_destroy = each.value.remove_state_on_destroy
|
||||||
|
|
||||||
|
dynamic "preserved_state" {
|
||||||
|
for_each = each.value.preserved_state == null ? [] : [""]
|
||||||
|
content {
|
||||||
|
metadata = each.value.preserved_state.metadata
|
||||||
|
dynamic "disk" {
|
||||||
|
for_each = (
|
||||||
|
each.value.preserved_state.disks == null
|
||||||
|
? {}
|
||||||
|
: each.value.preserved_state.disks
|
||||||
|
)
|
||||||
|
content {
|
||||||
|
device_name = disk.key
|
||||||
|
source = disk.value.source
|
||||||
|
delete_rule = (
|
||||||
|
disk.value.delete_on_instance_deletion == true
|
||||||
|
? "ON_PERMANENT_INSTANCE_DELETION"
|
||||||
|
: "NEVER"
|
||||||
|
)
|
||||||
|
mode = disk.value.read_only == true ? "READ_ONLY" : "READ_WRITE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,57 +14,149 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
variable "all_instances_config" {
|
||||||
|
description = "Metadata and labels set to all instances in the group."
|
||||||
|
type = object({
|
||||||
|
labels = optional(map(string))
|
||||||
|
metadata = optional(map(string))
|
||||||
|
})
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
variable "auto_healing_policies" {
|
variable "auto_healing_policies" {
|
||||||
description = "Auto-healing policies for this group."
|
description = "Auto-healing policies for this group."
|
||||||
type = object({
|
type = object({
|
||||||
health_check = string
|
health_check = optional(string)
|
||||||
initial_delay_sec = number
|
initial_delay_sec = number
|
||||||
})
|
})
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "autoscaler_config" {
|
variable "autoscaler_config" {
|
||||||
description = "Optional autoscaler configuration. Only one of 'cpu_utilization_target' 'load_balancing_utilization_target' or 'metric' can be not null."
|
description = "Optional autoscaler configuration."
|
||||||
type = object({
|
type = object({
|
||||||
max_replicas = number
|
max_replicas = number
|
||||||
min_replicas = number
|
min_replicas = number
|
||||||
cooldown_period = number
|
cooldown_period = optional(number)
|
||||||
cpu_utilization_target = number
|
mode = optional(string) # OFF, ONLY_UP, ON
|
||||||
load_balancing_utilization_target = number
|
scaling_control = optional(object({
|
||||||
metric = object({
|
down = optional(object({
|
||||||
name = string
|
max_replicas_fixed = optional(number)
|
||||||
single_instance_assignment = number
|
max_replicas_percent = optional(number)
|
||||||
target = number
|
time_window_sec = optional(number)
|
||||||
type = string # GAUGE, DELTA_PER_SECOND, DELTA_PER_MINUTE
|
}))
|
||||||
filter = string
|
in = optional(object({
|
||||||
})
|
max_replicas_fixed = optional(number)
|
||||||
|
max_replicas_percent = optional(number)
|
||||||
|
time_window_sec = optional(number)
|
||||||
|
}))
|
||||||
|
}), {})
|
||||||
|
scaling_signals = optional(object({
|
||||||
|
cpu_utilization = optional(object({
|
||||||
|
target = number
|
||||||
|
optimize_availability = optional(bool)
|
||||||
|
}))
|
||||||
|
load_balancing_utilization = optional(object({
|
||||||
|
target = number
|
||||||
|
}))
|
||||||
|
metrics = optional(list(object({
|
||||||
|
name = string
|
||||||
|
type = string # GAUGE, DELTA_PER_SECOND, DELTA_PER_MINUTE
|
||||||
|
target_value = number
|
||||||
|
single_instance_assignment = optional(number)
|
||||||
|
time_series_filter = optional(string)
|
||||||
|
})))
|
||||||
|
schedules = optional(list(object({
|
||||||
|
duration_sec = number
|
||||||
|
name = string
|
||||||
|
min_required_replicas = number
|
||||||
|
cron_schedule = string
|
||||||
|
description = optional(bool)
|
||||||
|
timezone = optional(string)
|
||||||
|
disabled = optional(bool)
|
||||||
|
})))
|
||||||
|
}), {})
|
||||||
})
|
})
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "default_version" {
|
variable "default_version_name" {
|
||||||
description = "Default application version template. Additional versions can be specified via the `versions` variable."
|
description = "Name used for the default version."
|
||||||
|
type = string
|
||||||
|
default = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "description" {
|
||||||
|
description = "Optional description used for all resources managed by this module."
|
||||||
|
type = string
|
||||||
|
default = "Terraform managed."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "distribution_policy" {
|
||||||
|
description = "DIstribution policy for regional MIG."
|
||||||
type = object({
|
type = object({
|
||||||
instance_template = string
|
target_shape = optional(string)
|
||||||
name = string
|
zones = optional(list(string))
|
||||||
})
|
})
|
||||||
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "health_check_config" {
|
variable "health_check_config" {
|
||||||
description = "Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage."
|
description = "Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage."
|
||||||
type = object({
|
type = object({
|
||||||
type = string # http https tcp ssl http2
|
check_interval_sec = optional(number)
|
||||||
check = map(any) # actual health check block attributes
|
description = optional(string, "Terraform managed.")
|
||||||
config = map(number) # interval, thresholds, timeout
|
enable_logging = optional(bool, false)
|
||||||
logging = bool
|
healthy_threshold = optional(number)
|
||||||
|
timeout_sec = optional(number)
|
||||||
|
unhealthy_threshold = optional(number)
|
||||||
|
grpc = optional(object({
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
service_name = optional(string)
|
||||||
|
}))
|
||||||
|
http = optional(object({
|
||||||
|
host = optional(string)
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request_path = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
use_protocol = optional(string, "http") # http http2 https
|
||||||
|
}))
|
||||||
|
tcp = optional(object({
|
||||||
|
port = optional(number)
|
||||||
|
port_name = optional(string)
|
||||||
|
port_specification = optional(string) # USE_FIXED_PORT USE_NAMED_PORT USE_SERVING_PORT
|
||||||
|
proxy_header = optional(string)
|
||||||
|
request = optional(string)
|
||||||
|
response = optional(string)
|
||||||
|
use_ssl = optional(bool, false)
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
default = null
|
default = null
|
||||||
|
validation {
|
||||||
|
condition = (
|
||||||
|
(try(var.health_check_config.grpc, null) == null ? 0 : 1) +
|
||||||
|
(try(var.health_check_config.http, null) == null ? 0 : 1) +
|
||||||
|
(try(var.health_check_config.tcp, null) == null ? 0 : 1) <= 1
|
||||||
|
)
|
||||||
|
error_message = "Only one health check type can be configured at a time."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "instance_template" {
|
||||||
|
description = "Instance template for the default version."
|
||||||
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "location" {
|
variable "location" {
|
||||||
description = "Compute zone, or region if `regional` is set to true."
|
description = "Compute zone or region."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "name" {
|
variable "name" {
|
||||||
description = "Managed group name."
|
description = "Managed group name."
|
||||||
type = string
|
type = string
|
||||||
|
@ -81,41 +173,30 @@ variable "project_id" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "regional" {
|
variable "stateful_disks" {
|
||||||
description = "Use regional instance group. When set, `location` should be set to the region."
|
description = "Stateful disk configuration applied at the MIG level to all instances, in device name => on permanent instance delete rule as boolean."
|
||||||
type = bool
|
type = map(bool)
|
||||||
default = false
|
default = {}
|
||||||
|
nullable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "stateful_config" {
|
variable "stateful_config" {
|
||||||
description = "Stateful configuration can be done by individual instances or for all instances in the MIG. They key in per_instance_config is the name of the specific instance. The key of the stateful_disks is the 'device_name' field of the resource. Please note that device_name is defined at the OS mount level, unlike the disk name."
|
description = "Stateful configuration for individual instances."
|
||||||
type = object({
|
type = map(object({
|
||||||
per_instance_config = map(object({
|
minimal_action = optional(string)
|
||||||
#name is the key
|
most_disruptive_action = optional(string)
|
||||||
#name = string
|
remove_state_on_destroy = optional(bool)
|
||||||
stateful_disks = map(object({
|
preserved_state = optional(object({
|
||||||
#device_name is the key
|
disks = optional(map(object({
|
||||||
source = string
|
source = string
|
||||||
mode = string # READ_WRITE | READ_ONLY
|
delete_on_instance_deletion = optional(bool)
|
||||||
delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION
|
read_only = optional(bool)
|
||||||
}))
|
})))
|
||||||
metadata = map(string)
|
metadata = optional(map(string))
|
||||||
update_config = object({
|
|
||||||
minimal_action = string # NONE | REPLACE | RESTART | REFRESH
|
|
||||||
most_disruptive_allowed_action = string # REPLACE | RESTART | REFRESH | NONE
|
|
||||||
remove_instance_state_on_destroy = bool
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
|
}))
|
||||||
mig_config = object({
|
default = {}
|
||||||
stateful_disks = map(object({
|
nullable = false
|
||||||
#device_name is the key
|
|
||||||
delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
default = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "target_pools" {
|
variable "target_pools" {
|
||||||
|
@ -131,32 +212,44 @@ variable "target_size" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "update_policy" {
|
variable "update_policy" {
|
||||||
description = "Update policy. Type can be 'OPPORTUNISTIC' or 'PROACTIVE', action 'REPLACE' or 'restart', surge type 'fixed' or 'percent'."
|
description = "Update policy. Minimal action and type are required."
|
||||||
type = object({
|
type = object({
|
||||||
instance_redistribution_type = optional(string, "PROACTIVE") # NONE | PROACTIVE. The attribute is ignored if regional is set to false.
|
minimal_action = string
|
||||||
max_surge_type = string # fixed | percent
|
type = string
|
||||||
max_surge = number
|
max_surge = optional(object({
|
||||||
max_unavailable_type = string
|
fixed = optional(number)
|
||||||
max_unavailable = number
|
percent = optional(number)
|
||||||
minimal_action = string # REPLACE | RESTART
|
}))
|
||||||
min_ready_sec = number
|
max_unavailable = optional(object({
|
||||||
type = string # OPPORTUNISTIC | PROACTIVE
|
fixed = optional(number)
|
||||||
|
percent = optional(number)
|
||||||
|
}))
|
||||||
|
min_ready_sec = optional(number)
|
||||||
|
most_disruptive_action = optional(string)
|
||||||
|
regional_redistribution_type = optional(string)
|
||||||
|
replacement_method = optional(string)
|
||||||
})
|
})
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "versions" {
|
variable "versions" {
|
||||||
description = "Additional application versions, target_type is either 'fixed' or 'percent'."
|
description = "Additional application versions, target_size is optional."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
instance_template = string
|
instance_template = string
|
||||||
target_type = string # fixed | percent
|
target_size = optional(object({
|
||||||
target_size = number
|
fixed = optional(number)
|
||||||
|
percent = optional(number)
|
||||||
|
}))
|
||||||
}))
|
}))
|
||||||
default = null
|
default = {}
|
||||||
|
nullable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "wait_for_instances" {
|
variable "wait_for_instances" {
|
||||||
description = "Wait for all instances to be created/updated before returning."
|
description = "Wait for all instances to be created/updated before returning."
|
||||||
type = bool
|
type = object({
|
||||||
default = null
|
enabled = bool
|
||||||
|
status = optional(string)
|
||||||
|
})
|
||||||
|
default = null
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,18 @@ resource "google_compute_disk" "default" {
|
||||||
}
|
}
|
||||||
|
|
||||||
module "test" {
|
module "test" {
|
||||||
source = "../../../../modules/compute-mig"
|
source = "../../../../modules/compute-mig"
|
||||||
project_id = "my-project"
|
project_id = "my-project"
|
||||||
location = "europe-west1"
|
name = "test-mig"
|
||||||
name = "test-mig"
|
target_size = 2
|
||||||
target_size = 2
|
default_version_name = "foo"
|
||||||
default_version = {
|
instance_template = "foo-template"
|
||||||
instance_template = "foo-template"
|
location = var.location
|
||||||
name = "foo"
|
autoscaler_config = var.autoscaler_config
|
||||||
}
|
health_check_config = var.health_check_config
|
||||||
autoscaler_config = var.autoscaler_config
|
named_ports = var.named_ports
|
||||||
health_check_config = var.health_check_config
|
stateful_config = var.stateful_config
|
||||||
named_ports = var.named_ports
|
stateful_disks = var.stateful_disks
|
||||||
regional = var.regional
|
update_policy = var.update_policy
|
||||||
stateful_config = var.stateful_config
|
versions = var.versions
|
||||||
|
|
||||||
update_policy = var.update_policy
|
|
||||||
versions = var.versions
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,101 +14,82 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
variable "autoscaler_config" {
|
variable "all_instances_config" {
|
||||||
type = object({
|
type = any
|
||||||
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
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "auto_healing_policies" {
|
variable "auto_healing_policies" {
|
||||||
type = object({
|
type = any
|
||||||
health_check = string
|
default = null
|
||||||
initial_delay_sec = number
|
}
|
||||||
})
|
|
||||||
|
variable "autoscaler_config" {
|
||||||
|
type = any
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "default_version_name" {
|
||||||
|
type = any
|
||||||
|
default = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "description" {
|
||||||
|
type = any
|
||||||
|
default = "Terraform managed."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "distribution_policy" {
|
||||||
|
type = any
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "health_check_config" {
|
variable "health_check_config" {
|
||||||
type = object({
|
type = any
|
||||||
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
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "location" {
|
||||||
|
type = any
|
||||||
|
default = "europe-west1-b"
|
||||||
|
}
|
||||||
|
|
||||||
variable "named_ports" {
|
variable "named_ports" {
|
||||||
type = map(number)
|
type = any
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "regional" {
|
variable "stateful_disks" {
|
||||||
type = bool
|
type = any
|
||||||
default = false
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "stateful_config" {
|
variable "stateful_config" {
|
||||||
description = "Stateful configuration can be done by individual instances or for all instances in the MIG. They key in per_instance_config is the name of the specific instance. The key of the stateful_disks is the 'device_name' field of the resource. Please note that device_name is defined at the OS mount level, unlike the disk name."
|
type = any
|
||||||
type = object({
|
default = {}
|
||||||
per_instance_config = map(object({
|
}
|
||||||
#name is the key
|
|
||||||
#name = string
|
|
||||||
stateful_disks = map(object({
|
|
||||||
#device_name is the key
|
|
||||||
source = string
|
|
||||||
mode = string # READ_WRITE | READ_ONLY
|
|
||||||
delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION
|
|
||||||
}))
|
|
||||||
metadata = map(string)
|
|
||||||
update_config = object({
|
|
||||||
minimal_action = string # NONE | REPLACE | RESTART | REFRESH
|
|
||||||
most_disruptive_allowed_action = string # REPLACE | RESTART | REFRESH | NONE
|
|
||||||
remove_instance_state_on_destroy = bool
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
mig_config = object({
|
variable "target_pools" {
|
||||||
stateful_disks = map(object({
|
type = any
|
||||||
#device_name is the key
|
default = []
|
||||||
delete_rule = string # NEVER | ON_PERMANENT_INSTANCE_DELETION
|
}
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
variable "target_size" {
|
||||||
|
type = any
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "update_policy" {
|
variable "update_policy" {
|
||||||
type = object({
|
type = any
|
||||||
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
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "versions" {
|
variable "versions" {
|
||||||
type = map(object({
|
type = any
|
||||||
instance_template = string
|
default = {}
|
||||||
target_type = string # fixed | percent
|
}
|
||||||
target_size = number
|
|
||||||
}))
|
variable "wait_for_instances" {
|
||||||
|
type = any
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
def test_defaults(plan_runner):
|
def test_defaults(plan_runner):
|
||||||
"Test variable defaults."
|
"Test variable defaults."
|
||||||
_, resources = plan_runner()
|
_, resources = plan_runner()
|
||||||
|
@ -21,7 +22,7 @@ def test_defaults(plan_runner):
|
||||||
assert mig['type'] == 'google_compute_instance_group_manager'
|
assert mig['type'] == 'google_compute_instance_group_manager'
|
||||||
assert mig['values']['target_size'] == 2
|
assert mig['values']['target_size'] == 2
|
||||||
assert mig['values']['zone']
|
assert mig['values']['zone']
|
||||||
_, resources = plan_runner(regional='true')
|
_, resources = plan_runner(location='"europe-west1"')
|
||||||
assert len(resources) == 1
|
assert len(resources) == 1
|
||||||
mig = resources[0]
|
mig = resources[0]
|
||||||
assert mig['type'] == 'google_compute_region_instance_group_manager'
|
assert mig['type'] == 'google_compute_region_instance_group_manager'
|
||||||
|
@ -31,7 +32,12 @@ def test_defaults(plan_runner):
|
||||||
|
|
||||||
def test_health_check(plan_runner):
|
def test_health_check(plan_runner):
|
||||||
"Test health check resource."
|
"Test health check resource."
|
||||||
health_check_config = '{type="tcp", check={port=80}, config=null, logging=false}'
|
health_check_config = '''{
|
||||||
|
enable_logging = true
|
||||||
|
tcp = {
|
||||||
|
port = 80
|
||||||
|
}
|
||||||
|
}'''
|
||||||
_, resources = plan_runner(health_check_config=health_check_config)
|
_, resources = plan_runner(health_check_config=health_check_config)
|
||||||
assert len(resources) == 2
|
assert len(resources) == 2
|
||||||
assert any(r['type'] == 'google_compute_health_check' for r in resources)
|
assert any(r['type'] == 'google_compute_health_check' for r in resources)
|
||||||
|
@ -39,20 +45,26 @@ def test_health_check(plan_runner):
|
||||||
|
|
||||||
def test_autoscaler(plan_runner):
|
def test_autoscaler(plan_runner):
|
||||||
"Test autoscaler resource."
|
"Test autoscaler resource."
|
||||||
autoscaler_config = (
|
autoscaler_config = '''{
|
||||||
'{'
|
colldown_period = 60
|
||||||
'max_replicas=3, min_replicas=1, cooldown_period=60,'
|
max_replicas = 3
|
||||||
'cpu_utilization_target=65, load_balancing_utilization_target=null,'
|
min_replicas = 1
|
||||||
'metric=null'
|
scaling_signals = {
|
||||||
'}'
|
cpu_utilization = {
|
||||||
)
|
target = 65
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'''
|
||||||
_, resources = plan_runner(autoscaler_config=autoscaler_config)
|
_, resources = plan_runner(autoscaler_config=autoscaler_config)
|
||||||
assert len(resources) == 2
|
assert len(resources) == 2
|
||||||
autoscaler = resources[0]
|
autoscaler = resources[0]
|
||||||
assert autoscaler['type'] == 'google_compute_autoscaler'
|
assert autoscaler['type'] == 'google_compute_autoscaler'
|
||||||
assert autoscaler['values']['autoscaling_policy'] == [{
|
assert autoscaler['values']['autoscaling_policy'] == [{
|
||||||
'cooldown_period': 60,
|
'cooldown_period': 60,
|
||||||
'cpu_utilization': [{'predictive_method': 'NONE', 'target': 65}],
|
'cpu_utilization': [{
|
||||||
|
'predictive_method': 'NONE',
|
||||||
|
'target': 65
|
||||||
|
}],
|
||||||
'load_balancing_utilization': [],
|
'load_balancing_utilization': [],
|
||||||
'max_replicas': 3,
|
'max_replicas': 3,
|
||||||
'metric': [],
|
'metric': [],
|
||||||
|
@ -62,7 +74,7 @@ def test_autoscaler(plan_runner):
|
||||||
'scaling_schedules': [],
|
'scaling_schedules': [],
|
||||||
}]
|
}]
|
||||||
_, resources = plan_runner(autoscaler_config=autoscaler_config,
|
_, resources = plan_runner(autoscaler_config=autoscaler_config,
|
||||||
regional='true')
|
location='"europe-west1"')
|
||||||
assert len(resources) == 2
|
assert len(resources) == 2
|
||||||
autoscaler = resources[0]
|
autoscaler = resources[0]
|
||||||
assert autoscaler['type'] == 'google_compute_region_autoscaler'
|
assert autoscaler['type'] == 'google_compute_region_autoscaler'
|
||||||
|
@ -71,17 +83,10 @@ def test_autoscaler(plan_runner):
|
||||||
def test_stateful_mig(plan_runner):
|
def test_stateful_mig(plan_runner):
|
||||||
"Test stateful instances - mig."
|
"Test stateful instances - mig."
|
||||||
|
|
||||||
stateful_config = (
|
stateful_disks = '''{
|
||||||
'{'
|
persistent-disk-1 = null
|
||||||
'per_instance_config = {},'
|
}'''
|
||||||
'mig_config = {'
|
_, resources = plan_runner(stateful_disks=stateful_disks)
|
||||||
'stateful_disks = {'
|
|
||||||
'persistent-disk-1 = {delete_rule="NEVER"}'
|
|
||||||
'}'
|
|
||||||
'}'
|
|
||||||
'}'
|
|
||||||
)
|
|
||||||
_, resources = plan_runner(stateful_config=stateful_config)
|
|
||||||
assert len(resources) == 1
|
assert len(resources) == 1
|
||||||
statefuldisk = resources[0]
|
statefuldisk = resources[0]
|
||||||
assert statefuldisk['type'] == 'google_compute_instance_group_manager'
|
assert statefuldisk['type'] == 'google_compute_instance_group_manager'
|
||||||
|
@ -93,35 +98,19 @@ def test_stateful_mig(plan_runner):
|
||||||
|
|
||||||
def test_stateful_instance(plan_runner):
|
def test_stateful_instance(plan_runner):
|
||||||
"Test stateful instances - instance."
|
"Test stateful instances - instance."
|
||||||
stateful_config = (
|
stateful_config = '''{
|
||||||
'{'
|
instance-1 = {
|
||||||
'per_instance_config = {'
|
most_disruptive_action = "REPLACE",
|
||||||
'instance-1 = {'
|
preserved_state = {
|
||||||
'stateful_disks = {'
|
disks = {
|
||||||
'persistent-disk-1 = {'
|
persistent-disk-1 = {
|
||||||
'source = "test-disk",'
|
source = "test-disk"
|
||||||
'mode = "READ_ONLY",'
|
}
|
||||||
'delete_rule= "NEVER",'
|
}
|
||||||
'},'
|
metadata = { foo = "bar" }
|
||||||
'},'
|
}
|
||||||
'metadata = {'
|
}
|
||||||
'foo = "bar"'
|
}'''
|
||||||
'},'
|
|
||||||
'update_config = {'
|
|
||||||
'minimal_action = "NONE",'
|
|
||||||
'most_disruptive_allowed_action = "REPLACE",'
|
|
||||||
'remove_instance_state_on_destroy = false,'
|
|
||||||
|
|
||||||
'},'
|
|
||||||
'},'
|
|
||||||
'},'
|
|
||||||
'mig_config = {'
|
|
||||||
'stateful_disks = {'
|
|
||||||
'persistent-disk-1 = {delete_rule="NEVER"}'
|
|
||||||
'}'
|
|
||||||
'}'
|
|
||||||
'}'
|
|
||||||
)
|
|
||||||
_, resources = plan_runner(stateful_config=stateful_config)
|
_, resources = plan_runner(stateful_config=stateful_config)
|
||||||
assert len(resources) == 2
|
assert len(resources) == 2
|
||||||
instanceconfig = resources[0]
|
instanceconfig = resources[0]
|
||||||
|
@ -134,13 +123,12 @@ def test_stateful_instance(plan_runner):
|
||||||
'device_name': 'persistent-disk-1',
|
'device_name': 'persistent-disk-1',
|
||||||
'delete_rule': 'NEVER',
|
'delete_rule': 'NEVER',
|
||||||
'source': 'test-disk',
|
'source': 'test-disk',
|
||||||
'mode': 'READ_ONLY',
|
'mode': 'READ_WRITE',
|
||||||
}],
|
}],
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'foo': 'bar'
|
'foo': 'bar'
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|
||||||
assert instanceconfig['values']['minimal_action'] == 'NONE'
|
assert instanceconfig['values']['minimal_action'] == 'NONE'
|
||||||
assert instanceconfig['values']['most_disruptive_allowed_action'] == 'REPLACE'
|
assert instanceconfig['values']['most_disruptive_allowed_action'] == 'REPLACE'
|
||||||
assert instanceconfig['values']['remove_instance_state_on_destroy'] == False
|
assert instanceconfig['values']['remove_instance_state_on_destroy'] == False
|
||||||
|
|
Loading…
Reference in New Issue