Hide
Compute Engine

Startup Scripts

Create and run your own startup scripts on your virtual machines to perform automated tasks every time your instance boots up. Startup scripts can perform a number of actions, such as installing software, performing updates, turning on services, and any other tasks defined in the script. You can use startup scripts to easily and programmatically customize your virtual machine instances, including on new instances at creation time.

For example, the following is a simple startup script that installs and starts an Apache server:

#! /bin/bash
apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/index.html
<html><body><h1>Hello World</h1>
<p>This page was created from a simple startup script!</p>
</body></html>
EOF

Provide a startup script with your initial virtual machine creation request and the script will run automatically on every boot. You can also add a startup script to a currently running instance and the startup script will run at next boot.

A startup script is specified through the metadata server, using startup script metadata keys. You can use gcloud, the API, or the Google Developers Console to provide a startup script.

Contents

Use a local startup script

A local startup script is a script located on your local computer. To use a local startup script, pass in a startup script file or provide the contents of a startup script directly to the metadata server.

Local startup scripts are subject to the metadata value length limit of 32768 bytes. If your startup script exceeds this limit, you will not be able to load it locally. Instead, save your file to Google Cloud Storage and specify the script URL during instance creation time. See Use a startup script stored on Cloud Storage for more information.

Provide a startup script file

To pass in a local startup script file, use gcloud and supply the --metadata-from-file flag, followed by a metadata key pair, startup-script=PATH/TO/FILE, where PATH/TO/FILE is a relative path to the startup script:

$ gcloud compute instances create example-instance \
    --metadata-from-file startup-script=examples/scripts/install.sh

You can only pass in a local startup script file through gcloud.

Provide startup script contents directly

Alternatively, you can pass in the contents of your startup script directly.

Developers Console


In Developers Console, specify a startup script directly in the Startup script section:

  1. Log into the VM instances page in the Developers Console.
  2. Click New instance.
  3. Fill in the desired properties for your instance and expand the Management, disk, networking, access & security options section.
  4. In the Automation section, supply the contents of your startup script under Startup script.

    Screenshot of setting startup script in the Developers Console

  5. When you are done, click Create to create your virtual machine.

gcloud


In gcloud, use the --metadata flag to provide the contents of your startup script, followed by the startup-script=CONTENTS key pair, where CONTENTS is the content of your startup script.

$ gcloud compute instances create example-instance --metadata startup-script="#! /bin/bash
> # Installs apache and a custom homepage
> sudo su -
> apt-get update
> apt-get install -y apache2
> cat <<EOF > /var/www/index.html
> <html><body><h1>Hello World</h1>
> <p>This page was created from a simple start up script!</p>
> </body></html>
> EOF"

API


In the API, provide a startup script as part of the metadata property in your request, using startup-script as the metadata key:

POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances

{
  "disks": [
    {
      "type": "PERSISTENT",
      "boot": true,
      "mode": "READ_WRITE",
      "initializeParams": {
        "sourceImage": "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/backports-debian-7-wheezy-v20150325",
        "diskType": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/diskTypes/pd-standard"
      }
    }
  ],
  "networkInterfaces": [
    {
      "network": "https://www.googleapis.com/compute/v1/projects/myproject/global/networks/default",
      "accessConfigs": [
        {
          "name": "External NAT",
          "type": "ONE_TO_ONE_NAT"
        }
      ]
    }
  ],
  "metadata": {
    "items": [
      {
       "key": "startup-script",
       "value": "#! /bin/bash\n\n# Installs apache and a custom homepage\napt-get update\napt-get install -y apache2\ncat <<EOF > /var/www/index.html\n<html><body><h1>Hello World</h1>\n<p>This page was created from a simple start up script!</p>\n</body></html>"
      }
    ]
  },
  "tags": {
    "items": []
  },
  "zone": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a"
  },
  "machineType": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/machineTypes/n1-standard-1",
  "name": "example-instance"
}

Provide a startup script for Windows instances

You can run startup scripts on Windows instances using unique Windows-specific metadata keys. Choose from any of the specialized keys listed below. Each key should match the type of script you want to run. You can also specify multiple scripts by passing in different keys to your instance. Each key can only be specified once per virtual machine.

The following keys can be used with a local startup script, using the same instructions above.

The following shutdown script keys are specific to Windows instances.

