Use a startup script on Linux VMs

A startup script performs tasks during the start-up process for a virtual machine (VM). This page provides you with the steps to follow for using startup scripts on VM instances.

Before you begin

To use gdcloud command-line interface (CLI) commands, ensure that you have downloaded, installed, and configured the gdcloud CLI. All commands for Distributed Cloud use the gdcloud or kubectl CLI, and require an operating system (OS) environment.

Get the kubeconfig file path

To run commands against the org admin cluster, ensure you have the following resources:

  1. Locate the org admin cluster name, or ask your Platform Administrator (PA) what the cluster name is.

  2. Sign in and generate the kubeconfig file for the org admin cluster if you don't have one.

  3. Use the path to the kubeconfig file of the org admin cluster to replace ORG_ADMIN_KUBECONFIG in these instructions.

Request permissions and access

To perform the tasks listed in this page, you must have the Project VirtualMachine Admin role. Follow the steps to either verify your access or have your Project IAM Admin assign you the Project VirtualMachine Admin (project-vm-admin) role in the namespace of the project where the VM resides.

Pass a startup script

You can use either bash or non-bash scripts as startup scripts. To do so, include #!/bin/… at the beginning of the script to indicate the script interpreter. For example, to use a Python 3 startup script, add #! /usr/bin/python3 to the beginning of the script.

Google Distributed Cloud (GDC) air-gapped runs startup scripts in alphabetical order, based on the name of each startup script.

The following table shows the script format to use based on your script size:

Script size Script format
Scripts up to 2048 bytes Clear text
Scripts greater than 2048 bytes Kubernetes secret

Define a startup script

To use a startup script you must add the startupScripts field to the VM spec field. Within this field you can specify multiple startup scripts as clear text or as a Kubernetes secret.

The following example specifies the startup scripts as clear text and a Kubernetes secret:

apiVersion: virtualmachine.gdc.goog/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  
  startupScripts:
  - name: hello-world
    script: |
      #!/bin/bash
      echo hello
  - name: add-user
    scriptSecretRef:
      name: add-user
---

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: add-user
data: 
  script:
    IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==

Review the following considerations:

  • The startup script runs on every boot.
  • The startup script has default root privileges.
  • In the Kubernetes secret, the name of the scriptSecretRef in the VM spec must match the metadata.name field.
  • In the Kubernetes secret, specify the startup script content by adding a key script to the data field.

Create a new VM with a startup script

These instructions apply regardless of what you use as the image to create your VM. Complete the following:

  1. To create a startup script as a Kubernetes secret, run:

    cat <<EOF >>FILE_NAME
    STARTUP_SCRIPT_CONTENT
    EOF
    
    kubectl --kubeconfig ORG_ADMIN_KUBECONFIG create secret -n PROJECT generic SECRET_NAME --from-file=script=FILE_NAME
    
    rm FILE_NAME
    
  2. Reference the steps to create a VM as described on the create a VM page. At step one add the startup script or scripts to the spec field before you run the command to create a VM.

    This example defines a startup script with both clear text and a Kubernetes secret:

    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
    name: VM_NAME
    namespace: PROJECT
    spec:
    
    startupScripts:
    - name: CLEAR_TEXT_SCRIPT_NAME
      script: |
        #!/bin/bash
        CLEAR_TEXT_SCRIPT
    - name: SECRET_SCRIPT_NAME
      scriptSecretRef:
        name: SECRET_NAME
    

    These variables are defined as follows:

    VariableDefinition
    ORG_ADMIN_KUBECONFIG The org admin cluster kubeconfig file path.
    PROJECT The Distributed Cloud project in which you want to create the VM.
    VM_NAME The name of the VM.
    FILE_NAME The name of the file to store the startup script.
    STARTUP_SCRIPT_CONTENT The commands to run as part of the startup script
    CLEAR_TEXT_SCRIPT_NAME The name of the clear text startup script.
    CLEAR_TEXT_SCRIPT The clear text script you define.
    SECRET_NAME The name of the Kubernetes secret.
    SECRET_SCRIPT_NAME The name of the startup script as a Kubernetes secret.
  3. Proceed with the following steps to create a VM.

    The following is an example of how to create a VM with startup scripts that adds a new user using a Kubernetes secret and clear text.

    kubectl --kubeconfig ORG_ADMIN_KUBECONFIG \
        apply -n PROJECT -f - <<EOF
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_BOOT_DISK_NAME
    spec:
      source:
        image:
          name: BOOT_DISK_IMAGE_NAME
          namespace: vm-system
      size: BOOT_DISK_SIZE
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: add-user
    data: 
      script:
        IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      compute:
        virtualMachineType: MACHINE_TYPE
      disks:
      - virtualMachineDiskRef:
          name: VM_BOOT_DISK_NAME
        boot: true
        autoDelete: BOOT_DISK_AUTO_DELETE
      startupScripts:
      - name: add-user
        scriptSecretRef:
          name: add-user
      - name: add-to-sudoers
        script: |
          #!/bin/bash
          usermod -aG sudo user
    EOF
    

    In the example the variables are defined as follows.

    VariableDefinition
    ORG_ADMIN_KUBECONFIG The org admin cluster kubeconfig file path.
    PROJECT The Distributed Cloud project in which you want to create the VM.
    VM_NAME The name of the new VM.
    VM_BOOT_DISK_NAME The name of the new VM boot disk.
    BOOT_DISK_IMAGE_NAME The name of the image to be used for the new VM boot disk.
    BOOT_DISK_SIZE The size of the boot disk, such as 20G.
    This value must always be greater than or equal to the minimumDiskSize of the boot disk image.
    BOOT_DISK_AUTO_DELETE Either true or false, indicating whether the boot disk is automatically deleted when the VM instance gets deleted.
    MACHINE_TYPE The predefined machine type for the new VM. To select an available machine type, run this command:
    kubectl --kubeconfig ORG_ADMIN_KUBECONFIG get virtualmachinetype.virtualmachine.gdc.goog --namespace vm-system

Update an existing VM with a startup script

You can also update an existing VM with a startup script. The VM must be shut down before you perform the update.

Follow the steps to update VM properties and update the spec field with the startup script that you would like to run.

View the output of a startup script

  1. Follow the steps to connect to a VM.
  2. Run the following command inside the guest VM to get the logs of the startup script that you ran:

    sudo journalctl -u cloud-final
    

    The startup script logs begin with the following:

    Started to run the command: /var/lib/google/startup-scripts/<script-name> ...