API

The VM Scaler API provides programmatic access to your workload definitions.

Authentication

A valid API key is required for API access. The API key for your account can be obtained by logging in to the web app, navigating to your Customer API key page.

Add the API key to your request by specifying it in the Authentication header.

Success and errors

The VM Scaler API communicates the status of the request with HTTP status codes.

If an error occurs, a 4XX or 5XX status code will be returned. The response body will contain a map with the keys error and message.

URLs

The URL for interacting with a workload follows the below format.

https://api.computesoftware.com/api/v1/workload/:workload-id/:workload-attribute

The :workload-attibute parameter is optional.

Workload ID

You can obtain a workload’s ID from the URL in the VM Scaler application. The workload ID for a workload at this URL https://app.computesoftware.com/workload/5bef4e2b-7d04-4dad-beee-01538d601c8a is 5bef4e2b-7d04-4dad-beee-01538d601c8a.

Operations

GET and POST are the supported operations for a workload. The workload attributes returned from the GET operation are the attributes allowed to change.

When updating a workload definitions via a POST, you must include an entity/id on all nested maps. This is how the system uniquely identifies nested maps in a workload. If an entity/id is not included, you will receive an error.

Workflow

Scenario: Blue/Green deployment

Blue/Green is a deployment technique that involves running two identical environments. At any time, only one of the environments is active. After the new environment is deemed production worthy, a switch is made to transfer production traffic to the new environment. This switch is typically done by either updating the user facing load balancer or pointing the DNS to a new endpoint.

After the switch is complete, it can take some time for traffic to migrate to the new environment depending on the switch over method used. If the listener rule on your load balancer is updated, it can take seconds or even up to minutes for traffic to switch over. This is due to connection draining and is an expected and useful behavior.

When performing the switch, you should update your workload definition to match the metrics produced from the new environment. This typically involves changing the CloudWatch metric dimensions and updating your Provisioning. These actions can be performed in a single API call.

Example Walkthrough

First let’s inspect our current workload definition.

curl -X GET \
  https://api.computesoftware.com/api/v1/workload/5cb8c4bb-b3ae-4548-bd1b-a62c98d81449 \
  -H 'Authorization: 6f10a527327f478ba0ce2115a59ecb02' 

Which gives us the below response.

