Use startup scripts on Linux VMs

Linux

A startup script is a file that performs tasks during the startup process of avirtual machine (VM) instance. Startup scripts can apply to all VMs in a projector to a single VM. Startup scripts specified by VM-level metadata overridestartup scripts specified by project-level metadata, and startup scripts onlyrun when a network is available. This document describes how to use startupscripts on Linux VM instances. For information about how to add aproject-level startup script, seegcloud compute project-info add-metadata.

For Linux startup scripts, you can use bash or non-bash file. To use a non-bashfile, designate the interpreter by adding a#! to the top of the file. Forexample, to use a Python 3 startup script, add#! /usr/bin/python3 to the topof the file.

If you specify a startup script by using one of the procedures in this document,Compute Engine does the following:

  1. Copies the startup script to the VM

  2. Sets run permissions on the startup script

  3. Runs the startup script as theroot user when the VM boots

For information about the various tasks related to startup scripts and when toperform each one, see theOverview.

Prerequisites

To run scripts stored in metadata on a VM instance, theguest environment must be installed and running.

  • The guest environment includes theguest agent (for example, google-guest-agent on Linux)that reads the script content or URL from the instance's metadata and initiates execution.
  • All public Compute Engine images come with the guest environmentpreinstalled.
  • If you create a custom image, you mustmanually install the Google Guest Environment to ensurescripts from metadata and other Google Cloud features function properly.

Before you begin

Metadata keys for Linux startup scripts

A startup script is passed to a VM from a location that is specified by ametadata key. A metadata key specifies whether the startup script is storedlocally, stored in Cloud Storage, or passed directly to the VM. Themetadata key that you use might also depend on the size of the startup script.

The following table shows the metadata keys that you can use for Linux startupscripts, and provides information about which key to use based on the storagelocation and size of the startup script.

Metadata keyUse for
startup-scriptPassing a bash or non-bash startup script that is stored locally or added directly and that is up to 256 KB in size
startup-script-urlPassing a bash or non-bash startup script that is stored in Cloud Storage and that is greater than 256 KB in size. The string you enter here is used as-is to rungcloud storage. If yourstartup-script-url contains space characters, then don't replace the spaces with%20 or add double quotes ("") to thestartup-script-url string.

Order of execution of Linux startup scripts

You can use multiple startup scripts. Startup scripts stored locally or addeddirectly execute before startup scripts that are stored inCloud Storage. The following table shows, based on the metadata key,the order of execution of Linux startup scripts.

Metadata keyOrder of execution
startup-scriptFirst during each boot after the initial boot
startup-script-urlSecond during each boot after the initial boot

Passing a Linux startup script directly

You can add the contents of a startup script directly to a VM when you createthe VM. The following procedures show how to create a VM with a startup scriptthat installs Apache and creates a basic web page.

Permissions required for this task

To perform this task, you must have the followingpermissions:

  • All permissions required tocreate a new VM.
  • compute.instances.setMetadata on the VM.

Console

Passing a Linux startup script directly to a new VM

  1. In the Google Cloud console, go to theCreate an instance page.

    Go to Create an instance

  2. To use a Linux operating system, do the following:

    1. In the navigation menu, clickOS and storage.

    2. ClickChange.

    3. In theBoot disk pane that appears, select a Linux operating system.

  3. To directly add a Linux startup script, do the following:

    1. In the navigation menu, clickAdvanced.

    2. In theAutomation section, enter the following in theStartup script field:

      #! /bin/bashapt updateapt -y install apache2cat <<EOF > /var/www/html/index.html<html><body><p>Linux startup script added directly.</p></body></html>EOF
  4. Optional: Specify other configuration options. For more information, seeConfiguration options during instance creation.

  5. To create and start the instance, clickCreate.

Passing a Linux startup script directly to an existing VM

  1. In the Google Cloud console, go to theVM instances page.

    Go to VM instances

  2. Click theName of the instance.

  3. ClickEdit.

  4. UnderAutomation, add the contents of your startup script.

Verifying the startup script

After the instance starts, view the external IP in a web browser to verifythat the startup script created the website. You might have to wait about 1minute for the sample startup script to finish.

gcloud

Passing a Linux startup script directly to a new VM

Pass the contents of a startup script directly to a VM when creating itby using the followinggcloud compute instances createcommand.

