Skip to content

Commit

Permalink
feat!: autoscaler supporting stateful ips (#297)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericyz authored May 3, 2023
1 parent 3390316 commit 5d13e8b
Show file tree
Hide file tree
Showing 24 changed files with 479 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ suites:
driver:
name: terraform
command_timeout: 1800
root_module_directory: test/fixtures/mig_with_percent/simple
root_module_directory: test/fixtures/mig_with_percent/simple
16 changes: 16 additions & 0 deletions autogen/main.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ resource "google_compute_region_instance_group_manager" "{{ module_name }}" {
}
}

dynamic "stateful_internal_ip" {
for_each = [for static_ip in var.stateful_ips: static_ip if static_ip["is_external"] == false]
content {
interface_name = stateful_internal_ip.value.interface_name
delete_rule = lookup(stateful_internal_ip.value, "delete_rule", null)
}
}

dynamic "stateful_external_ip" {
for_each = [for static_ip in var.stateful_ips: static_ip if static_ip["is_external"] == true]
content {
interface_name = stateful_external_ip.value.interface_name
delete_rule = lookup(stateful_external_ip.value, "delete_rule", null)
}
}

distribution_policy_zones = local.distribution_policy_zones
dynamic "update_policy" {
for_each = var.update_policy
Expand Down
13 changes: 13 additions & 0 deletions autogen/variables.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ variable "stateful_disks" {
default = []
}

#################
# Stateful IPs
#################
variable "stateful_ips" {
description = "Statful IPs created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-ip-addresses-in-migs"
type = list(object({
interface_name = string
delete_rule = string
is_external = bool
}))
default = []
}

#################
# Rolling Update
#################
Expand Down
4 changes: 2 additions & 2 deletions autogen/versions.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
terraform {
required_version = ">=0.13.0"
required_providers {
google = ">= 3.71, < 5.0"
google-beta = ">= 3.71, < 5.0"
google = ">= 4.48, < 5.0"
google-beta = ">= 4.48, < 5.0"
}
provider_meta "google" {
module_name = "blueprints/terraform/terraform-google-vm:{% if mig %}mig{% else %}mig_with_percent{% endif %}/v8.0.1"
Expand Down
23 changes: 22 additions & 1 deletion build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,28 @@ steps:
- verify-mig-with-percent-simple-local
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy mig-with-percent-simple-local']

- id: go-init-statful-mig
waitFor:
- create-all
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestMigStatefulModule --stage create --verbose']
- id: go-apply-statful-mig
waitFor:
- go-init-statful-mig
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestMigStatefulModule --stage apply --verbose']
timeout: 3600s
- id: go-verify-statful-mig
waitFor:
- go-apply-statful-mig
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestMigStatefulModule --stage verify --verbose']
- id: go-destroy-statful-mig
waitFor:
- go-verify-statful-mig
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestMigStatefulModule --stage destroy --verbose']
timeout: 1800s
tags:
- 'ci'
- 'integration'
Expand Down
24 changes: 24 additions & 0 deletions examples/mig_stateful/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# mig-simple

This is a simple, minimal example of how to use the MIG module to create a
managed instance group.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| project\_id | The GCP project to use for integration tests | `string` | n/a | yes |
| region | The GCP region to create and test resources in | `string` | `"us-central1"` | no |
| service\_account | Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template#service_account. | <pre>object({<br> email = string<br> scopes = set(string)<br> })</pre> | `null` | no |
| subnetwork | The subnetwork to host the compute instances in | `any` | n/a | yes |
| target\_size | The target number of running instances for this managed instance group. This value should always be explicitly set unless this resource is attached to an autoscaler, in which case it should never be set. | `any` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| region | The GCP region to create and test resources in |
| self\_link | Self-link of the managed instance group |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
78 changes: 78 additions & 0 deletions examples/mig_stateful/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright 2018 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.
*/

provider "google" {
}

provider "google-beta" {
}

resource "random_string" "suffix" {
length = 4
special = "false"
upper = "false"
}

/** Network **/

resource "google_compute_network" "main" {
project = var.project_id
name = "cft-vm-test-${random_string.suffix.result}"
auto_create_subnetworks = "false"
}

resource "google_compute_subnetwork" "main" {
project = var.project_id
region = var.region
name = "cft-vm-test-${random_string.suffix.result}"
ip_cidr_range = "10.128.0.0/20"
network = google_compute_network.main.self_link
}

module "instance_template" {
source = "../../modules/instance_template"
project_id = var.project_id
region = var.region
subnetwork = var.subnetwork
service_account = var.service_account
subnetwork_project = var.project_id
}

module "mig" {
source = "../../modules/mig"
project_id = var.project_id
region = var.region
target_size = var.target_size
hostname = "mig-stateful"
instance_template = module.instance_template.self_link
stateful_ips = [{
interface_name = "nic0"
delete_rule = "ON_PERMANENT_INSTANCE_DELETION"
is_external = true
}]

update_policy = [{
max_surge_fixed = 0
instance_redistribution_type = "NONE"
max_surge_percent = null
max_unavailable_fixed = 4
max_unavailable_percent = null
min_ready_sec = 180
replacement_method = "RECREATE"
minimal_action = "REFRESH"
type = "OPPORTUNISTIC"
}]
}
25 changes: 25 additions & 0 deletions examples/mig_stateful/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "self_link" {
description = "Self-link of the managed instance group"
value = module.mig.self_link
}

output "region" {
description = "The GCP region to create and test resources in"
value = var.region
}
46 changes: 46 additions & 0 deletions examples/mig_stateful/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/



variable "project_id" {
description = "The GCP project to use for integration tests"
type = string
}

variable "region" {
description = "The GCP region to create and test resources in"
type = string
default = "us-central1"
}

variable "subnetwork" {
description = "The subnetwork to host the compute instances in"
}

variable "target_size" {
description = "The target number of running instances for this managed instance group. This value should always be explicitly set unless this resource is attached to an autoscaler, in which case it should never be set."
}

variable "service_account" {
default = null
type = object({
email = string
scopes = set(string)
})
description = "Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template#service_account."
}

29 changes: 29 additions & 0 deletions examples/mig_stateful/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2018 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.
*/

terraform {
required_version = ">= 0.13"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 4.0"
}
}
}
1 change: 1 addition & 0 deletions modules/mig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ The current version is 2.X. The following guides are available to assist with up
| region | The GCP region where the managed instance group resides. | `string` | n/a | yes |
| scaling\_schedules | Autoscaling, scaling schedule block. https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_autoscaler#scaling_schedules | <pre>list(object({<br> disabled = bool<br> duration_sec = number<br> min_required_replicas = number<br> name = string<br> schedule = string<br> time_zone = string<br> }))</pre> | `[]` | no |
| stateful\_disks | Disks created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-disks-in-migs | <pre>list(object({<br> device_name = string<br> delete_rule = string<br> }))</pre> | `[]` | no |
| stateful\_ips | Statful IPs created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-ip-addresses-in-migs | <pre>list(object({<br> interface_name = string<br> delete_rule = string<br> is_external = bool<br> }))</pre> | `[]` | no |
| target\_pools | The target load balancing pools to assign this group to. | `list(string)` | `[]` | no |
| target\_size | The target number of running instances for this managed instance group. This value should always be explicitly set unless this resource is attached to an autoscaler, in which case it should never be set. | `number` | `1` | no |
| update\_policy | The rolling update policy. https://www.terraform.io/docs/providers/google/r/compute_region_instance_group_manager#rolling_update_policy | <pre>list(object({<br> max_surge_fixed = number<br> instance_redistribution_type = string<br> max_surge_percent = number<br> max_unavailable_fixed = number<br> max_unavailable_percent = number<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> }))</pre> | `[]` | no |
Expand Down
16 changes: 16 additions & 0 deletions modules/mig/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ resource "google_compute_region_instance_group_manager" "mig" {
}
}

