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