gcloud compute instances createVM_NAME \  --image-project=debian-cloud \  --image-family=debian-10 \  --metadata=startup-script='#! /bin/bash  apt update  apt -y install apache2  cat <<EOF > /var/www/html/index.html  <html><body><p>Linux startup script added directly.</p></body></html>  EOF'

ReplaceVM_NAME with the name of the VM.

Passing a Linux startup script directly to an existing VM

Add the startup script directly to an existing VM by using the followinggcloud compute instances add-metadatacommand:

gcloud compute instances add-metadataVM_NAME \    --zone=ZONE \    --metadata=startup-script='#! /bin/bash    apt update    apt -y install apache2    cat <<EOF > /var/www/html/index.html    <html><body><p>Linux startup script added directly.</p></body></html>    EOF'

Replace the following:

  • VM_NAME: the name of the VM

  • ZONE: the zone of the VM

Verifying the startup script

After the VM starts, view the external IP in a web browser to verify thatthe startup script created the web site. You might have to wait about 1minute for the sample startup script to finish.

REST

Passing a Linux startup script directly to a new VM

Pass the contents of a startup script directly to a VM when creating it byusing the followinginstances.insertmethod.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances{  ...  "networkInterfaces": [    {      "accessConfigs": [        {          "type": "ONE_TO_ONE_NAT"        }      ]    }  ],  "metadata": {    "items": [      {        "key": "startup-script",        "value": "#! /bin/bash\napt update\napt -y install apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><p>Linux startup script added directly.</p></body></html>\nEOF"      }    ]  },  ...}

Replace the following:

  • PROJECT_ID: the ID of the project where the VMexists.

  • ZONE: the zone to create the VM in.

Passing a Linux startup script directly to an existing VM

  1. Get themetadata.fingerprint value of the VM by using theinstances.get method:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

    Replace the following:

    • PROJECT_ID: the ID of the project where the VMexists.

    • ZONE: the zone of the VM.

    • VM_NAME: the name of the VM.

  2. Pass the startup script by using thefingerprint value, along with themetadata key and value for the startup script, in a call to theinstances.setMetadata method:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setMetadata{  "fingerprint":FINGERPRINT,  "items": [    {      "key": "startup-script",      "value": "#! /bin/bash\napt update\napt -y install apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><p>Linux startup script added directly.</p></body></html>\nEOF"    }  ],  ...}

    Replace the following:

    • PROJECT_ID: the ID of the project where the VMexists.

    • ZONE: the zone of the VM.

    • VM_NAME: the name of the VM.

    • FINGERPRINT: themetadata.fingerprint valueobtained by using theinstances.get method.

Verifying the startup script

After the VM starts, view the external IP in a web browser to verify thatthe startup script created the web site. You might have to wait about 1minute for the sample startup script to finish.

Passing a Linux startup script from a local file

You can store a startup script in a local file on your workstation and pass thelocal file as metadata to a VM when you create it. You cannot use files storedon VMs as startup scripts.

Before passing a Linux startup script from a local file to a VM, do thefollowing:

  1. Create a local file to store the startup script.

  2. Note the relative path from gcloud CLI to the startup script.

  3. Add the following startup script to the file:

    #! /bin/bashapt updateapt -y install apache2cat <<EOF > /var/www/html/index.html<html><body><p>Linux startup script from a local file.</p></body></html>EOF

Permissions required for this task

To perform this task, you must have the followingpermissions:

  • All permissions required tocreate a new VM.
  • compute.instances.setMetadata on the VM.

gcloud

Passing a Linux startup script from a local file to a new VM

Create a VM and pass the contents of a local file to be used as thestartup script by using thegcloud compute instances createcommand with the--metadata-from-file flag.

gcloud compute instances createVM_NAME \  --image-project=debian-cloud \  --image-family=debian-10 \  --metadata-from-file=startup-script=FILE_PATH

Replace the following:

  • VM_NAME: the name of the VM

  • FILE_PATH: the relative path to the startupscript file

Passing a Linux startup script from a local file to an existing VM

Pass a startup script to an existing VM from a local file by using the followinggcloud compute instances add-metadatacommand:

gcloud compute instances add-metadataVM_NAME \  --zone=ZONE \  --metadata-from-file startup-script=FILE_PATH

Replace the following:

  • VM_NAME: the name of the VM

  • ZONE: the zone of the VM

  • FILE_PATH: the relative path to the startupscript file

Verifying the startup script

View the external IP in a web browser to verify that the startup script createdthe web site. You might have to wait about 1 minute for the sample startupscript to finish.

