-
Notifications
You must be signed in to change notification settings - Fork 91
Open
Labels
bugSomething isn't workingSomething isn't working
Description
TL;DR
When the bastion-host module is upgraded, resulting in a replacement of the GCE VM, after the first apply, the new instance is missing the IAP tunnel permissions. Running a second apply attaches the proper permissions to the host.
Expected behavior
I expect that a single apply will recreate the bastion host and attach all required permissions including IAP tunnel permissions.
Observed behavior
I need to apply twice in order to enable IAP tunnel permissions for the host.
First apply:
# module.devinfra-deployment-target[0].module.iap_bastion.google_compute_instance_from_template.bastion_vm[0] must be replaced
-/+ resource "google_compute_instance_from_template" "bastion_vm" {
+ allow_stopping_for_update = (known after apply)
~ can_ip_forward = false -> (known after apply)
~ cpu_platform = "Intel Broadwell" -> (known after apply)
~ creation_timestamp = "2024-10-23T06:06:49.389-07:00" -> (known after apply)
~ current_status = "RUNNING" -> (known after apply)
~ deletion_protection = false -> (known after apply)
+ description = (known after apply)
+ desired_status = (known after apply)
~ effective_labels = {
+ "goog-terraform-provisioned" = "true"
# (3 unchanged elements hidden)
}
~ enable_display = false -> (known after apply)
+ hostname = (known after apply)
~ id = "projects/***/zones/us-west1-c/instances/***" -> (known after apply)
~ instance_id = "8582050113197001223" -> (known after apply)
+ key_revocation_action_type = (known after apply)
~ label_fingerprint = "wUX_V1xtcys=" -> (known after apply)
~ machine_type = "e2-micro" -> (known after apply)
~ metadata = {
- "enable-oslogin" = "TRUE"
- "startup-script" = <<-EOT
systemctl enable --now tinyproxy || {
apt install -y --no-install-recommends tinyproxy
systemctl enable --now tinyproxy
}
EOT
} -> (known after apply)
~ metadata_fingerprint = "haQtoG1OvUc=" -> (known after apply)
+ metadata_startup_script = (known after apply)
+ min_cpu_platform = (known after apply)
name = "***"
~ resource_policies = [] -> (known after apply)
~ self_link = "https://www.googleapis.com/compute/v1/projects/***/zones/us-west1-c/instances/***" -> (known after apply)
~ source_instance_template = "https://www.googleapis.com/compute/v1/projects/***/global/instanceTemplates/bastion-instance-template-20241023130644287300000001" # forces replacement -> (known after apply) # forces replacement
~ tags = [
- "use-nat",
] -> (known after apply)
# (3 unchanged attributes hidden)
- boot_disk {
- auto_delete = true -> null
- device_name = "persistent-disk-0" -> null
- mode = "READ_WRITE" -> null
- source = "https://www.googleapis.com/compute/v1/projects/***/zones/us-west1-c/disks/***" -> null
- initialize_params {
- enable_confidential_compute = false -> null
- image = "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-12-bookworm-v20241009" -> null
- labels = {} -> null
- provisioned_iops = 0 -> null
- provisioned_throughput = 0 -> null
- resource_manager_tags = {} -> null
- resource_policies = [] -> null
- size = 10 -> null
- type = "pd-standard" -> null
}
}
~ network_interface {
~ internal_ipv6_prefix_length = 0 -> (known after apply)
+ ipv6_access_type = (known after apply)
+ ipv6_address = (known after apply)
~ name = "nic0" -> (known after apply)
~ network = "https://www.googleapis.com/compute/v1/projects/***/global/networks/***" -> (known after apply)
~ network_ip = "10.33.0.2" -> (known after apply)
+ nic_type = (known after apply)
~ queue_count = 0 -> (known after apply)
~ stack_type = "IPV4_ONLY" -> (known after apply)
# (2 unchanged attributes hidden)
}
- scheduling {
- automatic_restart = true -> null
- min_node_cpus = 0 -> null
- on_host_maintenance = "MIGRATE" -> null
- preemptible = false -> null
- provisioning_model = "STANDARD" -> null
}
- service_account {
- email = "dicd-sa-b8b86331f959ef4f@***.iam.gserviceaccount.com" -> null
- scopes = [
- "https://www.googleapis.com/auth/cloud-platform",
] -> null
}
- shielded_instance_config {
- enable_integrity_monitoring = true -> null
- enable_secure_boot = true -> null
- enable_vtpm = true -> null
}
}
# module.devinfra-deployment-target[0].module.iap_bastion.module.instance_template.google_compute_instance_template.tpl must be replaced
+/- resource "google_compute_instance_template" "tpl" {
~ creation_timestamp = "2024-10-23T06:06:45.264-07:00" -> (known after apply)
~ effective_labels = {
+ "goog-terraform-provisioned" = "true"
# (3 unchanged elements hidden)
}
~ id = "projects/***/global/instanceTemplates/bastion-instance-template-20241023130644287300000001" -> (known after apply)
~ metadata_fingerprint = "haQtoG1OvUc=" -> (known after apply)
~ name = "bastion-instance-template-20241023130644287300000001" -> (known after apply)
~ region = "us-west1" -> (known after apply)
+ resource_policies = []
~ self_link = "https://www.googleapis.com/compute/beta/projects/***/global/instanceTemplates/bastion-instance-template-20241023130644287300000001" -> (known after apply)
~ self_link_unique = "https://www.googleapis.com/compute/beta/projects/***/global/instanceTemplates/bastion-instance-template-20241023130644287300000001?uniqueId=6348214262220278283" -> (known after apply)
tags = [
"use-nat",
]
# (7 unchanged attributes hidden)
~ advanced_machine_features {
- threads_per_core = 0 -> null
- visible_core_count = 0 -> null
# (1 unchanged attribute hidden)
}
~ disk {
~ device_name = "persistent-disk-0" -> (known after apply)
~ interface = "SCSI" -> (known after apply)
- labels = {} -> null
~ mode = "READ_WRITE" -> (known after apply)
~ provisioned_iops = 0 -> (known after apply)
~ provisioned_throughput = 0 -> (known after apply)
- resource_manager_tags = {} -> null
~ source_image = "projects/debian-cloud/global/images/family/debian-12" -> "debian-cloud/debian-12"
# (6 unchanged attributes hidden)
}
~ network_interface {
~ internal_ipv6_prefix_length = 0 -> (known after apply)
+ ipv6_access_type = (known after apply)
+ ipv6_address = (known after apply)
~ name = "nic0" -> (known after apply)
- network = "https://www.googleapis.com/compute/v1/projects/***/global/networks/***" -> null
+ network_attachment = (known after apply)
- queue_count = 0 -> null
+ stack_type = (known after apply)
~ subnetwork_project = "***" -> (known after apply)
# (1 unchanged attribute hidden)
}
+ network_performance_config { # forces replacement
+ total_egress_bandwidth_tier = "DEFAULT" # forces replacement
}
~ scheduling {
- host_error_timeout_seconds = 0 -> null
- min_node_cpus = 0 -> null
~ provisioning_model = "STANDARD" -> (known after apply)
# (3 unchanged attributes hidden)
}
# (3 unchanged blocks hidden)
}
Plan: 2 to add, 1 to change, 2 to destroy.
Second apply:
# module.devinfra-deployment-target[0].module.iap_bastion.module.iap_tunneling.google_iap_tunnel_instance_iam_binding.enable_iap["*** us-west1-c"] will be updated in-place
~ resource "google_iap_tunnel_instance_iam_binding" "enable_iap" {
id = "projects/***/iap_tunnel/zones/us-west1-c/instances/***/roles/iap.tunnelResourceAccessor"
~ members = [
+ "serviceAccount:deploy-to-***@***.iam.gserviceaccount.com",
+ "serviceAccount:deploy-to-***@***.iam.gserviceaccount.com",
]
# (5 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
Terraform Configuration
The only change was updating the bastion module version from `~> 5.0.1` to `~> 8.0`.
## Before:
module "iap_bastion" {
source = "terraform-google-modules/bastion-host/google"
version = "~> 5.0.1"
name = local.name
project = var.project
network = var.network
subnet = var.subnetwork
zone = var.zone
tags = var.tags
labels = local.labels
image_family = "debian-12"
machine_type = "e2-micro"
disk_size_gb = 10
create_instance_from_template = var.create_instance_from_template
# Allows OS Login and IAP access to the bastion host.
members = var.deployment-members
# These just need to be unique if this parent module is to be repeated.
service_account_name = "dicd-sa-${random_id._.hex}"
fw_name_allow_ssh_from_iap = "dicd-rule-${random_id._.hex}"
# We're relying on the defaults - pretty much just the default
# port of 8888.
startup_script = <<EOT
systemctl enable --now tinyproxy || {
apt install -y --no-install-recommends tinyproxy
systemctl enable --now tinyproxy
}
EOT
}
After
module "iap_bastion" {
source = "terraform-google-modules/bastion-host/google"
version = "~> 8.0"
name = local.name
project = var.project
network = var.network
subnet = var.subnetwork
zone = var.zone
tags = var.tags
labels = local.labels
image_family = "debian-12"
machine_type = "e2-micro"
disk_size_gb = 10
create_instance_from_template = var.create_instance_from_template
# Allows OS Login and IAP access to the bastion host.
members = var.deployment-members
# These just need to be unique if this parent module is to be repeated.
service_account_name = "dicd-sa-${random_id._.hex}"
fw_name_allow_ssh_from_iap = "dicd-rule-${random_id._.hex}"
# We're relying on the defaults - pretty much just the default
# port of 8888.
startup_script = <<EOT
systemctl enable --now tinyproxy || {
apt install -y --no-install-recommends tinyproxy
systemctl enable --now tinyproxy
}
EOT
}
### Terraform Version
```sh
❯ tf version
Terraform v1.5.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/google v6.12.0
+ provider registry.terraform.io/hashicorp/google-beta v6.12.0
+ provider registry.terraform.io/hashicorp/random v3.1.3
### Additional information
_No response_
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working