Running 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 many 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, a simple startup script that installs and starts an Apache server could look like this:

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

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

Contents

Before you begin

Startup script execution

The instance always executes startup scripts as root, and only executes those scripts after it creates any new users whose SSH keys are included in the instance metadata.

A startup script can be of any file type. If there is a startup script present, Compute Engine will:

  1. Copy the startup script to a local file in the instance.
  2. Set permissions on the file to make it executable.
  3. Execute the file.

You could, for example, provide a Python script instead of a bash script. Keep in mind that Compute Engine will run the script verbatim, regardless of the type of script.

To execute a script that is not bash, add a shebang line at the top of the file to let the operating system know which intepreter to use. For example, for a Python script, you can add a shebang line like:

#!/usr/bin/python

Use a local startup script file

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.

Apply a startup script file

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

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

Provide startup script contents directly

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

Console


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

  1. In the Cloud Platform Console, go to the VM Instances page.

    Go to the VM Instances page

  2. Click the Create instance button.
  3. On the Create a new instance page, fill in the desired properties for your instance.
  4. In the Automation section, supply the contents of your startup script under Startup script.

    Screenshot of setting startup script in the
    Cloud Platform Console

  5. Click the Create button to create the instance.

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/html/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

{
  ...
  "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/html/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>"
      }
    ]
  }
  ...
}

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 instance.

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

Type of script Runs during sysprep, before boot 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
ps11 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.

Set access permissions to your script

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.

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 Cloud Platform Console or Creating a bucket in gsutil.
  2. Upload the file to the bucket. Follow the instructions to use gsutil or the Cloud Platform Console to upload an object.
  3. Give the URL to the startup script file when you create a new instance.

    Console


    1. In the Cloud Platform Console, go to the VM Instances page.

      Go to the VM Instances page

    2. Click the Create instance button.
    3. On the Create a new instance page, fill in the desired properties for your instance.
    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 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 the Create button to create the instance.

    gcloud


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

    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


    In gcloud, create an instance with the --scopes and --metadata flags, and specify the windows-startup-script-url key. The --scopes flag gives the virtual machine access to Google Cloud Storage to download the startup script. You can provide the Google Cloud Storage URL to the script in either gs://bucket/file or https://storage.googleapis.com/bucket/file format.

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

Apply 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.

Console


  1. Go to the VM instances page.
  2. Click on the instance for which you want to add a startup script.
  3. Click the Edit button at the top of the page.
  4. Under Custom metadata, click Add item.
  5. 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.

Setting custom values in startup scripts

When you run startup scripts across instances, there may be situations where you would like to use custom values in your startup script. 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 key/value pairs during instance creation time and reference them in your startup scripts. For more information on creating custom metadata keys, read Set custom metadata.

Once you have set a custom metadata key pair, you can modify your startup script to query for the new metadata. For example, the same script above can be modified as such:

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

Troubleshooting

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.

Send feedback about...

Compute Engine