Type of script Runs during sysprep, before reboot Runs after sysprep is complete and on every subsequent boot
cmd startup scripts sysprep-specialize-script-cmd windows-startup-script-cmd
bat startup scripts sysprep-specialize-script-bat windows-startup-script-bat
PowerShell1 startup scripts sysprep-specialize-script-ps1 windows-startup-script-ps1

Use a startup script stored on Google Cloud Storage

You can store your script on Google Cloud Storage and provide the URL to the script when creating your instance. This allows you to access your startup script from anywhere and also bypasses the metadata server limit.

Access permissions

In order to use a startup script from Google Cloud Storage, you must have permission to access the script. Check the access control settings on the bucket and file to ensure you have permission.

By default, if you are a project owner or editor, you should be able to access files from the same project, unless there are explicit access controls that disallow it.

Windows instances are an exception to this rule and require that the startup script file is publicly accessible.

Provide a startup script

  1. Create a bucket. You can create a new bucket or use an existing bucket. For instructions on creating a new bucket, see Creating a bucket in the Google Developers Console or Creating a bucket in gsutil.
  2. Upload the file to the bucket. Follow the instructions to use gsutil or the Developers Console to upload an object.
  3. Give the URL to the startup script file when you create a new instance.

    Developers Console


    In the Developers Console:

    1. Log into the VM instances page in the Developers Console.
    2. Click New instance.
    3. Fill in the desired properties for your instance and expand the Management, disk, networking, access & security options section.
    4. In the Metadata section, fill in startup-script-url for the key.
    5. In the Value box, provide the URL to the file, either in the gs://bucket/file or https://storage.googleapis.com/bucket/file format.
    6. Click on the Access & security tab.
    7. In the Project access section, select Read-only from the Storage section. This gives the virtual machine access to use the startup script stored in Google Cloud Storage.
    8. Click Create to create your virtual machine.

    gcloud


    In gcloud, create an instance with the --scopes and --metadata flag, using the startup-script-url key. The --scopes flag gives the virtual machine access to Google Cloud Storage to get the startup script file. For the URL to the file, you can provide a URL in the format gs://bucket/file or https://storage.googleapis.com/bucket/file:

    $ gcloud compute instances create example-instance --scopes storage-ro \
     --metadata startup-script-url=gs://bucket/startupscript.sh
    

    API


    In the API, provide a startup script as part of the metadata property in your request, using startup-script-url as the metadata key. Also, provide a list of scopes, with a Google Cloud Storage scope so the virtual machine can access the startup script file:

    POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances
    
    {
      ...
      serviceAccounts": [
        {
          "email": "default",
          "scopes": [
            "https://www.googleapis.com/auth/devstorage.read_only",
          ]
        }
      ],
      "metadata": {
        "items": [
          {
           "key": "startup-script-url",
           "value": "gs://bucket/myfile"
          }
        ]
      },
      "tags": {
        "items": []
      },
      "zone": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a"
      },
      "machineType": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/machineTypes/n1-standard-1",
      "name": "example-instance"
    }
    

    Windows


    To use a startup script stored on Google Cloud Storage for a Windows instance, you must:

    1. Make your shutdown script file publicly accessible. Unlike Linux virtual machines, Windows instances require that your file is publicly-accessible.

    2. Use the following metadata key/value pair:

      windows-shutdown-script-url=URL
      

    When you pass in a startup script in this way, the startup script will run as if you has passed in a windows-shutdown-script-* key. Your startup script file can end with a .ps1, .cmd, or .bat file extension.

    For example:

    $ gcloud compute instances create example-windows-instance \
       --metadata windows-startup-script-url=gs://bucket/startupscript.ps1
    

Assign a startup script to running instances

If you have a running instance, add a startup script to the instance and the next time the instance restarts, the startup script will run. The startup script will also run on all subsequent reboots.

Follow these instructions to set a startup script on a running instance.

Developers Console


  1. Log into the VM instances page in the Developers Console.
  2. Click on the instance for which you want to add a startup script.
  3. Under Custom metadata, click Edit or Add.
  4. Add your startup script using one of the following keys:

    • startup-script: Supply the startup script contents directly with this key.
    • startup-script-url: Supply a Google Cloud Storage URL to the start script file with this key.

gcloud


In gcloud, use the instances add-metadata to add metadata to the instance. Use any of the available startup script keys:

  • --metadata startup-script=CONTENTS: Supply the startup script contents directly with this key.
  • --metadata startup-script-url=URL: Supply a Google Cloud Storage URL to the start script file with this key.
  • --metadata-from-file startup-script=FILE: Supply a locally stored start up script file.