Passing a Linux startup script from Cloud Storage

You can store a startup script in Cloud Storage and pass it to a VMwhen you create it. After you add a startup script to Cloud Storage,you have a URL that you can use to reference the startup script when you createa VM.

Before adding a startup script from a Cloud Storage bucket, do thefollowing:

  1. Create a file to store the startup script. This example uses a bash (.sh)file.

  2. Add the following to the bash file, which installs Apache and creates asimple web page:

    #! /bin/bashapt updateapt -y install apache2cat <<EOF > /var/www/html/index.html<html><body><p>Linux startup script from Cloud Storage.</p></body></html>EOF
  3. Create a Cloud Storage bucket.

  4. Add the file to the Cloud Storage bucket.

Security implications

  • By default, project owners and project editors can accessCloud Storage files in the same project, unless there are explicitaccess controls that disallow it.

  • If the Cloud Storage bucket or object is less secure than metadata,there is a risk of privilege escalation if the startup script is modified andthe VM reboots. This is because after the VM reboots, the startup script runs asroot and can then use the permissions of the attached service account toaccess other resources.

Limitations

Permissions required for this task

To perform this task, you must have the followingpermissions:

  • All permissions required tocreate a new VM.
  • compute.instances.setMetadata on the VM.
  • Permission to access the bucket and script file in Cloud Storage. Check theaccess control settings on the bucket and file to ensure you have permission.

Console

Passing a startup script that is stored in Cloud Storage to a new VM

  1. In the Google Cloud console, go to theCreate an instance page.

    Go to Create an instance

  2. To use a Linux operating system, do the following:

    1. In the navigation menu, clickOS and storage.

    2. In theOperating system and storage section, clickChange.Then, select a Linux operating system.

  3. To allow the instance to access the Cloud Storage bucket thatcontains the Linux startup script, do the following:

    1. In the navigation menu, clickSecurity.

    2. In theService account list, select a service accountthat has theStorage Object Viewer (roles/storage.objectViewer) IAM roleon the Cloud Storage bucket.

  4. To add a Linux startup script by specifying a file inCloud Storage, do the following:

    1. In the navigation menu, clickAdvanced.

    2. In theMetadata section, clickAdd item. TheKey andValue fields appear.

    3. In theKey field, enterstartup-script-url.

    4. In theValue field, enter the Cloud Storage location ofthe startup script file using one of the following formats:

      • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
      • gcloud storage URI:gs://BUCKET/FILE

        Replace the following:

      • BUCKET: the name of the bucket thatcontains the startup script file

      • FILE: the name of the startup scriptfile

  5. Optional: Specify other configuration options. For more information, seeConfiguration options during instance creation.

  6. To create and start the instance, clickCreate.

Passing a startup script that is stored in Cloud Storage to an existing VM

  1. In the Google Cloud console, go to theVM instances page.

    Go to VM instances

  2. Click theName of the instance.

  3. ClickEdit.

  4. UnderMetadata, add the following values:

    • Key:startup-script-url

    • Value: the Cloud Storage location of the startup scriptfile using one of the following formats:

      • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
      • gcloud storage URI:gs://BUCKET/FILE

Verifying the startup script

View the external IP in a web browser to verify that the startup scriptcreated the web site. You might have to wait about 1 minute for the samplestartup script to finish.

gcloud

Passing a startup script that is stored in Cloud Storage to a new VM

Pass a startup script stored in Cloud Storage to a VM when youcreate it by using the followinggcloud compute instances createcommand. For the value ofthe--scope flag, usestorage-ro so the VM can accessCloud Storage.

gcloud compute instances createVM_NAME \  --image-project=debian-cloud \  --image-family=debian-10 \  --scopes=storage-ro \  --metadata=startup-script-url=CLOUD_STORAGE_URL

Replace the following:

  • VM_NAME: the name of the VM.

  • CLOUD_STORAGE_URL: the metadata value. Set tothe Cloud Storage location of the startup script file using oneof the following formats:

    • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
    • gcloud storage URI:gs://BUCKET/FILE

Passing a startup script that is stored in Cloud Storage to an existing VM

Pass a startup script that is stored in Cloud Storage to anexisting VM by using the followinggcloud compute instances add-metadatacommand:

gcloud compute instances add-metadataVM_NAME \    --zone=ZONE \    --metadata startup-script-url=CLOUD_STORAGE_URL

