Use a startup script with a VM instance

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 Hosted use the gdcloud or kubectl CLI, and require an operating system (OS) environment.

Get the kubeconfig file paths

  1. Run gdcloud auth login to the admin cluster.

    1. Record the path to the generated file, as in this example:
      /tmp/admin-kubeconfig-with-user-identity.yaml.

    2. Use the path to replace ORG_ADMIN_KUBECONFIG in these instructions.

  2. Make sure you have enabled access to create and manage secrets.

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.

Startup script execution order

Startup scripts are executed in alphabetical order, based on the name of each startup script.

Startup script YAML format

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. Scripts must be specified as Kubernetes secrets. |

The following example has two startup scripts specified as Kubernetes secrets:

apiVersion: virtualmachine.gdc.goog/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  …
  startupScripts:
  - name: hello-world
    scriptSecretRef:
      name: hello-world
  - name: add-user
    scriptSecretRef:
      name: add-user
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: hello-world
data:
  script:
    IyEvYmluL2Jhc2gKZWNobyBoZWxsbwo=
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: add-user
data: 
  script:
    IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==

Important notes

  1. The startup script runs on every boot.
  2. The startup script has default root privileges.
  3. The name of the scriptSecretRef in the VM spec must match the metadata.name field in the Kubernetes secret.
  4. The startup script content in the Kubernetes secret must be specified 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.

  1. Create the startup script secret:

    cat <<EOF >>FILE_NAME
    STARTUP_SCRIPT_CONTENT
    EOF
    
    kubectl --kubeconfig ORG_ADMIN_KUBECONFIG create secret -n PROJECT generic SCRIPT_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 1 add the startup script or scripts to the spec field before you run the command to create a VM.

    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
    name: VM_NAME
    namespace: PROJECT
    spec:
    …
    startupScripts:
    - name: SCRIPT_NAME
      scriptSecretRef:
          name: SCRIPT_SECRET_NAME
    

    These variables are defined as follows:

    VariableDefinition
    ORG_ADMIN_KUBECONFIG The org admin cluster kubeconfig file path.
    PROJECT The Distributed Cloud Hosted 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
    SCRIPT_SECRET_NAME The name of the startup script secret.
    SCRIPT_NAME The name of the startup script in the VM spec.
  3. Proceed with the following steps to create a VM.

    The following is an example of how to create a VM with a startup script that adds a new user.

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