dynamic "stateful_internal_ip" {
for_each = [for static_ip in var.stateful_ips : static_ip if static_ip["is_external"] == false]
content {
interface_name = stateful_internal_ip.value.interface_name
delete_rule = lookup(stateful_internal_ip.value, "delete_rule", null)
}
}

dynamic "stateful_external_ip" {
for_each = [for static_ip in var.stateful_ips : static_ip if static_ip["is_external"] == true]
content {
interface_name = stateful_external_ip.value.interface_name
delete_rule = lookup(stateful_external_ip.value, "delete_rule", null)
}
}

distribution_policy_zones = local.distribution_policy_zones
dynamic "update_policy" {
for_each = var.update_policy
Expand Down
13 changes: 13 additions & 0 deletions modules/mig/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ variable "stateful_disks" {
default = []
}

#################
# Stateful IPs
#################
variable "stateful_ips" {
description = "Statful IPs created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-ip-addresses-in-migs"
type = list(object({
interface_name = string
delete_rule = string
is_external = bool
}))
default = []
}

#################
# Rolling Update
#################
Expand Down
4 changes: 2 additions & 2 deletions modules/mig/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
terraform {
required_version = ">=0.13.0"
required_providers {
google = ">= 3.71, < 5.0"
google-beta = ">= 3.71, < 5.0"
google = ">= 4.48, < 5.0"
google-beta = ">= 4.48, < 5.0"
}
provider_meta "google" {
module_name = "blueprints/terraform/terraform-google-vm:mig/v8.0.1"
Expand Down
1 change: 1 addition & 0 deletions modules/mig_with_percent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The current version is 2.X. The following guides are available to assist with up
| region | The GCP region where the managed instance group resides. | `string` | n/a | yes |
| scaling\_schedules | Autoscaling, scaling schedule block. https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_autoscaler#scaling_schedules | <pre>list(object({<br> disabled = bool<br> duration_sec = number<br> min_required_replicas = number<br> name = string<br> schedule = string<br> time_zone = string<br> }))</pre> | `[]` | no |
| stateful\_disks | Disks created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-disks-in-migs | <pre>list(object({<br> device_name = string<br> delete_rule = string<br> }))</pre> | `[]` | no |
| stateful\_ips | Statful IPs created on the instances that will be preserved on instance delete. https://cloud.google.com/compute/docs/instance-groups/configuring-stateful-ip-addresses-in-migs | <pre>list(object({<br> interface_name = string<br> delete_rule = string<br> is_external = bool<br> }))</pre> | `[]` | no |
| target\_pools | The target load balancing pools to assign this group to. | `list(string)` | `[]` | no |
| target\_size | The target number of running instances for this managed instance group. This value should always be explicitly set unless this resource is attached to an autoscaler, in which case it should never be set. | `number` | `1` | no |
| update\_policy | The rolling update policy. https://www.terraform.io/docs/providers/google/r/compute_region_instance_group_manager#rolling_update_policy | <pre>list(object({<br> max_surge_fixed = number<br> instance_redistribution_type = string<br> max_surge_percent = number<br> max_unavailable_fixed = number<br> max_unavailable_percent = number<br> min_ready_sec = number<br> replacement_method = string<br> minimal_action = string<br> type = string<br> }))</pre> | `[]` | no |
Expand Down
16 changes: 16 additions & 0 deletions modules/mig_with_percent/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ resource "google_compute_region_instance_group_manager" "mig_with_percent" {
}
}

dynamic "stateful_internal_ip" {
for_each = [for static_ip in var.stateful_ips : static_ip if static_ip["is_external"] == false]
content {
interface_name = stateful_internal_ip.value.interface_name
delete_rule = lookup(stateful_internal_ip.value, "delete_rule", null)
}
}

dynamic "stateful_external_ip" {
for_each = [for static_ip in var.stateful_ips : static_ip if static_ip["is_external"] == true]
content {
interface_name = stateful_external_ip.value.interface_name
delete_rule = lookup(stateful_external_ip.value, "delete_rule", null)
}
}

distribution_policy_zones = local.distribution_policy_zones
dynamic "update_policy" {
for_each = var.update_policy
Expand Down
Loading

0 comments on commit 5d13e8b

Please sign in to comment.