tools/mig-scaler/deployment/modules/workflow/workflow.yaml (105 lines of code) (raw):
#
# Copyright 2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
main:
params: [args]
steps:
- init:
assign:
# Project containing the MIG. This does not have to be the same project
# as the workflow.
- project: ${args.project}
# Region or zone conatining the MIG. Only set one, use region for regional
# MIGs, or zone for zonal MIGs.
- region: ${map.get(args, "region")}
- region: ${if(region == "", null, region)}
- zone: ${map.get(args, "zone")}
- zone: ${if(zone == "", null, zone)}
# Name of the MIG
- name: ${args.name}
# Target size to scale the MIG up to (cannot scale the MIG down).
- target_size: ${args.target_size}
# Rate at which to add new instances, instances are added in batches.
# Adds <increment> instances every <wait> seconds.
- increment: ${args.increment}
- wait: ${args.wait}
# Terminate the workflow if goes beyond the deadline
- deadline: ${time.parse(args.deadline)}
- repeat:
switch:
# Check there is enough time remaining
- condition: ${sys.now() >= deadline}
next: deadline
- increment_size:
steps:
- get_current_size:
call: get_mig_size
args:
project: ${project}
region: ${region}
zone: ${zone}
name: ${name}
result: current_size
# Possible improvement in the future, take into account any operations
# in progress so that if the actual number of instances has not yet
# reached the target size, wait a bit longer to check everything starts.
- check_size:
switch:
- condition: ${current_size >= target_size}
next: end
# This doesn't take into account if instances are still starting. The
# expectation is that the wait will be set such that the previous batch
# will have finished starting.
- new_size:
assign:
- new_size: ${math.min(current_size + increment, target_size)}
- scale_mig:
call: set_mig_size
args:
project: ${project}
region: ${region}
zone: ${zone}
name: ${name}
size: ${new_size}
- check_deadline:
switch:
# Check there's enough time remaining for the wait
- condition: ${(sys.now() + wait) >= deadline}
next: deadline
# Not terminating early if size == target_size, if instances fail to start
# the MIG can reduce the target_size. So check the target_size on the next
# iteration and attempt to increase it.
- wait:
call: sys.sleep
args:
seconds: ${wait}
next: repeat
- deadline:
raise: "deadline reached"
get_mig_size:
params: [project, region, zone, name]
steps:
- get_size:
switch:
- condition: ${zone == null}
next: get_size_region
next: get_size_zone
- get_size_region:
call: googleapis.compute.v1.regionInstanceGroupManagers.get
args:
instanceGroupManager: ${name}
project: ${project}
region: ${region}
result: group
next: return
- get_size_zone:
call: googleapis.compute.v1.instanceGroupManagers.get
args:
instanceGroupManager: ${name}
project: ${project}
zone: ${zone}
result: group
next: return
- return:
return: ${group.targetSize}
set_mig_size:
params: [project, region, zone, name, size]
steps:
- set_size:
switch:
- condition: ${zone == null}
next: set_size_region
next: set_size_zone
- set_size_region:
call: googleapis.compute.v1.regionInstanceGroupManagers.resize
args:
instanceGroupManager: ${name}
project: ${project}
region: ${region}
size: ${size}
next: end
- set_size_zone:
call: googleapis.compute.v1.instanceGroupManagers.resize
args:
instanceGroupManager: ${name}
project: ${project}
zone: ${zone}
size: ${size}
next: end