Is it possible to launch VMs with the deploying containers on option?
https://cloud.google.com/compute/docs/containers/deploying-containers?hl=en_US
I was precisely searching for a solution for that right now. Hope it is.
Unfortunately I don't think we can do this using current GCP APIs. It looks like you can only use gcloud or the UI right now, which I suspect just does the extra deployment work for you on top of the Container-Optimized OS image. I also probably wouldn't redo this deployment work within Terraform since the original feature is beta they may decide to expose this in the API eventually.
@danawillow to confirm there isn't a better option, but I'm guessing to containerize your GCE instances, you'll either need to go the GKE route or do the deployment step yourself (which, if you end up using an Container-Optimized OS image anyways, shouldn't be too bad? disclaimer: I haven't tried it)
Actually I think this will work with Terraform as-is, though it's definitely not intuitive. I went into the UI and pretended to create an instance and then clicked on the "Equivalent REST" button, which gave me:
POST https://www.googleapis.com/compute/v1/projects/graphite-test-danahoffman-tf/zones/us-central1-c/instances
{
"name": "instance-4",
"zone": "projects/graphite-test-danahoffman-tf/zones/us-central1-c",
"minCpuPlatform": "Automatic",
"machineType": "projects/graphite-test-danahoffman-tf/zones/us-central1-c/machineTypes/n1-standard-1",
"metadata": {
"items": [
{
"key": "gce-container-declaration",
"value": "spec:\n containers:\n - name: instance-4\n image: 'gcr.io/cloud-marketplace/google/nginx1:1.12'\n stdin: false\n tty: false\n restartPolicy: Always\n"
}
]
},
"tags": {
"items": []
},
"disks": [
{
"type": "PERSISTENT",
"boot": true,
"mode": "READ_WRITE",
"autoDelete": true,
"deviceName": "instance-4",
"initializeParams": {
"sourceImage": "https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-stable-63-10032-88-0",
"diskType": "projects/graphite-test-danahoffman-tf/zones/us-central1-c/diskTypes/pd-standard",
"diskSizeGb": "10"
}
}
],
"canIpForward": false,
"networkInterfaces": [
{
"subnetwork": "projects/graphite-test-danahoffman-tf/regions/us-central1/subnetworks/default",
"accessConfigs": [
{
"name": "External NAT",
"type": "ONE_TO_ONE_NAT"
}
],
"aliasIpRanges": []
}
],
"description": "",
"labels": {
"container-vm": "cos-stable-63-10032-88-0"
},
"scheduling": {
"preemptible": false,
"onHostMaintenance": "MIGRATE",
"automaticRestart": true
},
"deletionProtection": false,
"serviceAccounts": [
{
"email": "[email protected]",
"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/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/trace.append"
]
}
]
}
So it looks like the container-specific stuff that it added was:
"metadata": {
"items": [
{
"key": "gce-container-declaration",
"value": "spec:\n containers:\n - name: instance-4\n image: 'gcr.io/cloud-marketplace/google/nginx1:1.12'\n stdin: false\n tty: false\n restartPolicy: Always\n"
}
]
},
"sourceImage": "https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-stable-63-10032-88-0",
md5-b2f6b240cf573a2dcc97792ebd8b0f8c
"labels": {
"container-vm": "cos-stable-63-10032-88-0"
},
I don't think it makes sense currently to try to add any extra knobs in Terraform to handle this, since it means that some resource properties are all of a sudden controlled by multiple TF properties and that could end up becoming real tricky. However, you're more than welcome to do it yourself by using those fields, and maybe at some point they'll add something different in the REST API.
As a user, the above workaround makes me uncomfortable because managing a long, whitespace-significant, string value is not ideal. If the provider could abstract this into a declarative stanza and then transform it into metadata before making the API call then I would be much more keen on using it.
@NFollett89 Would a module be sufficient? I think we could relatively easily develop one which formats everything for you.
@morgante Yes, that would be great
Has anyone created a module for this? If so could you post url to an example? Greatly appreciated
@punkdata We've built a module, let me see about releasing it.
@morgante that would be very cool! I figured out a work around before I found this GH issue 😕
I got it to work but if there are other methods it would be great to see some examples
I just can't get the work-around to deploy the docker container.
Can someone who got it to work post their Terraform resource-script for the compute engine please? Maybe I am missing something.
Thanks.
Hey @MaxBinnewies . I ended up just using a ContainerOptmized VM and created an cloud-init script as described in this documentation: https://cloud.google.com/container-optimized-os/docs/how-to/run-container-instance. Check the section Starting a Docker container via Cloud-Config
We've released a module which takes care of constructing the cloud-init config for you. Check out this example: https://github.com/terraform-google-modules/terraform-google-container-vm/blob/master/examples/simple_instance/main.tf
Hm, seems like my problem was that I couldn't pull launcher.gcr.io/google/redis4:latest from Googles Marketplace through Terraform, whereas I can through the UI. Not really sure why.
I just use "redis" from Dockerhub now, that works. And I really just need a standard redis instance, nothing special.
Here is an example of what @danawillow said, boot disk needs to point to cos image and metadata becomes the json malarchi,
boot_disk {
initialize_params {
image = "cos-cloud/cos-stable-72-11316-171-0"
}
}
metadata {
google-logging-enabled="true"
gce-container-declaration = "spec:\n containers:\n - name: instance-4\n image: 'gcr.io/cloud-marketplace/google/nginx1:1.12'\n stdin: false\n tty: false\n restartPolicy: Always\n"
}
labels{
container-vm = "cos-stable-72-11316-171-0"
}
service_account {
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/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/trace.append"]
}
also your service account (used to run terraform) needs Service Account User along with the others.
What about setting other container attributes such as "Host directory mounts" and "Environment variables"?
Volumes can be mounted using the module: https://github.com/terraform-google-modules/terraform-google-container-vm
Closing this since the module now exists; feel free to file issues/FRs about this feature in that repository.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!
Most helpful comment
Actually I think this will work with Terraform as-is, though it's definitely not intuitive. I went into the UI and pretended to create an instance and then clicked on the "Equivalent REST" button, which gave me:
So it looks like the container-specific stuff that it added was:
I don't think it makes sense currently to try to add any extra knobs in Terraform to handle this, since it means that some resource properties are all of a sudden controlled by multiple TF properties and that could end up becoming real tricky. However, you're more than welcome to do it yourself by using those fields, and maybe at some point they'll add something different in the REST API.