From 65245637479473df5ee2955393e3a24dc40f4e33 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Fri, 19 Jun 2020 09:49:37 +0200 Subject: [PATCH 1/4] Add optional unmanaged instance groups to net-ilb (#98) * add optional unmanaged instance groups to net-ilb * depend health check creation on the health_check variable * add example for self-managed group * update changelog --- CHANGELOG.md | 1 + modules/net-ilb/README.md | 41 +++++++++++++++++++++++++++--- modules/net-ilb/main.tf | 48 ++++++++++++++++++++++++++++-------- modules/net-ilb/outputs.tf | 12 +++++++++ modules/net-ilb/variables.tf | 10 ++++++++ 5 files changed, 99 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abe1bfd6d..6340c2e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - **incompatible change** routes in the `net-vpc` module now interpolate the VPC name to ensure uniqueness, upgrading from a previous version will drop and recreate routes - the top-level `docker-images` folder has been moved inside `modules/cloud-config-container/onprem` - `dns_keys` output added to the `dns` module +- add `group-config` variable, `groups` and `group_self_links` outputs to `net-ilb` module to allow creating ILBs for externally managed instances ## [2.0.0] - 2020-06-11 diff --git a/modules/net-ilb/README.md b/modules/net-ilb/README.md index 759ad80f5..197f2a1e4 100644 --- a/modules/net-ilb/README.md +++ b/modules/net-ilb/README.md @@ -15,7 +15,40 @@ There are some corner cases (eg when switching the instance template from intern One other issue is a `Provider produced inconsistent final plan` error which is sometimes raised when switching template version. This seems to be related to this [open provider issue](https://github.com/terraform-providers/terraform-provider-google/issues/3937), but it's relatively harmless since the resource is updated, and subsequent applies raise no errors. -## Example +## Examples + +### Externally managed instances + +This examples shows how to create an ILB by combining externally managed instances (in a custom module or even outside of the current root module) in an unmanaged group. + +```hcl +module "ilb" { + source = "./modules/net-ilb" + project_id = "my-project" + region = "europe-west1" + name = "ilb-test" + service_label = "ilb-test" + network = local.network_self_link + subnetwork = local.subnetwork_self_link + group_configs = { + my-group = { + zone = europe-west1-b, named_ports = null, instances = [ + local.instance1_self_link, local.instance2_self_link + ] + } + } + backends = [{ + failover = false + group = module.ilb.groups.my-group.self_link + balancing_mode = "CONNECTION" + }] + health_check_config = { + type = "http", check = { port = 80 }, config = {}, logging = true + } +} +``` + +### End to end example This example spins up a simple HTTP server and combines four modules: @@ -81,6 +114,7 @@ module "ilb" { | name | description | type | required | default | |---|---|:---: |:---:|:---:| | backends | Load balancer backends, balancing mode is one of 'CONNECTION' or 'UTILIZATION'. | list(object({...})) | ✓ | | +| group_configs | Optional unmanaged groups to create. Can be referenced in backends via outputs. | map(object({...})) | ✓ | | | name | Name used for all resources. | string | ✓ | | | network | Network used for resources. | string | ✓ | | | project_id | Project id where resources will be created. | string | ✓ | | @@ -91,9 +125,8 @@ module "ilb" { | *failover_config* | Optional failover configuration. | object({...}) | | null | | *global_access* | Global access, defaults to false if not set. | bool | | null | | *health_check* | Name of existing health check to use, disables auto-created health check. | string | | null | -| *health_check_config* | Configuration of the auto-created helth check. | object({...}) | | ... | +| *health_check_config* | Configuration of the auto-created helth check. | object({...}) | | ... | | *labels* | Labels set on resources. | map(string) | | {} | -| *log_sample_rate* | Set a value between 0 and 1 to enable logging for resources, and set the sampling rate for backend logging. | number | | null | | *ports* | Comma-separated ports, leave null to use all ports. | list(string) | | null | | *protocol* | IP protocol used, defaults to TCP. | string | | TCP | | *service_label* | Optional prefix of the fully qualified forwarding rule name. | string | | null | @@ -109,6 +142,8 @@ module "ilb" { | forwarding_rule_address | Forwarding rule address. | | | forwarding_rule_id | Forwarding rule id. | | | forwarding_rule_self_link | Forwarding rule self link. | | +| group_self_links | Optional unmanaged instance group self links. | | +| groups | Optional unmanaged instance group resources. | | | health_check | Auto-created health-check resource. | | | health_check_self_id | Auto-created health-check self id. | | | health_check_self_link | Auto-created health-check self link. | | diff --git a/modules/net-ilb/main.tf b/modules/net-ilb/main.tf index eb6ee4751..75440d2f4 100644 --- a/modules/net-ilb/main.tf +++ b/modules/net-ilb/main.tf @@ -29,6 +29,7 @@ locals { google_compute_health_check.http2.0, {} ) + health_check_type = try(var.health_check_config.type, null) } resource "google_compute_forwarding_rule" "default" { @@ -89,9 +90,28 @@ resource "google_compute_region_backend_service" "default" { } +resource "google_compute_instance_group" "unmanaged" { + for_each = var.group_configs + project = var.project_id + zone = each.value.zone + name = each.key + description = "Terraform-managed." + instances = each.value.instances + dynamic named_port { + for_each = each.value.named_ports != null ? each.value.named_ports : {} + iterator = config + content { + name = config.key + port = config.value + } + } +} + resource "google_compute_health_check" "http" { - provider = google-beta - count = try(var.health_check_config.type, null) == "http" ? 1 : 0 + provider = google-beta + count = ( + var.health_check == null && local.health_check_type == "http" ? 1 : 0 + ) project = var.project_id name = var.name description = "Terraform managed." @@ -120,8 +140,10 @@ resource "google_compute_health_check" "http" { } resource "google_compute_health_check" "https" { - provider = google-beta - count = try(var.health_check_config.type, null) == "https" ? 1 : 0 + provider = google-beta + count = ( + var.health_check == null && local.health_check_type == "https" ? 1 : 0 + ) project = var.project_id name = var.name description = "Terraform managed." @@ -150,8 +172,10 @@ resource "google_compute_health_check" "https" { } resource "google_compute_health_check" "tcp" { - provider = google-beta - count = try(var.health_check_config.type, null) == "tcp" ? 1 : 0 + provider = google-beta + count = ( + var.health_check == null && local.health_check_type == "tcp" ? 1 : 0 + ) project = var.project_id name = var.name description = "Terraform managed." @@ -179,8 +203,10 @@ resource "google_compute_health_check" "tcp" { } resource "google_compute_health_check" "ssl" { - provider = google-beta - count = try(var.health_check_config.type, null) == "ssl" ? 1 : 0 + provider = google-beta + count = ( + var.health_check == null && local.health_check_type == "ssl" ? 1 : 0 + ) project = var.project_id name = var.name description = "Terraform managed." @@ -208,8 +234,10 @@ resource "google_compute_health_check" "ssl" { } resource "google_compute_health_check" "http2" { - provider = google-beta - count = try(var.health_check_config.type, null) == "http2" ? 1 : 0 + provider = google-beta + count = ( + var.health_check == null && local.health_check_type == "http2" ? 1 : 0 + ) project = var.project_id name = var.name description = "Terraform managed." diff --git a/modules/net-ilb/outputs.tf b/modules/net-ilb/outputs.tf index 8418e40a7..6f8ddd603 100644 --- a/modules/net-ilb/outputs.tf +++ b/modules/net-ilb/outputs.tf @@ -49,6 +49,18 @@ output "forwarding_rule_self_link" { value = google_compute_forwarding_rule.default.self_link } +output "groups" { + description = "Optional unmanaged instance group resources." + value = google_compute_instance_group.unmanaged +} + +output "group_self_links" { + description = "Optional unmanaged instance group self links." + value = { + for k, v in google_compute_instance_group.unmanaged : k => v.self_link + } +} + output "health_check" { description = "Auto-created health-check resource." value = local.health_check_resource diff --git a/modules/net-ilb/variables.tf b/modules/net-ilb/variables.tf index df7e7ee8b..f4f0036a5 100644 --- a/modules/net-ilb/variables.tf +++ b/modules/net-ilb/variables.tf @@ -55,6 +55,16 @@ variable "global_access" { default = null } +variable "group_configs" { + description = "Optional unmanaged groups to create. Can be referenced in backends via outputs." + type = map(object({ + instances = list(string) + named_ports = map(number) + zone = string + })) + default = {} +} + variable "health_check" { description = "Name of existing health check to use, disables auto-created health check." type = string From e2a9e3d415a715f1d012768ccb9fa061a814031d Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Fri, 19 Jun 2020 11:16:22 +0200 Subject: [PATCH 2/4] Update README.md --- modules/net-ilb/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/net-ilb/README.md b/modules/net-ilb/README.md index 197f2a1e4..a368b8eab 100644 --- a/modules/net-ilb/README.md +++ b/modules/net-ilb/README.md @@ -4,7 +4,6 @@ This module allows managing a GCE Internal Load Balancer and integrates the forw ## TODO -- [ ] do not create health check resource if `var.health_check` is not `null` (workaround is to set `var.health_check_config` to `null` - [ ] add a variable for setting address purpose to `SHARED_LOADBALANCER_VIP` and an output for the address once the [provider support has been implemented](https://github.com/terraform-providers/terraform-provider-google/issues/6499) ## Issues @@ -19,7 +18,7 @@ One other issue is a `Provider produced inconsistent final plan` error which is ### Externally managed instances -This examples shows how to create an ILB by combining externally managed instances (in a custom module or even outside of the current root module) in an unmanaged group. +This examples shows how to create an ILB by combining externally managed instances (in a custom module or even outside of the current root module) in an unmanaged group. When using internally managed groups, remember to run `terraform apply` each time group instances change. ```hcl module "ilb" { From 9f3500bff3df0bb1651f29c20f9ec1da0b6d88e3 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Mon, 22 Jun 2020 16:16:19 +0200 Subject: [PATCH 3/4] IAM bindings in compute-vm need to depend on the instance resource --- CHANGELOG.md | 1 + modules/compute-vm/main.tf | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6340c2e9b..b8dafed79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - the top-level `docker-images` folder has been moved inside `modules/cloud-config-container/onprem` - `dns_keys` output added to the `dns` module - add `group-config` variable, `groups` and `group_self_links` outputs to `net-ilb` module to allow creating ILBs for externally managed instances +- make the IAM bindings depend on the compute instance in the `compute-vm` module ## [2.0.0] - 2020-06-11 diff --git a/modules/compute-vm/main.tf b/modules/compute-vm/main.tf index 08981b715..83121fbda 100644 --- a/modules/compute-vm/main.tf +++ b/modules/compute-vm/main.tf @@ -175,6 +175,7 @@ resource "google_compute_instance_iam_binding" "default" { instance_name = each.value.name role = each.value.role members = lookup(var.iam_members, each.value.role, []) + depends_on = [google_compute_instance.default] } resource "google_compute_instance_template" "default" { From 3c60af506feca5c1bc5d869502e627f93447c31f Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Mon, 22 Jun 2020 17:18:01 +0200 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8dafed79..0b9e9b3a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [2.1.0] - 2020-06-22 + - **incompatible change** routes in the `net-vpc` module now interpolate the VPC name to ensure uniqueness, upgrading from a previous version will drop and recreate routes - the top-level `docker-images` folder has been moved inside `modules/cloud-config-container/onprem` - `dns_keys` output added to the `dns` module @@ -102,7 +104,8 @@ All notable changes to this project will be documented in this file. - merge development branch with suite of new modules and end-to-end examples -[Unreleased]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v2.0.0...HEAD +[Unreleased]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v2.1.0...HEAD +[2.1.0]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v2.0.0...v2.1.0 [2.0.0]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v1.9.0...v2.0.0 [1.9.0]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v1.8.1...v1.9.0 [1.8.1]: https://github.com/terraform-google-modules/cloud-foundation-fabric/compare/v1.8.0...v1.8.1