For example:

$ gcloud compute instances add-metadata example-instance \
    --metadata-from-file startup-script=path/to/file

$ gcloud compute instances add-metadata example-instance \
    --metadata startup-script-url=gs://bucket/file

API


In the API, make a request to the instances().setMetadata method, providing the new metadata and a fingerprint value.

A fingerprint is a random string of characters generated by Compute Engine and is used to perform optimistic locking. Provide the matching fingerprint value in order to perform your request. The fingerprint changes after each request and if you provide a mismatched fingerprint, your request is rejected. In this way, only one update can be made at a time, preventing collisions.

To get the current fingerprint of an instance, perform a instances().get request and copy the fingerprint value:

GET https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance

{

 ...
 "name": "example-instance",
 "metadata": {
  "kind": "compute#metadata",
  "fingerprint": "zhma6O1w2l8="
 },
 "...
}

Next, make a request to the instances().setMetadata method, using one of the following metadata keys and the fingerprint value:

  • startup-script: Supply the startup script contents directly with this key.
  • startup-script-url: Supply a Google Cloud Storage URL to the start script file with this key.

For example:

POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata

{
 "fingerprint": "zhma6O1w2l8=",
 "items": [
  {
   "key": "startup-script-url",
   "value": "gs://bucket/file"
  }
 ]
}

Rerunning a Startup Script

You can force your startup scripts to rerun on your VM by ssh'ing in and running the following command:

$ sudo /usr/share/google/run-startup-scripts
google Running startup script...
google Finished running startup script...

You can view a log for all the times you have run your startup scripts at /var/log/startupscript.log.

Using custom values in startup scripts

When you run startup scripts across instances, there may be situations where you would like to use custom values for different instances. For example, you may want to run a startup script on different instances and have each instance print out a custom message.

You can specify these custom values as custom metadata during instance creation time and reference them in your startup scripts.

Set a custom value

To set a custom value, provide a key/value pair with the metadata property.

Developers Console


  1. Log into the VM instances page in the Developers Console.
  2. Click on the instance for which you want to add a startup script.
  3. Under Custom metadata, click Edit or Add.
  4. Set your custom key/value pair.
  5. Save your changes.

gcloud


In gcloud, use the add-metadata method:

$ gcloud compute instances add-metadata example-instance --metadata foo=bar

API


In the API, make a request to the instances().setMetadata method, providing the new metadata and a fingerprint value.

A fingerprint is a random string of characters generated by Compute Engine and is used to perform optimistic locking. Provide the matching fingerprint value in order to perform your request. The fingerprint changes after each request and if you provide a mismatched fingerprint, your request is rejected. In this way, only one update can be made at a time, preventing collisions.

To get the current fingerprint of an instance, perform a instances().get request and copy the fingerprint value:

GET https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance

{

 ...
 "name": "example-instance",
 "metadata": {
  "kind": "compute#metadata",
  "fingerprint": "zhma6O1w2l8="
 },
 "...
}

Next, make a request to the 'instances().setMetadata` method and set your custom metadata key/value pairs:

POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata

{
 "fingerprint": "zhma6O1w2l8=",
 "items": [
  {
   "key": "foo",
   "value": "bar"
  }
 ]
}

Now, you can access the value of foo from within an instance by connecting to the instance with ssh and querying the metadata server:

user@example-instance:~$ curl http://metadata/computeMetadata/v1/instance/attributes/foo -H "Metadata-Flavor: Google"
bar

Use a custom value

After setting a custom value, you can modify your startup script to query for custom metadata. For example, the same script above can be modified as such:

#! /bin/bash
VALUE_OF_FOO=$(curl http://metadata/computeMetadata/v1/instance/attributes/foo -H "Metadata-Flavor: Google")
apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/index.html
<html><body><h1>Hello World</h1>
<p>The value of foo: $VALUE_OF_FOO</p>
</body></html>
EOF

Troubleshootig

Network connectivity to the metadata server

Specific to Linux virtual machines, Compute Engine will wait for a connection to the metadata server before attempting to get information such as a custom startup or shutdown script from the metadata server. If the metadata server is not responding or the network is not yet configured, the virtual machine will not finish booting up.

On the virtual machine, the serial port output will show ""Waiting for metadata server, attempt N" where N is the number of attempts that have been made.

If this occurs for a lengthy period of time (more than seven minutes), there is likely a transient network issue which should resolve on its own. If this lasts for more than seven minutes, recreate your virtual machine.