# GCE Managed Instance Group module
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.
Stateful disks can be created directly, as shown in the last example below.
## Examples
This example shows how to manage a simple MIG that leverages the `compute-vm` module to manage the underlying instance template. The following sub-examples will only show how to enable specific features of this module, and won't replicate the combined setup.
```hcl
module "cos-nginx" {
source = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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
}
create_template = true
metadata = {
user-data = module.cos-nginx.cloud_config
}
}
module "nginx-mig" {
source = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 2
instance_template = module.nginx-template.template.self_link
}
# tftest modules=2 resources=2
```
### Multiple versions
If multiple versions are desired, use more `compute-vm` instances for the additional templates used in each version (not shown here), and reference them like this:
```hcl
module "cos-nginx" {
source = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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
}
create_template = true
metadata = {
user-data = module.cos-nginx.cloud_config
}
}
module "nginx-mig" {
source = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
versions = {
canary = {
instance_template = module.nginx-template.template.self_link
target_size = {
fixed = 1
}
}
}
}
# tftest modules=2 resources=2
```
### Health check and autohealing policies
Autohealing policies can use an externally defined health check, or have this module auto-create one:
```hcl
module "cos-nginx" {
source = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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
}
create_template = true
metadata = {
user-data = module.cos-nginx.cloud_config
}
}
module "nginx-mig" {
source = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
auto_healing_policies = {
initial_delay_sec = 30
}
health_check_config = {
enable_logging = true
http = {
port = 80
}
}
}
# tftest modules=2 resources=3
```
### Autoscaling
The module can create and manage an autoscaler associated with the MIG. When using autoscaling do not set the `target_size` variable or set it to `null`. Here we show a CPU utilization autoscaler, the other available modes are load balancing utilization and custom metric, like the underlying autoscaler resource.
```hcl
module "cos-nginx" {
source = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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
}
create_template = true
metadata = {
user-data = module.cos-nginx.cloud_config
}
}
module "nginx-mig" {
source = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
autoscaler_config = {
max_replicas = 3
min_replicas = 1
cooldown_period = 30
scaling_signals = {
cpu_utilization = {
target = 0.65
}
}
}
}
# tftest modules=2 resources=3
```
### Update policy
```hcl
module "cos-nginx" {
source = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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
}
create_template = true
metadata = {
user-data = module.cos-nginx.cloud_config
}
}
module "nginx-mig" {
source = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
update_policy = {
minimal_action = "REPLACE"
type = "PROACTIVE"
min_ready_sec = 30
max_surge = {
fixed = 1
}
}
}
# 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 = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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 = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
autoscaler_config = {
max_replicas = 3
min_replicas = 1
cooldown_period = 30
scaling_signals = {
cpu_utilization = {
target = 0.65
}
}
}
stateful_disks = {
repd-1 = false
}
}
# 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 = "./fabric/modules/cloud-config-container/nginx"
}
module "nginx-template" {
source = "./fabric/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 = "./fabric/modules/compute-mig"
project_id = "my-project"
location = "europe-west1-b"
name = "mig-test"
target_size = 3
instance_template = module.nginx-template.template.self_link
autoscaler_config = {
max_replicas = 3
min_replicas = 1
cooldown_period = 30
scaling_signals = {
cpu_utilization = {
target = 0.65
}
}
}
stateful_config = {
# name needs to match a MIG instance name
instance-1 = {
minimal_action = "NONE",
most_disruptive_allowed_action = "REPLACE"
preserved_state = {
disks = {
persistent-disk-1 = {
source = "test-disk",
}
}
metadata = {
foo = "bar"
}
}
}
}
}
# tftest modules=2 resources=4
```
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [instance_template](variables.tf#L177) | Instance template for the default version. | string
| ✓ | |
| [location](variables.tf#L182) | Compute zone or region. | string
| ✓ | |
| [name](variables.tf#L187) | Managed group name. | string
| ✓ | |
| [project_id](variables.tf#L198) | Project id. | string
| ✓ | |
| [all_instances_config](variables.tf#L17) | Metadata and labels set to all instances in the group. | object({…})
| | null
|
| [auto_healing_policies](variables.tf#L26) | Auto-healing policies for this group. | object({…})
| | null
|
| [autoscaler_config](variables.tf#L35) | Optional autoscaler configuration. | object({…})
| | null
|
| [default_version_name](variables.tf#L83) | Name used for the default version. | string
| | "default"
|
| [description](variables.tf#L89) | Optional description used for all resources managed by this module. | string
| | "Terraform managed."
|
| [distribution_policy](variables.tf#L95) | DIstribution policy for regional MIG. | object({…})
| | null
|
| [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. | object({…})
| | null
|
| [named_ports](variables.tf#L192) | Named ports. | map(number)
| | null
|
| [stateful_config](variables.tf#L203) | Stateful configuration for individual instances. | map(object({…}))
| | {}
|
| [stateful_disks](variables.tf#L222) | Stateful disk configuration applied at the MIG level to all instances, in device name => on permanent instance delete rule as boolean. | map(bool)
| | {}
|
| [target_pools](variables.tf#L229) | Optional list of URLs for target pools to which new instances in the group are added. | list(string)
| | []
|
| [target_size](variables.tf#L235) | Group target size, leave null when using an autoscaler. | number
| | null
|
| [update_policy](variables.tf#L241) | Update policy. Minimal action and type are required. | object({…})
| | null
|
| [versions](variables.tf#L262) | Additional application versions, target_size is optional. | map(object({…}))
| | {}
|
| [wait_for_instances](variables.tf#L275) | Wait for all instances to be created/updated before returning. | object({…})
| | null
|
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [autoscaler](outputs.tf#L17) | Auto-created autoscaler resource. | |
| [group_manager](outputs.tf#L26) | Instance group resource. | |
| [health_check](outputs.tf#L35) | Auto-created health-check resource. | |