hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.33k stars 1.73k forks source link

google_compute_attached_disk seams to be not attached to the container volume #16132

Open jas1989 opened 1 year ago

jas1989 commented 1 year ago

Community Note

Terraform Version

Terraform v1.5.7 on linux_amd64

Affected Resource(s)

Terraform Configuration Files

variable "dev-app" {
  type = object({
    image_cloud: string,
    version: string,
    variables: map(string)
  })
}

locals {
  # https://www.terraform.io/docs/language/values/locals.html
  # instance_name = format("%s-%s", var.instance_name, substr(md5(module.gce-container.container.image), 0, 8))

  env_variables = [for var_name, var_value in var.dev-app.variables : {
    name = var_name
    value = var_value
  }]

  metadata_for_recreation_compute_engine_version = "${var.dev-app.version}"
  metadata_for_recreation_comupte_engine_variables = jsonencode(var.dev-app.variables)
}

resource "google_compute_disk" "pd" {
  project = var.project_name
  name    = "dev-app-data-disk"
  type    = "pd-ssd"
  zone    = var.zone_spec
  size    = 10
}

resource "google_compute_firewall" "http-access" {
  name    = "dev-app-http"
  project = var.project_name
  network = "default"

  allow {
    protocol = "tcp"
    ports    = [443]
  }

  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["dev-app-container-disk"]
}

module "gce-container" {
  # https://github.com/terraform-google-modules/terraform-google-container-vm
  source = "terraform-google-modules/container-vm/google"
  version = "3.1.0"

  container = {
    image = "${var.dev-app.image_cloud}:${var.dev-app.version}"
    custom_command = [
#      "sleep 10",
      "./scripts/start-worker.sh"
    ]
    env = local.env_variables

    volumeMounts = [
      {
        mountPath = "/cache"
        name      = "tempfs-0"
        readOnly  = false
      },
      {
        mountPath = "/persistent-data"
        name      = "${google_compute_disk.pd.name}"
        readOnly  = false
      },
    ]
  }

  volumes = [
    {
      name = "tempfs-0"

      emptyDir = {
        medium = "Memory"
      }
    },
    {
      name = "${google_compute_disk.pd.name}"

      gcePersistentDisk = {
        pdName = "${google_compute_disk.pd.name}"
        fsType = "ext4"
      }
    },
  ]

  restart_policy = "Always"
}

resource "google_compute_attached_disk" "attached_disk" {
  disk        = google_compute_disk.pd.name
  instance    = google_compute_instance.vm.name
  device_name = "additional-disk" # Nome del disco nella macchina virtuale
  mode        = "READ_WRITE"
  zone        = var.zone_spec

  depends_on = [ 
    google_compute_disk.pd,
    google_compute_instance.vm
  ]
}

resource "google_compute_instance" "vm" {
  name = "dev-app"
  machine_type = "e2-medium"
  zone    = "${var.zone_spec}"

  description = "metadata_for_recreation_compute_engine_version SHA512 hash (base64): ${base64sha512(local.metadata_for_recreation_compute_engine_version)}\nmetadata_for_recreation_compute_engine_variables SHA512 hash (base64): ${base64sha512(local.metadata_for_recreation_comupte_engine_variables)}"

  # If true, allows Terraform to stop the instance to update its properties.
  allow_stopping_for_update = true

  boot_disk {
    initialize_params {
      image = module.gce-container.source_image
    }
  }

  lifecycle {
    ignore_changes = [attached_disk]
  }

  network_interface {
    subnetwork_project = var.project_name
    subnetwork         = "default"
    access_config {
      nat_ip = google_compute_address.default.address
    }
  }

  metadata = {
    gce-container-declaration = module.gce-container.metadata_value
    metadata_for_recreation_compute_engine_version = local.metadata_for_recreation_compute_engine_version
    metadata_for_recreation_comupte_engine_variables = local.metadata_for_recreation_comupte_engine_variables
  }

  tags = ["dev-app-container", "dev-app-container-disk"]

  service_account {
    email = ""
    scopes = [
      "https://www.googleapis.com/auth/cloud-platform",
    ]
  }

  depends_on = [ 
    google_compute_disk.pd
  ]
}

output "app-compute-engine" {
  description = "App Compute Engine URL"
  value       = google_compute_instance.vm.self_link
}

Debug Output

Panic Output

Expected Behavior

  1. I expect that launching the terraform apply command will create it in order:
    • google_compute_disk
    • google_compute_instance
    • google_compute_attached_disk
  2. The terraform apply command is successful. From the Google console I see the disk mounted in read/write mode.
  3. The container on the VM starts with a disk attached

Actual Behavior

The container doesn't start due to this error:

Error: Failed to start container: Volume dev-app-data-disk: Could not determine if the GCE Persistent Disk dev-app-data-disk is attached read-only or read-write.

Steps to Reproduce

  1. terraform apply

Important Factoids

References

b/304967884

edwardmedia commented 1 year ago

@jas1989 can you share the debug log that contains all the api requests and responses?

Since you use module "gce-container" and we don't have much insight of it, are you able to reach out to its owner for help?

module "gce-container" {
   source = "terraform-google-modules/container-vm/google"
....
}

Help me to understand what you try to do?


resource "google_compute_instance" "vm" {
  name = "dev-app"
...
  boot_disk {
    initialize_params {
      image = module.gce-container.source_image
    }
  }
...
}
jas1989 commented 1 year ago

@edwardmedia, I've run terraform apply with the DEBUG log level for the logs, but it produced a large file containing some sensitive information, such as security certificate contents and the IP address of the VM, among other things. Do you know if there is another way to generate this kind of file?

As you suggested, I've opened an issue on the module's repository. It's likely more of an issue with this module rather than this repository.

Regarding the last questions, I came across information suggesting that it's beneficial to work with a Container-Optimized Image when running a container inside a GCP VM. I found a solution online that involves using the module mentioned before with the configuration I posted above. Unfortunately, I had to find a workaround to retain the information of the persistent disk because in the original setup, any changes to the VM parameters would cause it to restart, resulting in the destruction of the attached disk.

This is where the google_compute_attached_disk resource comes into play. Using it ensures that the disk isn't destroyed every time the VM is. However, a problem arises here. The containers aren't able to determine whether the attached disk is in read-only or read-write mode, and this error causes the containers to stop.