Using Packer to build a GCE with “error creating instance” error, next steps

google-cloud-platformgoogle-compute-enginepacker

I've been working with using Packer v0.10.1 to build an image and am running into this access security issue when trying to run via Hashicorp's Atlas tool.

    Packer v0.10.1

    [1;32mgooglecompute output will be in this color.[0m

    [1;32m==> googlecompute: Checking image does not exist...[0m
    [1;32m==> googlecompute: Creating temporary SSH key for instance...[0m
    [1;32m==> googlecompute: Creating instance...[0m
    [0;32m    googlecompute: Loading zone: us-central1-a[0m
    [1;31m==> googlecompute: Error creating instance: Get https://www.googleapis.com/compute/v1/projects/united-course-124523/zones/us-central1-a?alt=json: oauth2/google: can't get a token from the metadata service; not running on GCE[0m
    [1;31mBuild 'googlecompute' errored: Error creating instance: Get https://www.googleapis.com/compute/v1/projects/united-course-124523/zones/us-central1-a?alt=json: oauth2/google: can't get a token from the metadata service; not running on GCE[0m

    ==> Some builds didn't complete successfully and had errors:
    --> googlecompute: Error creating instance: Get https://www.googleapis.com/compute/v1/projects/united-course-124523/zones/us-central1-a?alt=json: oauth2/google: can't get a token from the metadata service; not running on GCE

    ==> Builds finished but no artifacts were created.

Any thoughts, it seems like it ought to be a GCE error but I've uploaded the account.json variable to an environment variable as shown in the Packer template file below.

    {
      "variables": {
        "instance_name": "hdqc-redis-{{timestamp}}",
        "image_name": "testing-hdqc-redis-{{timestamp}}"
      },
      "builders": [
        {
          "type": "googlecompute",
          "project_id": "united-course-124523",
          "source_image": "debian-8-jessie-v20160718",
          "zone": "us-central1-a",
          "instance_name": "{{user `instance_name`}}",
          "image_name": "{{user `image_name`}}",
          "image_description": "Nginx Server.",
          "communicator": "ssh",
          "ssh_username": "redisadmin"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "inline": [
            "sleep 3",
            "echo \"slept for 3 seconds.\""
          ]
        },
        {
          "type": "file",
          "source": "install-redis.sh",
          "destination": "install-redis.sh"
        },
        {
          "type": "shell",
          "script": "install-redis.sh",
          "pause_before": "10s"
        }
      ]
    }

After realizing, this was simply just excluding the account.json, which as shown here requires a specific service account in GCE. So I changed and added the variable of the account.json file contents.

    {
      "variables": {
        "instance_name": "hdqc-redis-{{timestamp}}",
        "image_name": "testing-hdqc-redis-{{timestamp}}",
        "account_json": "{{env `packer_account_json`}}",
      },
      "builders": [
        {
          "type": "googlecompute",
          "account_file": "{{user `account_json`}}",
          "project_id": "united-course-124523",
          "source_image": "debian-8-jessie-v20160718",
          "zone": "us-central1-a",
          "instance_name": "{{user `instance_name`}}",
          "image_name": "{{user `image_name`}}",
          "image_description": "Nginx Server.",
          "communicator": "ssh",
          "ssh_username": "redisadmin"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "inline": [
            "sleep 3",
            "echo \"slept for 3 seconds.\""
          ]
        },
        {
          "type": "file",
          "source": "install-redis.sh",
          "destination": "install-redis.sh"
        },
        {
          "type": "shell",
          "script": "install-redis.sh",
          "pause_before": "10s"
        }
      ]
    }

But then adding this change, where I have the account.json file contents stored as a variable called "packer_account_json" and ended up with the following error.

    Packer v0.10.1

    googlecompute output will be in this color.

    1 error(s) occurred:

    * account_file path does not exist: {

To which I ponder, what in the world now. It can't take a variable? This is similar to how I have stored the account.json contents as a variable for Terraform, and it works just fine.

Best Answer

Packer needs credentials to launch a GCE VM to create the image. If you were running the Packer process on GCE, those credentials would be provided by the instance metadata service.

Since Atlas isn't running on GCE, you'll need to create a service account key, download it, and add it to your Packer manifest. That would be the account_file entry in this simple manifest:

{ "type": "googlecompute", "account_file": "account.json", "project_id": "your-project", "source_image": "your-base-image", "zone": "us-central1-a" }

The Running Without A Compute Engine Service Account section in the Packer docs gives step-by-step instruction for creating the service account key.