Skip to content

Commit

Permalink
feat: autoscaler supporting stateful ips
Browse files Browse the repository at this point in the history
  • Loading branch information
ericyz committed Mar 6, 2023
1 parent db2a325 commit aff958c
Show file tree
Hide file tree
Showing 25 changed files with 572 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,8 @@ suites:
name: terraform
command_timeout: 1800
root_module_directory: test/fixtures/mig_with_percent/simple
- name: mig_stateful
driver:
name: terraform
command_timeout: 1800
root_module_directory: test/fixtures/mig/stateful
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 = var.stateful_internal_ips
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 = var.stateful_external_ips
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
21 changes: 21 additions & 0 deletions autogen/variables.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ variable "stateful_disks" {
default = []
}

#################
# Stateful IPs
#################
variable "stateful_internal_ips" {
description = "Internal 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
}))
default = []
}

variable "stateful_external_ips" {
description = "External 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
}))
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.0"
Expand Down
24 changes: 24 additions & 0 deletions build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,30 @@ 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: create-mig-stateful-local
wait_for:
- destroy-it-simple-local
- destroy-it-additional-disks-local
- destroy-preemptible-and-regular-instance-templates-simple-local
- go-destroy-instance-simple
- destroy-mig-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 create mig-stateful-local']
- id: converge-mig-stateful-local
wait_for:
- create-mig-stateful-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 converge mig-stateful-local']
- id: verify-mig-stateful-local
wait_for:
- converge-mig-stateful-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 verify mig-stateful-local']
- id: destroy-mig-stateful-local
wait_for:
- verify-mig-stateful-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-stateful-local']

tags:
- 'ci'
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 -->
80 changes: 80 additions & 0 deletions examples/mig/stateful/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* 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" {
project = var.project_id
region = var.region
}

provider "google-beta" {
project = var.project_id
region = var.region
}

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
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_internal_ips = [{
interface_name = "nic0"
delete_rule = "ON_PERMANENT_INSTANCE_DELETION"
}]

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"
}
}
}
2 changes: 2 additions & 0 deletions modules/mig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ 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\_external\_ips | External 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> }))</pre> | `[]` | no |
| stateful\_internal\_ips | Internal 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> }))</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 = var.stateful_internal_ips
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 = var.stateful_external_ips
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
21 changes: 21 additions & 0 deletions modules/mig/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ variable "stateful_disks" {
default = []
}

#################
# Stateful IPs
#################
variable "stateful_internal_ips" {
description = "Internal 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
}))
default = []
}

variable "stateful_external_ips" {
description = "External 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
}))
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.0"
Expand Down
2 changes: 2 additions & 0 deletions modules/mig_with_percent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ 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\_external\_ips | External 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> }))</pre> | `[]` | no |
| stateful\_internal\_ips | Internal 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> }))</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
Loading

0 comments on commit aff958c

Please sign in to comment.