6

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?

John Hanley
  • 74,467
  • 6
  • 95
  • 159
carlspring
  • 31,231
  • 29
  • 115
  • 197
  • 1
    You are trying to specify a container for the booting disk image. You need to specify a Container OS boot image and the run the container inside the OS. This example will help you: https://github.com/terraform-google-modules/terraform-google-container-vm/tree/v1.0.0/modules/cos-generic – John Hanley Mar 13 '20 at 01:01

4 Answers4

5

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.

kichik
  • 33,220
  • 7
  • 94
  • 114
  • Thanks! With this I am getting `Error: Error waiting to create Service: resource is in failed state "Ready:False", message: Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "eu.gcr.io/carlspring/carlspring/hello-spring-boot@sha256:4ca4129f5d19f78a46c64ab65b501497ddc48491e86e17b36615fb4a338da865" error: "Invalid command \"/bin/sh\": file not found" ]. `. Any advice? – carlspring Mar 13 '20 at 01:15
  • 1
    Sounds like your image is broken and has a bad entry point. You can fix that or override it with [`command`](https://www.terraform.io/docs/providers/google/r/cloud_run_service.html#command). – kichik Mar 13 '20 at 01:16
  • I have the following at the end of my `Dockerfile`: `ENTRYPOINT java -jar /java/hello-spring-boot*1.0-SNAPSHOT-spring-boot.war`. Running this locally in Docker works fine. I actually also had this as `CMD` before this and before re-deploying. How would a correct `command` look like? – carlspring Mar 13 '20 at 01:20
  • 1
    If you don't have `/bin/sh` in your image you need `ENTRYPOINT ["java", "-jar", "/java/hello-sprint-boot*1.0-SNAPSHOT-sprint-boot.war"]`. You may have to get rid of that `*` though. – kichik Mar 13 '20 at 01:39
  • Thanks for your suggestions and help! – carlspring Mar 14 '20 at 04:52
5

Terraform can be used to create a GCP VM Instance with Docker Image. Here is an example: https://github.com/terraform-providers/terraform-provider-google/issues/1022#issuecomment-475383003

Hope this helps.

Pradeep Bhadani
  • 4,435
  • 6
  • 29
  • 48
2

The following line indicates the image does not exist:

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

You should tag the image as eu.gcr.io/carlspring/hello-spring-boot:1.0.

Or alternatively, change image reference in boot_disk block to be eu.gcr.io/carlspring/carlspring/hello-spring-boot:1.0.

Elgarni
  • 236
  • 2
  • 5
  • @Elgami: I have updated my question with more details. The way I tagged it was like this: `docker tag carlspring/hello-spring-boot:1.0 eu.gcr.io/${PROJECT_ID}/carlspring/hello-spring-boot:1.0`. Are you saying this is incorrect? – carlspring Mar 13 '20 at 00:18
  • Thanks for your suggestions and help! – carlspring Mar 14 '20 at 04:52
1

You can do this using a VM in GCE whose operating system is based on a Google-supplied Container OS image. You then can use this terraform module that facilitates the fetching and running of a container image.

chb
  • 1,727
  • 7
  • 25
  • 47