{
    "workload/name": "Example",
    "workload/min-vm-count": 1,
    "workload/max-vm-count": 100,
    "workload/vm-delay-in-minutes": 5,
    "workload/metrics": [
        {
            "entity/id": "1e753a4d-b82c-4619-bf59-5b4f31ee64dc",
            "metric/name": "VM-Count",
            "metric/source": "metric.source/aws-cloudwatch",
            "metric.cloudwatch/region": "us-west-2",
            "metric.cloudwatch/namespace": "AWS/ApplicationELB",
            "metric.cloudwatch/metric-name": "HealthyHostCount",
            "metric.cloudwatch/dimensions-str": "TargetGroup=targetgroup/blue,LoadBalancer=app/myLoadBalancer",
            "metric.cloudwatch/statistic": "Average",
            "metric/core-metric-kw": "metric.core-metric/working-vms-amount",
            "metric/default-value": 0
        },
        {
            "entity/id": "2b54a970-0cee-4334-b9bd-cea017af4ebe",
            "metric/name": "Request-Count",
            "metric/source": "metric.source/aws-cloudwatch",
            "metric.cloudwatch/region": "us-west-2",
            "metric.cloudwatch/namespace": "AWS/ApplicationELB",
            "metric.cloudwatch/metric-name": "RequestCount",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer",
            "metric.cloudwatch/statistic": "Sum",
            "metric/core-metric-kw": "metric.core-metric/workload-amount",
            "metric/default-value": 0
        },
        {
            "entity/id": "2405277c-3ad8-4f44-9394-07e6974c7229",
            "metric/name": "CPU-Util",
            "metric/source": "metric.source/aws-cloudwatch",
            "metric.cloudwatch/region": "us-west-2",
            "metric.cloudwatch/namespace": "AWS/ECS",
            "metric.cloudwatch/metric-name": "CPUUtilization",
            "metric.cloudwatch/dimensions-str": "ClusterName=blue-cluster,ServiceName=example-service",
            "metric.cloudwatch/statistic": "Average",
            "metric/core-metric-kw": "metric.core-metric/cluster-state",
            "metric/default-value": 0
        },
        {
            "entity/id": "7a392504-c1d2-48d1-9024-397a646f78e6",
            "metric/name": "Average-Response-Time",
            "metric/source": "metric.source/aws-cloudwatch",
            "metric.cloudwatch/region": "us-west-2",
            "metric.cloudwatch/namespace": "AWS/ApplicationELB",
            "metric.cloudwatch/metric-name": "TargetResponseTime",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer",
            "metric.cloudwatch/statistic": "Average",
            "metric/default-value": 0.5
        },
        {
            "entity/id": "2385569e-e8ac-4801-8130-d4f760e93c27",
            "metric/name": "Failed-Requests",
            "metric/source": "metric.source/aws-cloudwatch",
            "metric.cloudwatch/region": "us-west-2",
            "metric.cloudwatch/namespace": "AWS/ApplicationELB",
            "metric.cloudwatch/metric-name": "HTTPCode_Target_5XX_Count",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer",
            "metric.cloudwatch/statistic": "Sum",
            "metric/default-value": 0
        }
    ],
    "workload/provisioning": {
        "entity/id": "69150e52-7765-4ca9-861a-34564de5321d",
        "provisioning/type": "aws.ecs",
        "provisioning.aws.ecs/region": "us-west-2",
        "provisioning.aws.ecs/cluster": "blue-cluster",
        "provisioning.aws.ecs/service": "example-service"
    },
    "workload/vm-price": {
        "entity/id": "25f301f0-1367-42b2-b887-fcc394110d1f",
        "vm-price/provider": "aws.ec2",
        "vm-price.aws.ec2/region": "us-west-2",
        "vm-price.aws.ec2/instance-type": "m5.24xlarge"
    }
}

We are going to update the metric dimensions and provisioning to point to the metrics produced from the new environment. Note that our Blue environment is using a Load Balancer named "app/myLoadBalancer" with the target group "targetgroup/blue" and is running in a Cluster named "blue-cluster" with a Service "example-service".

Our new Green environment has updated the target group on the Load Balancer to "targetgroup/green" and is provisioned in a new Cluster named "green-cluster".

We need to pass all the metrics to the API but we only need to change the attribute "metric.cloudwatch/dimensions-str" on the metrics and "provisioning.aws.ecs/cluster" on the provisioning. The maps will be merged with their existing values so including unchanged values is okay.

curl -X POST \
  https://api.computesoftware.com/api/v1/workload/5cb8c4bb-b3ae-4548-bd1b-a52c98d81449 \
  -H 'Authorization: 6f10a527327f478ba0ce2115a59ecb02' \
  -H 'Content-Type: application/json' \
  -d '{
    "workload/metrics": [
        {
            "entity/id": "1e753a4d-b82c-4619-bf59-5b4f31ee64dc",
            "metric/name": "VM-Count",
            "metric.cloudwatch/dimensions-str": "TargetGroup=targetgroup/green,LoadBalancer=app/myLoadBalancer"
        },
        {
            "entity/id": "2b54a970-0cee-4334-b9bd-cea017af4ebe",
            "metric/name": "Request-Count",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer"
        },
        {
            "entity/id": "2405277c-3ad8-4f44-9394-07e6974c7229",
            "metric/name": "CPU-Util",
            "metric.cloudwatch/dimensions-str": "ClusterName=green-cluster,ServiceName=example-service"
        },
        {
            "entity/id": "7a392504-c1d2-48d1-9024-397a646f78e6",
            "metric/name": "Average-Response-Time",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer"
        },
        {
            "entity/id": "2385569e-e8ac-4801-8130-d4f760e93c27",
            "metric/name": "Failed-Requests",
            "metric.cloudwatch/dimensions-str": "LoadBalancer=app/myLoadBalancer"
        }
    ],
    "workload/provisioning": {
        "entity/id": "69150e52-7765-4ca9-861a-34564de5321d",
        "provisioning.aws.ecs/cluster": "green-cluster"
    }
}'