From 942cf53890f41a707105a96e68522f20401784c1 Mon Sep 17 00:00:00 2001 From: Lyly Louanghaksaphone Date: Wed, 15 Apr 2020 11:56:54 -0400 Subject: [PATCH 1/2] Update keys --- .gitignore | 1 + main.tf | 419 +++++++++++++++++++++++++++++++++++---------------- outputs.tf | 69 ++++++--- variables.tf | 143 +++++++++--------- 4 files changed, 403 insertions(+), 229 deletions(-) diff --git a/.gitignore b/.gitignore index 2ac8978..40f4eba 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ **/backend.tf **/terraform.tfvars **/values-*.yaml +.tool-versions diff --git a/main.tf b/main.tf index ff3b368..c14be02 100644 --- a/main.tf +++ b/main.tf @@ -15,51 +15,74 @@ */ resource "google_compute_instance_template" "default" { - count = "${var.module_enabled ? 1 : 0}" - project = "${var.project}" + count = var.module_enabled ? 1 : 0 + project = var.project name_prefix = "default-" - machine_type = "${var.machine_type}" + machine_type = var.machine_type - region = "${var.region}" + region = var.region - tags = ["${concat(list("allow-ssh"), var.target_tags)}"] + # TF-UPGRADE-TODO: In Terraform v0.10 and earlier, it was sometimes necessary to + # force an interpolation expression to be interpreted as a list by wrapping it + # in an extra set of list brackets. That form was supported for compatibility in + # v0.11, but is no longer supported in Terraform v0.12. + # + # If the expression in the following list itself returns a list, remove the + # brackets to avoid interpretation as a list of lists. If the expression + # returns a single list item then leave it as-is and remove this TODO comment. + # DONE, removed the extra bracket due to the network tags returning a list + tags = concat(["allow-ssh"], var.target_tags) - labels = "${var.instance_labels}" + labels = var.instance_labels network_interface { - network = "${var.subnetwork == "" ? var.network : ""}" - subnetwork = "${var.subnetwork}" - access_config = ["${var.access_config}"] - network_ip = "${var.network_ip}" - subnetwork_project = "${var.subnetwork_project == "" ? var.project : var.subnetwork_project}" + network = var.subnetwork == "" ? var.network : "" + subnetwork = var.subnetwork + dynamic "access_config" { + for_each = var.access_config + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE + nat_ip = lookup(access_config, "nat_ip", null) + network_tier = lookup(access_config, "network_tier", null) + } + } + network_ip = var.network_ip + subnetwork_project = var.subnetwork_project == "" ? var.project : var.subnetwork_project } - can_ip_forward = "${var.can_ip_forward}" + can_ip_forward = var.can_ip_forward disk { - auto_delete = "${var.disk_auto_delete}" + auto_delete = var.disk_auto_delete boot = true - source_image = "${var.compute_image}" + source_image = var.compute_image type = "PERSISTENT" - disk_type = "${var.disk_type}" - disk_size_gb = "${var.disk_size_gb}" - mode = "${var.mode}" + disk_type = var.disk_type + disk_size_gb = var.disk_size_gb + mode = var.mode } service_account { - email = "${var.service_account_email}" - scopes = ["${var.service_account_scopes}"] + email = var.service_account_email + scopes = var.service_account_scopes } - metadata = "${merge( - map("startup-script", "${var.startup_script}", "tf_depends_id", "${var.depends_id}"), - var.metadata - )}" + metadata = merge( + { + "startup-script" = var.startup_script + "tf_depends_id" = var.depends_id + }, + var.metadata, + ) scheduling { - preemptible = "${var.preemptible}" - automatic_restart = "${var.automatic_restart}" + preemptible = var.preemptible + automatic_restart = var.automatic_restart } lifecycle { @@ -72,217 +95,351 @@ provider "google-beta" { } resource "google_compute_instance_group_manager" "default" { - provider = "google-beta" - count = "${var.module_enabled && var.zonal ? 1 : 0}" - project = "${var.project}" - name = "${var.name}" + provider = google-beta + count = var.module_enabled && var.zonal ? 1 : 0 + project = var.project + name = var.name description = "compute VM Instance Group" - wait_for_instances = "${var.wait_for_instances}" + wait_for_instances = var.wait_for_instances - base_instance_name = "${var.name}" + base_instance_name = var.name version { name = "${var.name}-default" - instance_template = "${google_compute_instance_template.default.self_link}" + instance_template = google_compute_instance_template.default[0].self_link } - zone = "${var.zone}" - - update_policy = "${var.update_policy}" + zone = var.zone + + dynamic "update_policy" { + for_each = var.update_policy + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE, VERIFIED THE KEYS + max_surge_fixed = lookup(update_policy.value, "max_surge_fixed", null) + max_surge_percent = lookup(update_policy.value, "max_surge_percent", null) + max_unavailable_fixed = lookup(update_policy.value, "max_unavailable_fixed", null) + max_unavailable_percent = lookup(update_policy.value, "max_unavailable_percent", null) + min_ready_sec = lookup(update_policy.value, "min_ready_sec", null) + minimal_action = update_policy.value.minimal_action + type = update_policy.value.type + } + } - target_pools = ["${var.target_pools}"] + target_pools = var.target_pools // There is no way to unset target_size when autoscaling is true so for now, jsut use the min_replicas value. // Issue: https://github.com/terraform-providers/terraform-provider-google/issues/667 - target_size = "${var.autoscaling ? var.min_replicas : var.size}" + target_size = var.autoscaling ? var.min_replicas : var.size named_port { - name = "${var.service_port_name}" - port = "${var.service_port}" + name = var.service_port_name + port = var.service_port } - auto_healing_policies = { - health_check = "${var.http_health_check ? element(concat(google_compute_health_check.mig-health-check.*.self_link, list("")), 0) : ""}" - initial_delay_sec = "${var.hc_initial_delay}" + auto_healing_policies { + health_check = var.http_health_check ? element( + concat( + google_compute_health_check.mig-health-check.*.self_link, + [""], + ), + 0, + ) : "" + initial_delay_sec = var.hc_initial_delay } provisioner "local-exec" { - when = "destroy" - command = "${var.local_cmd_destroy}" + when = destroy + command = ":" } provisioner "local-exec" { - when = "create" - command = "${var.local_cmd_create}" + when = create + command = var.local_cmd_create } } resource "google_compute_autoscaler" "default" { - count = "${var.module_enabled && var.autoscaling && var.zonal ? 1 : 0}" - name = "${var.name}" - zone = "${var.zone}" - project = "${var.project}" - target = "${google_compute_instance_group_manager.default.self_link}" - - autoscaling_policy = { - max_replicas = "${var.max_replicas}" - min_replicas = "${var.min_replicas}" - cooldown_period = "${var.cooldown_period}" - cpu_utilization = ["${var.autoscaling_cpu}"] - metric = ["${var.autoscaling_metric}"] - load_balancing_utilization = ["${var.autoscaling_lb}"] + count = var.module_enabled && var.autoscaling && var.zonal ? 1 : 0 + name = var.name + zone = var.zone + project = var.project + target = google_compute_instance_group_manager.default[0].self_link + + autoscaling_policy { + max_replicas = var.max_replicas + min_replicas = var.min_replicas + cooldown_period = var.cooldown_period + dynamic "cpu_utilization" { + for_each = var.autoscaling_cpu + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE, AUTOSCALING IS OFF FOR NAT GATEWAYS + target = cpu_utilization.value.target + } + } + dynamic "metric" { + for_each = var.autoscaling_metric + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE VERIFIED THIS IN GUI + name = metric.value.name + target = lookup(metric.value, "target", null) + type = lookup(metric.value, "type", null) + } + } + dynamic "load_balancing_utilization" { + for_each = var.autoscaling_lb + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE + target = load_balancing_utilization.value.target + } + } } } data "google_compute_zones" "available" { - project = "${var.project}" - region = "${var.region}" + project = var.project + region = var.region } locals { distribution_zones = { - default = ["${data.google_compute_zones.available.names}"] - user = ["${var.distribution_policy_zones}"] + default = [data.google_compute_zones.available.names] + user = [var.distribution_policy_zones] } - dependency_id = "${element(concat(null_resource.region_dummy_dependency.*.id, list("disabled")), 0)}" + dependency_id = element( + concat(null_resource.region_dummy_dependency.*.id, ["disabled"]), + 0, + ) } resource "google_compute_region_instance_group_manager" "default" { - count = "${var.module_enabled && ! var.zonal ? 1 : 0}" - project = "${var.project}" - name = "${var.name}" + count = var.module_enabled && false == var.zonal ? 1 : 0 + project = var.project + name = var.name description = "compute VM Instance Group" - wait_for_instances = "${var.wait_for_instances}" - - base_instance_name = "${var.name}" - - instance_template = "${google_compute_instance_template.default.self_link}" - - region = "${var.region}" - - update_policy = "${var.update_policy}" + wait_for_instances = var.wait_for_instances + + base_instance_name = var.name + + instance_template = google_compute_instance_template.default[0].self_link + + region = var.region + + dynamic "update_policy" { + for_each = var.update_policy + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE, verified all keys in terraform.io + type = update_policy.value.type + instance_redistribution_type = lookup(update_policy.value, "instance_redistribution_type", null) + minimal_action = update_policy.value.minimal_action + max_surge_fixed = lookup(update_policy.value, "max_surge_fixed", null) + max_surge_percent = lookup(update_policy.value, "max_surge_percent", null) + max_unavailable_fixed = lookup(update_policy.value, "max_unavailable_fixed", null) + max_unavailable_percent = lookup(update_policy.value, "max_unavailable_percent", null) + min_ready_sec = lookup(update_policy.value, "min_ready_sec", null) + } + } - distribution_policy_zones = ["${local.distribution_zones["${length(var.distribution_policy_zones) == 0 ? "default" : "user"}"]}"] + # TF-UPGRADE-TODO: In Terraform v0.10 and earlier, it was sometimes necessary to + # force an interpolation expression to be interpreted as a list by wrapping it + # in an extra set of list brackets. That form was supported for compatibility in + # v0.11, but is no longer supported in Terraform v0.12. + # + # If the expression in the following list itself returns a list, remove the + # brackets to avoid interpretation as a list of lists. If the expression + # returns a single list item then leave it as-is and remove this TODO comment. + # DONE, this should be list due to it's functionality of managing multiple zones + distribution_policy_zones = local.distribution_zones[length(var.distribution_policy_zones) == 0 ? "default" : "user"] - target_pools = ["${var.target_pools}"] + target_pools = var.target_pools // There is no way to unset target_size when autoscaling is true so for now, jsut use the min_replicas value. // Issue: https://github.com/terraform-providers/terraform-provider-google/issues/667 - target_size = "${var.autoscaling ? var.min_replicas : var.size}" + target_size = var.autoscaling ? var.min_replicas : var.size auto_healing_policies { - health_check = "${var.http_health_check ? element(concat(google_compute_health_check.mig-health-check.*.self_link, list("")), 0) : ""}" - initial_delay_sec = "${var.hc_initial_delay}" + health_check = var.http_health_check ? element( + concat( + google_compute_health_check.mig-health-check.*.self_link, + [""], + ), + 0, + ) : "" + initial_delay_sec = var.hc_initial_delay } named_port { - name = "${var.service_port_name}" - port = "${var.service_port}" + name = var.service_port_name + port = var.service_port } provisioner "local-exec" { - when = "destroy" - command = "${var.local_cmd_destroy}" + when = destroy + command = ":" } provisioner "local-exec" { - when = "create" - command = "${var.local_cmd_create}" + when = create + command = var.local_cmd_create } // Initial instance verification can take 10-15m when a health check is present. - timeouts = { - create = "${var.http_health_check ? "15m" : "5m"}" + timeouts { + create = var.http_health_check ? "15m" : "5m" } } resource "google_compute_region_autoscaler" "default" { - count = "${var.module_enabled && var.autoscaling && ! var.zonal ? 1 : 0}" - name = "${var.name}" - region = "${var.region}" - project = "${var.project}" - target = "${google_compute_region_instance_group_manager.default.self_link}" - - autoscaling_policy = { - max_replicas = "${var.max_replicas}" - min_replicas = "${var.min_replicas}" - cooldown_period = "${var.cooldown_period}" - cpu_utilization = ["${var.autoscaling_cpu}"] - metric = ["${var.autoscaling_metric}"] - load_balancing_utilization = ["${var.autoscaling_lb}"] + count = var.module_enabled && var.autoscaling && false == var.zonal ? 1 : 0 + name = var.name + region = var.region + project = var.project + target = google_compute_region_instance_group_manager.default[0].self_link + + autoscaling_policy { + max_replicas = var.max_replicas + min_replicas = var.min_replicas + cooldown_period = var.cooldown_period + dynamic "cpu_utilization" { + for_each = var.autoscaling_cpu + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE, ONLY TARGET IS REQUIRED + target = cpu_utilization.value.target + } + } + dynamic "metric" { + for_each = var.autoscaling_metric + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE, VERIFIED REQUIRED AND OPTIONAL + name = metric.value.name + target = lookup(metric.value, "target", null) + type = lookup(metric.value, "type", null) + } + } + dynamic "load_balancing_utilization" { + for_each = var.autoscaling_lb + content { + # TF-UPGRADE-TODO: The automatic upgrade tool can't predict + # which keys might be set in maps assigned here, so it has + # produced a comprehensive set here. Consider simplifying + # this after confirming which keys can be set in practice. + # DONE + target = load_balancing_utilization.value.target + } + } } } resource "null_resource" "dummy_dependency" { - count = "${var.module_enabled && var.zonal ? 1 : 0}" - depends_on = ["google_compute_instance_group_manager.default"] + count = var.module_enabled && var.zonal ? 1 : 0 + depends_on = [google_compute_instance_group_manager.default] triggers = { - instance_template = "${element(google_compute_instance_template.default.*.self_link, 0)}" + instance_template = element(google_compute_instance_template.default.*.self_link, 0) } } resource "null_resource" "region_dummy_dependency" { - count = "${var.module_enabled && ! var.zonal ? 1 : 0}" - depends_on = ["google_compute_region_instance_group_manager.default"] + count = var.module_enabled && false == var.zonal ? 1 : 0 + depends_on = [google_compute_region_instance_group_manager.default] triggers = { - instance_template = "${element(google_compute_instance_template.default.*.self_link, 0)}" + instance_template = element(google_compute_instance_template.default.*.self_link, 0) } } resource "google_compute_firewall" "default-ssh" { - count = "${var.module_enabled && var.ssh_fw_rule ? 1 : 0}" - project = "${var.subnetwork_project == "" ? var.project : var.subnetwork_project}" + count = var.module_enabled && var.ssh_fw_rule ? 1 : 0 + project = var.subnetwork_project == "" ? var.project : var.subnetwork_project name = "${var.name}-vm-ssh" - network = "${var.network}" + network = var.network allow { protocol = "tcp" ports = ["22"] } - source_ranges = ["${var.ssh_source_ranges}"] + source_ranges = var.ssh_source_ranges target_tags = ["allow-ssh"] } resource "google_compute_health_check" "mig-health-check" { - count = "${var.module_enabled && var.http_health_check ? 1 : 0}" - name = "${var.name}" - project = "${var.project}" + count = var.module_enabled && var.http_health_check ? 1 : 0 + name = var.name + project = var.project - check_interval_sec = "${var.hc_interval}" - timeout_sec = "${var.hc_timeout}" - healthy_threshold = "${var.hc_healthy_threshold}" - unhealthy_threshold = "${var.hc_unhealthy_threshold}" + check_interval_sec = var.hc_interval + timeout_sec = var.hc_timeout + healthy_threshold = var.hc_healthy_threshold + unhealthy_threshold = var.hc_unhealthy_threshold http_health_check { - port = "${var.hc_port == "" ? var.service_port : var.hc_port}" - request_path = "${var.hc_path}" + port = var.hc_port == "" ? var.service_port : var.hc_port + request_path = var.hc_path } } resource "google_compute_firewall" "mig-health-check" { - count = "${var.module_enabled && var.http_health_check ? 1 : 0}" - project = "${var.subnetwork_project == "" ? var.project : var.subnetwork_project}" + count = var.module_enabled && var.http_health_check ? 1 : 0 + project = var.subnetwork_project == "" ? var.project : var.subnetwork_project name = "${var.name}-vm-hc" - network = "${var.network}" + network = var.network allow { protocol = "tcp" - ports = ["${var.hc_port == "" ? var.service_port : var.hc_port}"] + ports = [var.hc_port == "" ? var.service_port : var.hc_port] } source_ranges = ["130.211.0.0/22", "35.191.0.0/16"] - target_tags = ["${var.target_tags}"] + target_tags = var.target_tags } data "google_compute_instance_group" "zonal" { - count = "${var.zonal ? 1 : 0}" - zone = "${var.zone}" - project = "${var.project}" + count = var.zonal ? 1 : 0 + zone = var.zone + project = var.project // Use the dependency id which is recreated whenever the instance template changes to signal when to re-read the data source. - name = "${element(split("|", "${local.dependency_id}|${element(concat(google_compute_instance_group_manager.default.*.name, list("unused")), 0)}"), 1)}" -} \ No newline at end of file + name = element( + split( + "|", + "${local.dependency_id}|${element( + concat( + google_compute_instance_group_manager.default.*.name, + ["unused"], + ), + 0, + )}", + ), + 1, + ) +} + diff --git a/outputs.tf b/outputs.tf index 7a38f54..fce3554 100644 --- a/outputs.tf +++ b/outputs.tf @@ -14,62 +14,81 @@ * limitations under the License. */ -output name { +output "name" { description = "Pass through of input `name`." - value = "${var.name}" + value = var.name } -output instance_template { +output "instance_template" { description = "Link to the instance_template for the group" - value = "${google_compute_instance_template.default.*.self_link}" + value = google_compute_instance_template.default.*.self_link } -output instance_group { +output "instance_group" { description = "Link to the `instance_group` property of the instance group manager resource." - value = "${element(concat(google_compute_instance_group_manager.default.*.instance_group, list("")), 0)}" + value = element( + concat( + google_compute_instance_group_manager.default.*.instance_group, + [""], + ), + 0, + ) } -output instances { +output "instances" { description = "List of instances in the instance group. Note that this can change dynamically depending on the current number of instances in the group and may be empty the first time read." - value = "${data.google_compute_instance_group.zonal.*.instances}" + value = data.google_compute_instance_group.zonal.*.instances } -output region_instance_group { +output "region_instance_group" { description = "Link to the `instance_group` property of the region instance group manager resource." - value = "${element(concat(google_compute_region_instance_group_manager.default.*.instance_group, list("")), 0)}" + value = element( + concat( + google_compute_region_instance_group_manager.default.*.instance_group, + [""], + ), + 0, + ) } -output target_tags { +output "target_tags" { description = "Pass through of input `target_tags`." - value = "${var.target_tags}" + value = var.target_tags } -output service_port { +output "service_port" { description = "Pass through of input `service_port`." - value = "${var.service_port}" + value = var.service_port } -output service_port_name { +output "service_port_name" { description = "Pass through of input `service_port_name`." - value = "${var.service_port_name}" + value = var.service_port_name } -output depends_id { +output "depends_id" { description = "Id of the dummy dependency created used for intra-module dependency creation with zonal groups." - value = "${element(concat(null_resource.dummy_dependency.*.id, list("")), 0)}" + value = element(concat(null_resource.dummy_dependency.*.id, [""]), 0) } -output region_depends_id { +output "region_depends_id" { description = "Id of the dummy dependency created used for intra-module dependency creation with regional groups." - value = "${element(concat(null_resource.region_dummy_dependency.*.id, list("")), 0)}" + value = element(concat(null_resource.region_dummy_dependency.*.id, [""]), 0) } -output network_ip { +output "network_ip" { description = "Pass through of input `network_ip`." - value = "${var.network_ip}" + value = var.network_ip } -output health_check { +output "health_check" { description = "The healthcheck for the managed instance group" - value = "${element(concat(google_compute_health_check.mig-health-check.*.self_link, list("")), 0)}" -} \ No newline at end of file + value = element( + concat( + google_compute_health_check.mig-health-check.*.self_link, + [""], + ), + 0, + ) +} + diff --git a/variables.tf b/variables.tf index 25defcb..3b5af07 100644 --- a/variables.tf +++ b/variables.tf @@ -14,150 +14,142 @@ * limitations under the License. */ -variable module_enabled { +variable "module_enabled" { description = "" default = true } -variable project { +variable "project" { description = "The project to deploy to, if not set the default provider project is used." default = "" } -variable region { +variable "region" { description = "Region for cloud resources." default = "us-central1" } -variable zone { +variable "zone" { description = "Zone for managed instance groups." default = "us-central1-f" } -variable network { +variable "network" { description = "Name of the network to deploy instances to." default = "default" } -variable subnetwork { +variable "subnetwork" { description = "The subnetwork to deploy to" default = "default" } -variable subnetwork_project { +variable "subnetwork_project" { description = "The project the subnetwork belongs to. If not set, var.project is used instead." default = "" } -variable name { +variable "name" { description = "Name of the managed instance group." } -variable size { +variable "size" { description = "Target size of the managed instance group." default = 1 } -variable startup_script { +variable "startup_script" { description = "Content of startup-script metadata passed to the instance template." default = "" } -variable access_config { +variable "access_config" { description = "The access config block for the instances. Set to [] to remove external IP." - type = "list" - - default = [ - {}, - ] + type = list(string) + default = [] } -variable metadata { +variable "metadata" { description = "Map of metadata values to pass to instances." - type = "map" + type = map(string) default = {} } -variable can_ip_forward { +variable "can_ip_forward" { description = "Allow ip forwarding." default = false } -variable network_ip { +variable "network_ip" { description = "Set the network IP of the instance in the template. Useful for instance groups of size 1." default = "" } -variable machine_type { +variable "machine_type" { description = "Machine type for the VMs in the instance group." default = "f1-micro" } -variable compute_image { +variable "compute_image" { description = "Image used for compute VMs." default = "projects/debian-cloud/global/images/family/debian-9" } -variable wait_for_instances { +variable "wait_for_instances" { description = "Wait for all instances to be created/updated before returning" default = false } -variable update_policy { +variable "update_policy" { description = "The upgrade policy to apply when the instance template changes." - type = "list" + type = list(string) default = [] } -variable service_port { +variable "service_port" { description = "Port the service is listening on." } -variable service_port_name { +variable "service_port_name" { description = "Name of the port the service is listening on." } -variable target_tags { +variable "target_tags" { description = "Tag added to instances for firewall and networking." - type = "list" + type = list(string) default = ["allow-service"] } -variable instance_labels { +variable "instance_labels" { description = "Labels added to instances." - type = "map" + type = map(string) default = {} } -variable target_pools { +variable "target_pools" { description = "The target load balancing pools to assign this group to." - type = "list" + type = list(string) default = [] } -variable depends_id { +variable "depends_id" { description = "The ID of a resource that the instance group depends on." default = "" } -variable local_cmd_create { +variable "local_cmd_create" { description = "Command to run on create as local-exec provisioner for the instance group manager." default = ":" } -variable local_cmd_destroy { - description = "Command to run on destroy as local-exec provisioner for the instance group manager." - default = ":" -} - -variable service_account_email { +variable "service_account_email" { description = "The email of the service account for the instance template." default = "default" } -variable service_account_scopes { +variable "service_account_scopes" { description = "List of scopes for the instance template service account" - type = "list" + type = list(string) default = [ "https://www.googleapis.com/auth/compute", @@ -167,39 +159,39 @@ variable service_account_scopes { ] } -variable zonal { +variable "zonal" { description = "Create a single-zone managed instance group. If false, a regional managed instance group is created." default = true } -variable distribution_policy_zones { +variable "distribution_policy_zones" { description = "The distribution policy for this managed instance group when zonal=false. Default is all zones in given region." - type = "list" + type = list(string) default = [] } -variable ssh_source_ranges { +variable "ssh_source_ranges" { description = "Network ranges to allow SSH from" - type = "list" + type = list(string) default = ["0.0.0.0/0"] } -variable disk_auto_delete { +variable "disk_auto_delete" { description = "Whether or not the disk should be auto-deleted." default = true } -variable disk_type { +variable "disk_type" { description = "The GCE disk type. Can be either pd-ssd, local-ssd, or pd-standard." default = "pd-ssd" } -variable disk_size_gb { +variable "disk_size_gb" { description = "The size of the image in gigabytes. If not specified, it will inherit the size of its base image." default = 0 } -variable mode { +variable "mode" { description = "The mode in which to attach this disk, either READ_WRITE or READ_ONLY." default = "READ_WRITE" } @@ -215,86 +207,91 @@ variable "automatic_restart" { } /* Autoscaling */ -variable autoscaling { +variable "autoscaling" { description = "Enable autoscaling." default = false } -variable max_replicas { +variable "max_replicas" { description = "Autoscaling, max replicas." default = 5 } -variable min_replicas { +variable "min_replicas" { description = "Autoscaling, min replics." default = 1 } -variable cooldown_period { +variable "cooldown_period" { description = "Autoscaling, cooldown period in seconds." default = 60 } -variable autoscaling_cpu { +variable "autoscaling_cpu" { description = "Autoscaling, cpu utilization policy block as single element array. https://www.terraform.io/docs/providers/google/r/compute_autoscaler.html#cpu_utilization" - type = "list" + type = list(map(number)) default = [] } -variable autoscaling_metric { +variable "autoscaling_metric" { description = "Autoscaling, metric policy block as single element array. https://www.terraform.io/docs/providers/google/r/compute_autoscaler.html#metric" - type = "list" - default = [] + type = list(object({ + name = string + target = number + type = string + })) + default = [] } -variable autoscaling_lb { +variable "autoscaling_lb" { description = "Autoscaling, load balancing utilization policy block as single element array. https://www.terraform.io/docs/providers/google/r/compute_autoscaler.html#load_balancing_utilization" - type = "list" + type = list(map(number)) default = [] } /* Health checks */ -variable http_health_check { +variable "http_health_check" { description = "Enable or disable the http health check for auto healing." default = true } -variable hc_initial_delay { +variable "hc_initial_delay" { description = "Health check, intial delay in seconds." default = 30 } -variable hc_interval { +variable "hc_interval" { description = "Health check, check interval in seconds." default = 30 } -variable hc_timeout { +variable "hc_timeout" { description = "Health check, timeout in seconds." default = 10 } -variable hc_healthy_threshold { +variable "hc_healthy_threshold" { description = "Health check, healthy threshold." default = 1 } -variable hc_unhealthy_threshold { +variable "hc_unhealthy_threshold" { description = "Health check, unhealthy threshold." default = 10 } -variable hc_port { +variable "hc_port" { description = "Health check, health check port, if different from var.service_port, if not given, var.service_port is used." default = "" } -variable hc_path { +variable "hc_path" { description = "Health check, the http path to check." default = "/" } -variable ssh_fw_rule { +variable "ssh_fw_rule" { description = "Whether or not the SSH Firewall Rule should be created" default = true -} \ No newline at end of file +} + From 8dda13cd4266bf7fcfe57531e174e8a08771c69d Mon Sep 17 00:00:00 2001 From: Lyly Louanghaksaphone Date: Wed, 15 Apr 2020 14:37:17 -0400 Subject: [PATCH 2/2] removed todo --- main.tf | 190 ++++++++++++++++++++++++--------------------------- variables.tf | 67 +++++++++++++++++- 2 files changed, 154 insertions(+), 103 deletions(-) diff --git a/main.tf b/main.tf index c14be02..2ff9d0a 100644 --- a/main.tf +++ b/main.tf @@ -14,27 +14,52 @@ * limitations under the License. */ -resource "google_compute_instance_template" "default" { - count = var.module_enabled ? 1 : 0 - project = var.project - name_prefix = "default-" +############### +# Data Sources +############### +data "google_compute_image" "image" { + project = var.source_image != "" ? var.source_image_project : "centos-cloud" + name = var.source_image != "" ? var.source_image : "centos-6-v20180716" +} + +data "google_compute_image" "image_family" { + project = var.source_image_family != "" ? var.source_image_project : "centos-cloud" + family = var.source_image_family != "" ? var.source_image_family : "centos-6" +} - machine_type = var.machine_type +######### +# Locals +######### + +locals { + boot_disk = [ + { + source_image = var.source_image != "" ? data.google_compute_image.image.self_link : data.google_compute_image.image_family.self_link + disk_size_gb = var.disk_size_gb + disk_type = var.disk_type + auto_delete = var.auto_delete + boot = "true" + }, + ] - region = var.region + all_disks = concat(local.boot_disk, var.additional_disks) - # TF-UPGRADE-TODO: In Terraform v0.10 and earlier, it was sometimes necessary to - # force an interpolation expression to be interpreted as a list by wrapping it - # in an extra set of list brackets. That form was supported for compatibility in - # v0.11, but is no longer supported in Terraform v0.12. - # - # If the expression in the following list itself returns a list, remove the - # brackets to avoid interpretation as a list of lists. If the expression - # returns a single list item then leave it as-is and remove this TODO comment. - # DONE, removed the extra bracket due to the network tags returning a list - tags = concat(["allow-ssh"], var.target_tags) + # NOTE: Even if all the shielded_instance_config values are false, if the + # config block exists and an unsupported image is chosen, the apply will fail + # so we use a single-value array with the default value to initialize the block + # only if it is enabled. + shielded_vm_configs = var.enable_shielded_vm ? [true] : [] +} - labels = var.instance_labels +resource "google_compute_instance_template" "default" { + count = var.module_enabled ? 1 : 0 + name_prefix = "default-" + project = var.project + machine_type = var.machine_type + labels = var.instance_labels + tags = concat(["allow-ssh"], var.target_tags) + can_ip_forward = var.can_ip_forward + region = var.region network_interface { network = var.subnetwork == "" ? var.network : "" @@ -42,34 +67,44 @@ resource "google_compute_instance_template" "default" { dynamic "access_config" { for_each = var.access_config content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE - nat_ip = lookup(access_config, "nat_ip", null) - network_tier = lookup(access_config, "network_tier", null) + nat_ip = access_config.value.nat_ip + network_tier = access_config.value.network_tier } } network_ip = var.network_ip subnetwork_project = var.subnetwork_project == "" ? var.project : var.subnetwork_project } - can_ip_forward = var.can_ip_forward - - disk { - auto_delete = var.disk_auto_delete - boot = true - source_image = var.compute_image - type = "PERSISTENT" - disk_type = var.disk_type - disk_size_gb = var.disk_size_gb - mode = var.mode + dynamic "disk" { + for_each = local.all_disks + content { + auto_delete = lookup(disk.value, "auto_delete", null) + boot = lookup(disk.value, "boot", null) + device_name = lookup(disk.value, "device_name", null) + disk_name = lookup(disk.value, "disk_name", null) + disk_size_gb = lookup(disk.value, "disk_size_gb", null) + disk_type = lookup(disk.value, "disk_type", null) + interface = lookup(disk.value, "interface", null) + mode = lookup(disk.value, "mode", null) + source = lookup(disk.value, "source", null) + source_image = lookup(disk.value, "source_image", null) + type = lookup(disk.value, "type", null) + + dynamic "disk_encryption_key" { + for_each = lookup(disk.value, "disk_encryption_key", []) + content { + kms_key_self_link = lookup(disk_encryption_key.value, "kms_key_self_link", null) + } + } + } } - service_account { - email = var.service_account_email - scopes = var.service_account_scopes + dynamic "service_account" { + for_each = [var.service_account] + content { + email = lookup(service_account.value, "email", null) + scopes = lookup(service_account.value, "scopes", null) + } } metadata = merge( @@ -80,14 +115,24 @@ resource "google_compute_instance_template" "default" { var.metadata, ) + # scheduling must have automatic_restart be false when preemptible is true. scheduling { preemptible = var.preemptible - automatic_restart = var.automatic_restart + automatic_restart = ! var.preemptible } lifecycle { create_before_destroy = true } + + dynamic "shielded_instance_config" { + for_each = local.shielded_vm_configs + content { + enable_secure_boot = lookup(var.shielded_instance_config, "enable_secure_boot", shielded_instance_config.value) + enable_vtpm = lookup(var.shielded_instance_config, "enable_vtpm", shielded_instance_config.value) + enable_integrity_monitoring = lookup(var.shielded_instance_config, "enable_integrity_monitoring", shielded_instance_config.value) + } + } } provider "google-beta" { @@ -114,11 +159,6 @@ resource "google_compute_instance_group_manager" "default" { dynamic "update_policy" { for_each = var.update_policy content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE, VERIFIED THE KEYS max_surge_fixed = lookup(update_policy.value, "max_surge_fixed", null) max_surge_percent = lookup(update_policy.value, "max_surge_percent", null) max_unavailable_fixed = lookup(update_policy.value, "max_unavailable_fixed", null) @@ -130,10 +170,7 @@ resource "google_compute_instance_group_manager" "default" { } target_pools = var.target_pools - - // There is no way to unset target_size when autoscaling is true so for now, jsut use the min_replicas value. - // Issue: https://github.com/terraform-providers/terraform-provider-google/issues/667 - target_size = var.autoscaling ? var.min_replicas : var.size + target_size = var.autoscaling ? var.min_replicas : var.size named_port { name = var.service_port_name @@ -176,22 +213,12 @@ resource "google_compute_autoscaler" "default" { dynamic "cpu_utilization" { for_each = var.autoscaling_cpu content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE, AUTOSCALING IS OFF FOR NAT GATEWAYS target = cpu_utilization.value.target } } dynamic "metric" { for_each = var.autoscaling_metric content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE VERIFIED THIS IN GUI name = metric.value.name target = lookup(metric.value, "target", null) type = lookup(metric.value, "type", null) @@ -200,11 +227,6 @@ resource "google_compute_autoscaler" "default" { dynamic "load_balancing_utilization" { for_each = var.autoscaling_lb content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE target = load_balancing_utilization.value.target } } @@ -234,24 +256,19 @@ resource "google_compute_region_instance_group_manager" "default" { name = var.name description = "compute VM Instance Group" wait_for_instances = var.wait_for_instances - base_instance_name = var.name + region = var.region - instance_template = google_compute_instance_template.default[0].self_link - - region = var.region + version { + instance_template = google_compute_instance_template.default[0].self_link + } dynamic "update_policy" { for_each = var.update_policy content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE, verified all keys in terraform.io + minimal_action = update_policy.value.minimal_action type = update_policy.value.type instance_redistribution_type = lookup(update_policy.value, "instance_redistribution_type", null) - minimal_action = update_policy.value.minimal_action max_surge_fixed = lookup(update_policy.value, "max_surge_fixed", null) max_surge_percent = lookup(update_policy.value, "max_surge_percent", null) max_unavailable_fixed = lookup(update_policy.value, "max_unavailable_fixed", null) @@ -260,22 +277,10 @@ resource "google_compute_region_instance_group_manager" "default" { } } - # TF-UPGRADE-TODO: In Terraform v0.10 and earlier, it was sometimes necessary to - # force an interpolation expression to be interpreted as a list by wrapping it - # in an extra set of list brackets. That form was supported for compatibility in - # v0.11, but is no longer supported in Terraform v0.12. - # - # If the expression in the following list itself returns a list, remove the - # brackets to avoid interpretation as a list of lists. If the expression - # returns a single list item then leave it as-is and remove this TODO comment. - # DONE, this should be list due to it's functionality of managing multiple zones distribution_policy_zones = local.distribution_zones[length(var.distribution_policy_zones) == 0 ? "default" : "user"] target_pools = var.target_pools - - // There is no way to unset target_size when autoscaling is true so for now, jsut use the min_replicas value. - // Issue: https://github.com/terraform-providers/terraform-provider-google/issues/667 - target_size = var.autoscaling ? var.min_replicas : var.size + target_size = var.autoscaling ? var.min_replicas : var.size auto_healing_policies { health_check = var.http_health_check ? element( @@ -323,22 +328,12 @@ resource "google_compute_region_autoscaler" "default" { dynamic "cpu_utilization" { for_each = var.autoscaling_cpu content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE, ONLY TARGET IS REQUIRED target = cpu_utilization.value.target } } dynamic "metric" { for_each = var.autoscaling_metric content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE, VERIFIED REQUIRED AND OPTIONAL name = metric.value.name target = lookup(metric.value, "target", null) type = lookup(metric.value, "type", null) @@ -347,11 +342,6 @@ resource "google_compute_region_autoscaler" "default" { dynamic "load_balancing_utilization" { for_each = var.autoscaling_lb content { - # TF-UPGRADE-TODO: The automatic upgrade tool can't predict - # which keys might be set in maps assigned here, so it has - # produced a comprehensive set here. Consider simplifying - # this after confirming which keys can be set in practice. - # DONE target = load_balancing_utilization.value.target } } diff --git a/variables.tf b/variables.tf index 3b5af07..6bcf3c7 100644 --- a/variables.tf +++ b/variables.tf @@ -142,6 +142,18 @@ variable "local_cmd_create" { default = ":" } +################## +# service_account +################## + +variable "service_account" { + 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.html#service_account." +} + variable "service_account_email" { description = "The email of the service account for the instance template." default = "default" @@ -159,6 +171,29 @@ variable "service_account_scopes" { ] } +########################### +# Shielded VMs +########################### +variable "enable_shielded_vm" { + default = false + description = "Whether to enable the Shielded VM configuration on the instance. Note that the instance image must support Shielded VMs. See https://cloud.google.com/compute/docs/images" +} + +variable "shielded_instance_config" { + description = "Not used unless enable_shielded_vm is true. Shielded VM configuration for the instance." + type = object({ + enable_secure_boot = bool + enable_vtpm = bool + enable_integrity_monitoring = bool + }) + + default = { + enable_secure_boot = true + enable_vtpm = true + enable_integrity_monitoring = true + } +} + variable "zonal" { description = "Create a single-zone managed instance group. If false, a regional managed instance group is created." default = true @@ -176,9 +211,35 @@ variable "ssh_source_ranges" { default = ["0.0.0.0/0"] } -variable "disk_auto_delete" { - description = "Whether or not the disk should be auto-deleted." - default = true +variable "source_image" { + description = "Source disk image. If neither source_image nor source_image_family is specified, defaults to the latest public CentOS image." + default = "" +} + +variable "source_image_family" { + description = "Source image family. If neither source_image nor source_image_family is specified, defaults to the latest public CentOS image." + default = "centos-7" +} + +variable "source_image_project" { + description = "Project where the source image comes from. The default project contains images that support Shielded VMs if desired" + default = "gce-uefi-images" +} + +variable "auto_delete" { + description = "Whether or not the boot disk should be auto-deleted" + default = "true" +} + +variable "additional_disks" { + description = "List of maps of additional disks. See https://www.terraform.io/docs/providers/google/r/compute_instance_template.html#disk_name" + type = list(object({ + auto_delete = bool + boot = bool + disk_size_gb = number + disk_type = string + })) + default = [] } variable "disk_type" {