Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any equivalent in terraform to the gcloud compute instances create-with-container command?

I am trying to create an VM in Google Compute Engine which automatically runs a container that I uploaded to the Google Container Registry (as described here https://cloud.google.com/compute/docs/containers/deploying-containers#how_deploying_containers_on_works)

The

gcloud compute instances create-with-container [INSTANCE_NAME] \
     --container-image [DOCKER_IMAGE]

works so far, but I dont see any equivalent in Terraform.
From what I've seen google_compute_image is not what helps me.

like image 344
JSAN L. Avatar asked Nov 01 '25 07:11

JSAN L.


2 Answers

I used terraformer to reverse-terraform my compute engine instance instance-container that runs Nginx container.

Here's the result terraform file

resource "google_compute_instance" "tfer--instance-002D-container" {
  boot_disk {
    auto_delete = "true"
    device_name = "instance-container"

    initialize_params {
      image = "https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-stable-80-12739-91-0"
      size  = "10"
      type  = "pd-standard"
    }

    mode   = "READ_WRITE"
    source = "https://www.googleapis.com/compute/v1/projects/your-project-id/zones/asia-east1-b/disks/instance-container"
  }

  can_ip_forward      = "false"
  deletion_protection = "false"
  enable_display      = "false"

  labels = {
    container-vm = "cos-stable-80-12739-91-0"
  }

  machine_type = "g1-small"

  metadata = {
    gce-container-declaration = "spec:\n  containers:\n    - name: instance-container\n      image: nginx\n      stdin: false\n      tty: false\n  restartPolicy: Always\n\n# This container declaration format is not public API and may change without notice. Please\n# use gcloud command-line tool or Google Cloud Console to run Containers on Google Compute Engine."
    google-logging-enabled    = "true"
  }

  name = "instance-container"

  network_interface {
    access_config {
      nat_ip       = "104.199.164.22"
      network_tier = "PREMIUM"
    }

    name               = "nic0"
    network            = "https://www.googleapis.com/compute/v1/projects/your-project-id/global/networks/default"
    network_ip         = "10.140.15.223"
    subnetwork         = "https://www.googleapis.com/compute/v1/projects/your-project-id/regions/asia-east1/subnetworks/default"
    subnetwork_project = "your-project-id"
  }

  project = "your-project-id"

  scheduling {
    automatic_restart   = "true"
    on_host_maintenance = "MIGRATE"
    preemptible         = "false"
  }

  service_account {
    email  = "[email protected]"
    scopes = ["https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append", "https://www.googleapis.com/auth/devstorage.read_only"]
  }

  shielded_instance_config {
    enable_integrity_monitoring = "true"
    enable_secure_boot          = "false"
    enable_vtpm                 = "true"
  }

  zone = "asia-east1-b"
}

After comparing with normal instance resources, it looks like relies on the metadata gce-container-declaration and labels to do this job.

However, as the comments in the metadata said,

This container declaration format is not public API and may change without notice.

Please use gcloud command-line tool or Google Cloud Console to run Containers on Google Compute Engine.

It's more reliable to use gcloud command at this time before your issue be solved by Terraform Google Cloud Platform provider.

like image 151
Brent Chang Avatar answered Nov 03 '25 22:11

Brent Chang


There is a Terraform module that handles the generation of metadata for deploying containers on Google Compute Engine instances. It works similar to the command gcloud compute instances create-with-container.

You have to use the module along side with google_compute_instance resource and pass the attributes of the module to the resource, such as image, metadata and labels keys.

An example of usage.

# Module with metadata to create and start an instance with container. 
module "gce-container" {
  source = "terraform-google-modules/container-vm/google"
  version = "~> 2.0"  # Upgrade the version if necessary.

  container = {
    image = "gcr.io/google-samples/hello-app:1.0"
  }
}

# Compute instance with container.
resource "google_compute_instance" "default" {
  name         = "hello-app-instance"
  machine_type = "e2-micro"
  zone         = var.zone

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

  network_interface {
    network = var.network
    # To be accesible from internet.
    access_config {
        # Ephemeral public IP.
    }
  }

  tags = ["container-vm-example"]

  metadata = {
    # Required metadata key.
    gce-container-declaration = module.gce-container.metadata_value
    google-logging-enabled    = "true"
    google-monitoring-enabled = "true"
  }

  labels = {
    # Required label key.
    container-vm = module.gce-container.vm_container_label
  }

  # A service account.
  service_account {
    email = var.service_account_email
    # List copied from default scope.
    # https://cloud.google.com/sdk/gcloud/reference/alpha/compute/instances/set-scopes#--scopes
    scopes = [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring.write",
      "https://www.googleapis.com/auth/pubsub",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append"
    ]
  }
}

Some notes: unlike the command gcloud compute instances create-with-container, Terraform configuration will not add automatically

  • An external IP address. In the example above I've used a network_interface.access_config to auto generate it.
  • A default service account with default scope. In the example above I replicated the list of default scopes.
like image 36
vilozio Avatar answered Nov 03 '25 21:11

vilozio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!