Added support for Stateful Managed Instance Groups (#367)
* First iteration updates * All tests passing * Updated README and var descriptions * Updated README * Updated example README * Consolidated stateful vars * consolidated stateful vars * Updated README * Requested changes to try * Fixed README examples and try Co-authored-by: Ludovico Magnocavallo <ludomagno@google.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
# GCE Managed Instance Group module
|
||||
|
||||
This module allows creating a managed instance group supporting one or more application versions via instance templates. A health check and an autoscaler can also be optionally created.
|
||||
This module 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.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -266,6 +268,182 @@ module "nginx-mig" {
|
||||
# tftest:modules=2:resources=2
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
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).
|
||||
|
||||
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`.
|
||||
|
||||
|
||||
```hcl
|
||||
module "cos-nginx" {
|
||||
source = "./modules/cloud-config-container/nginx"
|
||||
}
|
||||
|
||||
module "nginx-template" {
|
||||
source = "./modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
name = "nginx-template"
|
||||
zone = "europe-west1-b"
|
||||
tags = ["http-server", "ssh"]
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
nat = false
|
||||
addresses = null
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
attached_disks = [{
|
||||
name = "repd-1"
|
||||
size = null
|
||||
source_type = "attach"
|
||||
source = "regions/${var.region}/disks/repd-test-1"
|
||||
options = {
|
||||
mode = "READ_ONLY"
|
||||
replica_zone = "${var.region}-c"
|
||||
type = "PERSISTENT"
|
||||
}
|
||||
}]
|
||||
create_template = true
|
||||
metadata = {
|
||||
user-data = module.cos-nginx.cloud_config
|
||||
}
|
||||
}
|
||||
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
autoscaler_config = {
|
||||
max_replicas = 3
|
||||
min_replicas = 1
|
||||
cooldown_period = 30
|
||||
cpu_utilization_target = 0.65
|
||||
load_balancing_utilization_target = null
|
||||
metric = null
|
||||
}
|
||||
stateful_config = {
|
||||
per_instance_config = {},
|
||||
mig_config = {
|
||||
stateful_disks = {
|
||||
persistent-disk-1 = {
|
||||
delete_rule = "NEVER"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest:modules=2:resources=3
|
||||
|
||||
```
|
||||
|
||||
### Stateful MIGs - Instance Config
|
||||
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.
|
||||
|
||||
```hcl
|
||||
module "cos-nginx" {
|
||||
source = "./modules/cloud-config-container/nginx"
|
||||
}
|
||||
|
||||
module "nginx-template" {
|
||||
source = "./modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
name = "nginx-template"
|
||||
zone = "europe-west1-b"
|
||||
tags = ["http-server", "ssh"]
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
nat = false
|
||||
addresses = null
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
attached_disks = [{
|
||||
name = "repd-1"
|
||||
size = null
|
||||
source_type = "attach"
|
||||
source = "regions/${var.region}/disks/repd-test-1"
|
||||
options = {
|
||||
mode = "READ_ONLY"
|
||||
replica_zone = "${var.region}-c"
|
||||
type = "PERSISTENT"
|
||||
}
|
||||
}]
|
||||
create_template = true
|
||||
metadata = {
|
||||
user-data = module.cos-nginx.cloud_config
|
||||
}
|
||||
}
|
||||
|
||||
module "nginx-mig" {
|
||||
source = "./modules/compute-mig"
|
||||
project_id = "my-project"
|
||||
location = "europe-west1-b"
|
||||
name = "mig-test"
|
||||
target_size = 3
|
||||
default_version = {
|
||||
instance_template = module.nginx-template.template.self_link
|
||||
name = "default"
|
||||
}
|
||||
autoscaler_config = {
|
||||
max_replicas = 3
|
||||
min_replicas = 1
|
||||
cooldown_period = 30
|
||||
cpu_utilization_target = 0.65
|
||||
load_balancing_utilization_target = null
|
||||
metric = null
|
||||
}
|
||||
stateful_config = {
|
||||
per_instance_config = {
|
||||
# note that this needs to be the name of an existing instance within the Managed Instance Group
|
||||
instance-1 = {
|
||||
stateful_disks = {
|
||||
persistent-disk-1 = {
|
||||
source = "test-disk",
|
||||
mode = "READ_ONLY",
|
||||
delete_rule= "NEVER",
|
||||
},
|
||||
},
|
||||
metadata = {
|
||||
foo = "bar"
|
||||
},
|
||||
update_config = {
|
||||
minimal_action = "NONE",
|
||||
most_disruptive_allowed_action = "REPLACE",
|
||||
remove_instance_state_on_destroy = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
mig_config = {
|
||||
stateful_disks = {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest:modules=2:resources=4
|
||||
|
||||
```
|
||||
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
@@ -280,6 +458,7 @@ module "nginx-mig" {
|
||||
| *health_check_config* | 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 title="">null</code> |
|
||||
| *named_ports* | Named ports. | <code title="map(number)">map(number)</code> | | <code title="">null</code> |
|
||||
| *regional* | Use regional instance group. When set, `location` should be set to the region. | <code title="">bool</code> | | <code title="">false</code> |
|
||||
| *stateful_config* | 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 title="">null</code> |
|
||||
| *target_pools* | Optional list of URLs for target pools to which new instances in the group are added. | <code title="list(string)">list(string)</code> | | <code title="">[]</code> |
|
||||
| *target_size* | Group target size, leave null when using an autoscaler. | <code title="">number</code> | | <code title="">null</code> |
|
||||
| *update_policy* | Update policy. Type can be 'OPPORTUNISTIC' or 'PROACTIVE', action 'REPLACE' or 'restart', surge type 'fixed' or 'percent'. | <code title="object({ type = string # OPPORTUNISTIC | PROACTIVE minimal_action = string # REPLACE | RESTART min_ready_sec = number max_surge_type = string # fixed | percent max_surge = number max_unavailable_type = string max_unavailable = number })">object({...})</code> | | <code title="">null</code> |
|
||||
@@ -297,4 +476,4 @@ module "nginx-mig" {
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] add support for instance groups
|
||||
- [✓] add support for instance groups
|
||||
|
||||
Reference in New Issue
Block a user