Search code examples
dockergoogle-cloud-platformterraformgoogle-container-os

Can you run Docker containers in GCP via Terraform?


I have created a Docker image that I'd like to run in GCP using Terraform. I have tagged and pushed the image to GCR like this:

docker tag carlspring/hello-spring-boot:1.0 eu.gcr.io/${PROJECT_ID}/carlspring/hello-spring-boot:1.0
docker push eu.gcr.io/carlspring/carlspring/hello-spring-boot:1.0

I have the following code:

provider "google" {
  // Set this to CREDENTIALS
  credentials = file("credentials.json")

  // Set this to PROJECT_ID
  project = "carlspring"
  region  = "europe-west2"
  zone    = "europe-west2-a"
}

resource "google_compute_network" "vpc_network" {
  name = "carlspring-terraform-network"
}


resource "google_compute_instance" "docker" {
  count        = 1
  name         = "tf-docker-${count.index}"
  machine_type = "f1-micro"
  zone         = var.zone
  tags         = ["docker-node"]

  boot_disk {
    initialize_params {
      image = "carlspring/hello-spring-boot"
    }
  }
}

After doing:

terraform init
terraform plan
terraform apply

I get:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_instance.docker[0]: Creating...

Error: Error resolving image name 'carlspring/hello-spring-boot': Could not find image or family carlspring/hello-spring-boot

  on main.tf line 18, in resource "google_compute_instance" "docker":
  18: resource "google_compute_instance" "docker" {

The examples I've seen online are either using K8s, or starting a VM image running a Linux in which Docker is installed and an image is being started. Can't I just simply use my own container to start the instance?


Solution

  • google_compute_instance expects a VM image, not a Docker image. If you want to deploy Docker images to GCP, the easiest option is Cloud Run. To use it with Terraform you need cloud_run_service.

    For example:

    resource "google_cloud_run_service" "default" {
      name     = "cloudrun-srv"
      location = "us-central1"
    
      template {
        spec {
          containers {
            image = "eu.gcr.io/carlspring/carlspring/hello-spring-boot:1.0"
          }
        }
      }
    
      traffic {
        percent         = 100
        latest_revision = true
      }
    }
    

    Note that I used eu.gcr.io/carlspring/carlspring/hello-spring-boot:1.0 and not carlspring/hello-spring-boot. You must use the fully qualified name as the short one points to Docker Hub where your image will not be found.