Replace the following:

  • VM_NAME: the name of the VM.

  • ZONE: the zone of the VM.

  • CLOUD_STORAGE_URL: the metadata value. Set tothe Cloud Storage location of the startup script file using oneof the following formats:

    • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
    • gcloud storage URI:gs://BUCKET/FILE

Verifying the startup script

View the external IP in a web browser to verify that the startup scriptcreated the web site. You might have to wait about 1 minute for the samplestartup script to finish.

REST

Passing a startup script that is stored in Cloud Storage to a new VM

Pass a startup script that is stored in Cloud Storage to a VMwhen you create it by using the followinginstances.insertmethod. Tothescopes field, addhttps://www.googleapis.com/auth/devstorage.read_only so the VM can accessCloud Storage.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances{  ...  "networkInterfaces": [    {      "accessConfigs": [        {          "type": "ONE_TO_ONE_NAT"        }      ]    }  ],  "serviceAccounts": [    {      "email": "default",      "scopes": [        "https://www.googleapis.com/auth/devstorage.read_only"      ]    }  ],  "metadata": {    "items": [      {        "key": "startup-script-url",        "value": "CLOUD_STORAGE_URL"      }    ]  },  ...}

Replace the following:

  • PROJECT_ID: the project ID.

  • ZONE: the zone to create the VM in.

  • CLOUD_STORAGE_URL: the metadata value. Set tothe Cloud Storage location of the startup script file using oneof the following formats:

    • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
    • gcloud storage URI:gs://BUCKET/FILE

Passing a startup script that is stored in Cloud Storage to an existing VM

  1. Get themetadata.fingerprint value of the VM by using theinstances.get method:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

    Replace the following:

    • PROJECT_ID: the project ID

    • ZONE: the zone of the VM

    • VM_NAME: the name of the VM

  2. Pass the startup script by using thefingerprint value, along with themetadata key and value for the startup script, in a call to theinstances.setMetadata method:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setMetadata{  "fingerprint":FINGERPRINT,  "items": [    {        "key": "startup-script-url",        "value": "CLOUD_STORAGE_URL"    }  ],  ...}

    Replace the following:

    • PROJECT_ID: the project ID.

    • ZONE: the zone of the VM.

    • VM_NAME: the name of the VM.

    • FINGERPRINT: themetadata.fingerprint valueobtained by using theinstances.get method.

    • CLOUD_STORAGE_URL: the metadata value. Set tothe Cloud Storage location of the startup script file usingone of the following formats:

      • Authenticated URL:https://storage.googleapis.com/BUCKET/FILE
      • gcloud storage URI:gs://BUCKET/FILE

Verifying the startup script

View the external IP in a web browser to verify that the startup scriptcreated the web site. You might have to wait about 1 minute for the samplestartup script to finish.

Accessing metadata from a Linux startup script

In a startup script you can access metadata values. For example, you can use thesame script for multiple VMs, and parameterize each script individually bypassing different metadata values to each VM.

To access a custom metadata value from a startup script, do the following:

  1. Create a startup script that queries the value of a metadata key. Forexample, the following bash file (.sh) startup script queries the value ofthefoo metadata key.

    #! /bin/bashMETADATA_VALUE=$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/foo -H "Metadata-Flavor: Google")apt updateapt -y install apache2cat <<EOF > /var/www/html/index.html<html><body><p>Accessing metadata value of foo: $METADATA_VALUE</p></body></html>EOF
  2. Set the value of thefoo metadata key when creating a VM by using thefollowinggcloud compute instances createcommand. For this example,the startup script is passed to the VM from a local file.

    gcloud

    gcloud compute instances createVM_NAME \  --image-project=debian-cloud \  --image-family=debian-10 \  --metadata-from-file=startup-script=FILE_PATH \  --metadata=foo=bar

    Replace the following:

    • VM_NAME: the name of the VM

    • FILE_PATH: the relative path to the startupscript file

    For more information about how to specify a metadata key/value pair, seeSetting custom metadata.

  3. From your local workstation, view the external IP in a web browser to verify thatthe startup script outputs the value offoo. You might have to wait about 1minute for the sample startup script to finish.

Rerunning a Linux startup script

Rerun a startup script by doing the following:

  1. Connecting to the VM.

  2. Running the following command:

    sudogoogle_metadata_script_runnerstartup

Viewing the output of a Linux startup script

You can view the output from a Linux startup script by doing any of thefollowing:

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.