Search code examples
ubuntugoogle-cloud-platformcrongcloud

gcloud commands not working in crontab -e?


I have few projects running in my google cloud projects and I am trying to stop them at specific time and start at specific time.

I created a script file for stopping test.sh

#!/bin/bash
gcloud compute instances stop instance1

now I tried crontab -e and added this,

30 01 1-31 1-12 1-5 /home/user/test.sh >> /var/log/test.log

But this didn't stop my gcp instance and also didn't create any log file.

update,

I am just confused about the timings

00 10 * * 1-5 start.sh
00 01 * * 1-5 stop.sh

00 01 * * 6 stop.sh

How will this works on Saturday and Sunday? I want to stop the instances on saturday 1am and start it back on monday 10am. Is my configuration correct?

from monday to friday it should turn off at 1am and start at morning 10am.


Solution

  • `crontab` runs as root (!?) and, as such is not authenticated for `gcloud`

    There are probably better options but by way of outline of a solution:

    • Create a service account with the appropriate permissions to be used by cron
    • Activate the service account gcloud auth activate-service-account for root on the Instance (either during startup or per cron task)
    • Run the cron jobs

    201126 Update

    Apologies, I misread your question and thought you want to run cron on a Compute Engine instance too.

    I think you want to run cron locally.

    The trick (!) is to ensure your commands use absolute paths.

    which gcloud
    

    For me, this returns /snap/bin/gcloud because I'm running on Ubuntu and have gcloud installed as a snap. This will likely be different for you.

    Then, the following works for me:

    stop.sh:

    #!/usr/bin/env bash
    
    PROJECT=[[YOUR-PROJECT]]
    INSTANCE=[[YOUR-INSTANCE]]
    ZONE=[[YOUR-ZONE]]
    
    echo "[$(date --rfc-3339=seconds)] Stopping ${INSTANCE}"
    
    /snap/bin/gcloud compute instances stop ${INSTANCE} \
    --project=${PROJECT} \
    --zone=${ZONE} \
    --verbosity=debug
    
    echo "[$(date --rfc-3339=seconds)] Stopped ${INSTANCE}"
    

    NOTE I've added --verbosity=debug but you may prefer to reduce or omit this entirely.

    Ensure the script is executable:

    chmod +x /path/to/stop.sh
    

    Then crontab -e:

    # Stackoverflow: 64994379
    * * * * * /path/to/stop.sh >>/path/to/stop.log 2>&1
    

    NOTE You want 30 01 1-31 1-12 1-5 here. This may be simpler as 30 01 * * 1-5

    And:

    [2020-11-26 09:39:01-08:00] Stopping [[YOUR-INSTANCE]]
    DEBUG: Running [gcloud.compute.instances.stop] with arguments: [--project: "[[YOUR-PROJECT]]", --verbosity: "debug", --zone: "[[YOUR-ZONE]]", INSTANCE_NAMES:1: "['[[YOUR-INSTANCE]]']"]
    Stopping instance(s) [[YOUR-INSTANCE]]...
    ......done.
    Updated [https://compute.googleapis.com/compute/v1/projects/[[YOUR-PROJECT]]/zones/[[YOUR-ZONE]]/instances/[[YOUR-INSTANCE]]].
    INFO: Display format: "none"
    DEBUG: SDK update checks are disabled.
    [2020-11-26 09:39:04-08:00] Stopped [[YOUR-INSTANCE]]
    [2020-11-26 09:40:01-08:00] Stopping [[YOUR-INSTANCE]]
    DEBUG: Running [gcloud.compute.instances.stop] with arguments: [--project: "[[YOUR-PROJECT]]", --verbosity: "debug", --zone: "[[YOUR-ZONE]]", INSTANCE_NAMES:1: "['[[YOUR-INSTANCE]]']"]
    Stopping instance(s) [[YOUR-INSTANCE]]...
    .....done.
    Updated [https://compute.googleapis.com/compute/v1/projects/[[YOUR-PROJECT]]/zones/[[YOUR-ZONE]]/instances/[[YOUR-INSTANCE]]].
    INFO: Display format: "none"
    DEBUG: SDK update checks are disabled.
    [2020-11-26 09:40:04-08:00] Stopped [[YOUR-INSTANCE]]
    [2020-11-26 09:41:01-08:00] Stopping [[YOUR-INSTANCE]]
    DEBUG: Running [gcloud.compute.instances.stop] with arguments: [--project: "[[YOUR-PROJECT]]", --verbosity: "debug", --zone: "[[YOUR-ZONE]]", INSTANCE_NAMES:1: "['[[YOUR-INSTANCE]]']"]
    Stopping instance(s) [[YOUR-INSTANCE]]...
    ......done.
    Updated [https://compute.googleapis.com/compute/v1/projects/[[YOUR-PROJECT]]/zones/[[YOUR-ZONE]]/instances/[[YOUR-INSTANCE]]].
    INFO: Display format: "none"
    DEBUG: SDK update checks are disabled.
    [2020-11-26 09:41:05-08:00] Stopped [[YOUR-INSTANCE]]
    

    Google Cloud Scheduler gives you the added benefit of running regardless of whether your host (running cron) is running.

    You could augment the script to iterate over all your projects and shutdown every instance too if you want to be very diligent. In such a case, it would be good to have the script notify you of its success or failure too in order that you don't become complacent.