6

I want to automatically start/stop our app engine services by running a bash script.

I know it's easy to run gcloud app versions start/stop, but I don't want to manually check the version number. I want to dynamically pass the version that is serving 100% traffic to gcloud and tell it to stop.

On the flip side, I also want to tell gcloud to start the most recently deployed version.

What's the recommended way to do this?

Thanks!

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
Mike
  • 1,180
  • 3
  • 15
  • 28
  • Note that the `gcloud app versions start|stop` commands are only applicable to manually scaled services, while traffic switching/splitting applies to dynamically scaled services. – Dan Cornilescu Feb 25 '18 at 17:12

2 Answers2

6

One way to do that is to use gcloud's keys and flags: projections, --format, --filters. To read more directly from the terminal use gcloud topic, for example:

gcloud topic projections

In order to see what fields/properties are available use --format=flattened, like:

gcloud app services list --format=flattened

For the sake of simplicity I will leave outside everything but gcloud.

for SERVICE in $(gcloud app services list --format='table[no-heading](id)'); do
    echo "for service $SERVICE :"

    RECENT=$(gcloud app versions list --format='table[no-heading](id)' --filter="service=$SERVICE" | tail -n1)

    echo 'y' | gcloud app versions start $RECENT

    VERSIONS=$(gcloud app versions list --format='table[no-heading](id)' --filter="service=$SERVICE AND version.servingStatus=SERVING AND NOT id=$RECENT" | tr '\n' ' ')

    echo 'y' | gcloud app versions stop $VERSIONS
done

'table[no-heading](service)' outputs a table without heading, which is set in brackets, and a single column with service IDs, which is set in parentheses.

--filter="service=$SERVICE AND version.servingStatus=SERVING AND NOT id=$RECENT" will only show versions from indicated service that are serving, except the one indicated by RECENT.

Additionally, if you would want to use dates for filtering:

gcloud app versions list --format='table(id, version.servingStatus, version.createTime.date(format="%s"))' --filter="service=default" --sort-by="~version.createTime"

version.createTime.date(format="%s") is a function date converting version.createTime.date into the number of seconds since the Epoch.

%s comes from strftime(3) and returns dates in Epoch format which is easier to understand and compare.

--sort-by="~version.createTime"sorts by creation date and because of ~ in descending order.

A.Queue
  • 1,549
  • 6
  • 21
1

One approach is to use the --stop-previous-version and/or --promote options when deploying with gcloud app deploy (they should be the default if I interpret the docs correctly, unless you use --no-stop-previous-version and/or --no-promote):

--promote

Promote the deployed version to receive all traffic. Overrides the default app/promote_by_default property value for this command invocation. Use --no-promote to disable.

--stop-previous-version

Stop the previously running version when deploying a new version that receives all traffic. Overrides the default app/stop_previous_version property value for this command invocation. Use --no-stop-previous-version to disable.

But, if you're using the standard environment and dynamic scaling, you should be aware that if the previous version handles a lot of traffic there may be service degradation/interruptions during the switch (it may take a while for the GAE autoscaler to determine how many new version instances it needs to spin up to handle that traffic, see Use traffic migration or splitting when switching to a new default version. You can perform these programmatically, see Not applicable to the flex environment, which doesn't support traffic splitting.

Also potentially of interest: GAE shutdown or restart all the active instances of a service/app

You can only control at which deployed version(s) is the traffic routed to by default, you can't really stop all traffic to a deployed version, it can always be reached via targeted routing.

BTW, the gcloud app versions [start|stop] commands are only applicable to manually scaled services:

It may only be used if the scaling module for your service has been set to manual.

Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
  • Thanks Dan! However, I don't want to deploy a new version. I want to turn off/on an existing service, and I think those commands are only available using `gcloud app deploy` – Mike Feb 25 '18 at 14:59
  • I _do_ want to deploy and switch to a new version, but the `--stop-previous-version` flag explicitly states that it does not work for automatically scaled versions. It's very annoying because, as far as I can tell, app engine _never_ turns off my auto scaled instances, even though they're receiving no traffic; presumably I could set the minimum instances to allow scaling to zero, but I don't want that for the _current_ version (I want a couple of instances live). – El Yobo Mar 05 '19 at 03:17