[Yandex Cloud documentation](../../../index.md) > [Yandex Compute Cloud](../../index.md) > [Tutorials](../index.md) > [Working with an instance group with autoscaling](index.md) > Management console

# Running an autoscaling instance group using the management console, CLI, and API


To configure an [autoscaling instance group](index.md):

1. [Get your cloud ready](#before-begin).
1. [Set up your environment](#prepare).
1. [Create an autoscaling instance group with a network load balancer](#create-vm-group).
1. [Add a network load balancer with a target group](#connect-balancer).
1. [Test your instance group and network load balancer](#check-service).

If you no longer need the resources you created, [delete them](#clear-out).

## Get your cloud ready {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../../billing/quickstart/index.md) and [link](../../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../../resource-manager/concepts/resources-hierarchy.md).

1. If you do not have the Yandex Cloud CLI yet, [install it](../../../cli/quickstart.md#install).

1. To make sure the scripts from the step-by-step guide run correctly, download and install [jq](https://stedolan.github.io/jq/download/).

1. To check autoscaling, install [wrk](https://github.com/wg/wrk).

### Required paid resources {#paid-resources}

The infrastructure cost includes:
* Fee for continuously running [VMs](../../concepts/vm.md) (see [Compute Cloud pricing](../../pricing.md)).
* Fee for [network load balancers](../../../network-load-balancer/concepts/index.md) and traffic balancing (see [Network Load Balancer pricing](../../../network-load-balancer/pricing.md)).

## Set up your environment {#prepare}

1. Create a [service account](../../../iam/concepts/users/service-accounts.md) named `for-autoscale`. To create, update, and delete VM instances in your group, as well as integrate the group with Network Load Balancer, assign the [compute.editor](../../security/index.md#compute-editor) and [load-balancer.editor](../../../network-load-balancer/security/index.md#load-balancer-editor) roles to the service account:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder) where you want to create your service account.
     1. Navigate to **Identity and Access Management**.
     1. Click **Create service account**. In the window that opens:
        * In the **Name** field, specify `for-autoscale`.
        * To assign the service account a role for the current folder, click ![image](../../../_assets/console-icons/plus.svg) **Add role** and select `compute.editor` and `load-balancer.editor`.
        * Click **Create**.

   - CLI {#cli}

     1. Create a service account:

        The folder used by default is the one specified when [creating](../../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

        ```bash
        yc iam service-account create --name for-autoscale
        ```

        Result:

        ```text
        id: ajelabcde12f********
        folder_id: b0g12ga82bcv********
        created_at: "2020-11-30T14:32:18.900092Z"
        name: for-autoscale
        ```

     1. Assign the `compute.editor` role to the service account:

        ```bash
        yc resource-manager folder add-access-binding <folder_ID> \
          --role compute.editor \
          --subject serviceAccount:<service_account_ID>
        ```

     1. Assign the `load-balancer.editor` role to the service account:

        ```bash
        yc resource-manager folder add-access-binding <folder_ID> \
          --role load-balancer.editor \
          --subject serviceAccount:<service_account_ID>
        ```

   - API {#api}

     Use the [create](../../../iam/api-ref/ServiceAccount/create.md) REST API method for the [ServiceAccount](../../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/Create](../../../iam/api-ref/grpc/ServiceAccount/create.md) gRPC API call.

   {% endlist %}

1. Create a [network](../../../vpc/concepts/network.md#network) named `yc-auto-network` and [subnets](../../../vpc/concepts/network.md#subnet) in two availability zones:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you want to create your network.
     1. Navigate to **Virtual Private Cloud**.
     1. Click **Create network**.
     1. In the **Name** field, enter `yc-auto-network`.
     1. In the **Advanced** field, enable **Create subnets**.
     1. Click **Create network**.

   - CLI {#cli}

     1. Create a network:

        ```bash
        yc vpc network create --name yc-auto-network
        ```

        Result:

        ```text
        id: enpabce123hd********
        folder_id: b0g12ga82bcv********
        created_at: "2020-11-30T14:57:15Z"
        name: yc-auto-network
        ```

     1. Create a subnet in the `ru-central1-a` availability zone:

        ```bash
        yc vpc subnet create \
          --network-id enpabce123hd******** \
          --range 192.168.1.0/24 \
          --zone ru-central1-a
        ```

        Result:

        ```text
        id: e1lnabc23r1c********
        folder_id: b0g12ga82bcv********
        created_at: "2020-11-30T16:23:12Z"
        network_id: enpabce123hd********
        zone_id: ru-central1-a
        v4_cidr_blocks:
        - 192.168.1.0/24
        ```

     1. Create a subnet in the `ru-central1-b` availability zone:

        ```bash
        yc vpc subnet create \
          --network-id enpabce123hd******** \
          --range 192.168.2.0/24 \
          --zone ru-central1-b
        ```

        Result:

        ```text
        id: b1csa2b3clid********
        folder_id: b0g12ga82bcv********
        created_at: "2020-11-30T16:25:02Z"
        network_id: enpabce123hd********
        zone_id: ru-central1-b
        v4_cidr_blocks:
        - 192.168.2.0/24
        ```

   - API {#api}

     1. Create a network.

        Use the [create](../../../vpc/api-ref/Network/create.md) REST API method for the [Network](../../../vpc/api-ref/Network/index.md) resource or the [NetworkService/Create](../../../vpc/api-ref/grpc/Network/create.md) gRPC API call.
     1. Create subnets in the `ru-central1-a` and `ru-central1-b` availability zones.

        Use the [create](../../../vpc/api-ref/Subnet/create.md) REST API method for the [Subnet](../../../vpc/api-ref/Subnet/index.md) resource or the [SubnetService/Create](../../../vpc/api-ref/grpc/Subnet/create.md) gRPC API call.

   {% endlist %}

1. Create a [security group](../../../vpc/concepts/security-groups.md):

   {% list tabs group=instructions %}

   - Management console {#console}

     1. Open the [management console](https://console.yandex.cloud).
     1. Navigate to **Virtual Private Cloud**.
     1. Open the **Security groups** tab.
     1. Create a security group for the load balancer:
        1. Click **Create group**.
        1. Enter the group **Name**: `sg-autoscale`.
        1. Select `yc-auto-network` for **Network**.
        1. Under **Rules**, create rules by following the steps below the table:

           Traffic<br>direction | Description | Port<br>range | Protocol | Source type /<br>destination type | Source /<br>destination
           --- | --- | --- | --- | --- | ---
           Egress | any | All | Any | CIDR | 0.0.0.0/0
           Ingress | ext-http | 80 | TCP | CIDR | 0.0.0.0/0
           Inbound | healthchecks | 80 | TCP | Load balancer health checks | —

           1. Select the **Egress** or **Ingress** tab.
           1. Click **Add rule**.
           1. In the **Port range** field of the window that opens, specify a port or range of ports open for inbound or outbound traffic.
           1. In the **Protocol** field, specify the protocol or leave **Any** to allow traffic over any protocol.
           1. In the **Purpose** or **Source** field, select the rule purpose:
              * **CIDR**: Rule will apply to the range of [IP addresses](../../../vpc/concepts/address.md). In the **CIDR blocks** field, specify the CIDR ranges of the source or destination subnets. To add more CIDRs, click **Add CIDR**.
              * **Security group**: Rule will apply to the VMs from the current group or the selected security group.
              * **Load balancer health checks**: Rule allowing a load balancer to health-check VMs.
           1. Click **Save**. Repeat these steps to create all rules from the table.
        1. Click **Save**.

   {% endlist %}

## Create an autoscaling instance group with a network load balancer {#create-vm-group}

1. In this tutorial, you will be creating all instance groups from a [Container Optimized Image](../../../cos/concepts/index.md). Each VM instance will have a Docker container running a web server that emulates the service load.

   Get the ID of the latest version of the [public](../../operations/images-with-pre-installed-software/get-list.md) Container Optimized Image.
   
   A Container Optimized Image in [Container Registry](../../../container-registry/index.md) may get updates and modifications that come with new releases. This will not automatically update the [VM](../../concepts/vm.md) image to the latest version. To create an [instance group](../../concepts/instance-groups/index.md) with the latest Container Optimized Image version, perform an availability check:
   
   {% list tabs group=instructions %}
   
   - CLI {#cli}
   
     ```bash
     yc compute image get-latest-from-family container-optimized-image --folder-id standard-images
     ```
   
     Result:
   
     ```bash
     id: <latest_COI_version_ID>
     folder_id: standard-images
     ...
     ```
   
   - Yandex Cloud Marketplace {#marketplace}
   
     1. Go to the Cloud Marketplace page and select the image with the configuration you need:
        * [Container Optimized Image](https://yandex.cloud/en/marketplace/products/yc/container-optimized-image).
        * [Container Optimized Image GPU](https://yandex.cloud/en/marketplace/products/yc/container-optimized-image-gpu).
     1. Under **Product IDs**, copy the `image_id` value.
   
   {% endlist %}

1. Save the specification of the instance group with a network load balancer to the `specification.yaml` file:

   ```yaml
   name: auto-group
   service_account_id: <service_account_ID>
   scale_policy:
     auto_scale:
       min_zone_size: 1
       max_size: 6
       measurement_duration: 60s
       warmup_duration: 120s
       stabilization_duration: 60s
       initial_size: 2
       cpu_utilization_rule:
         utilization_target: 40
   deploy_policy:
     max_unavailable: 1
   allocation_policy:
     zones:
       - zone_id: ru-central1-a
       - zone_id: ru-central1-b
   load_balancer_spec:
     target_group_spec:
       name: auto-group-tg
   instance_template:
     service_account_id: <service_account_ID>
     platform_id: standard-v3
     resources_spec:
       memory: 2G
       cores: 2
       core_fraction: 100
     metadata:
       docker-container-declaration: |-
         spec:
           containers:
           - image: cr.yandex/yc/demo/web-app:v1
             securityContext:
               privileged: false
             tty: false
             stdin: false
     boot_disk_spec:
       mode: READ_WRITE
       disk_spec:
         type_id: network-hdd
         size: 30G
         image_id: fd8iv792kira******** # ID of the public Container Optimized Image
     network_interface_specs:
       - network_id: <cloud_network_ID>
         primary_v4_address_spec: { one_to_one_nat_spec: { ip_version: IPV4 }}
   ```

1. In `specification.yaml`, replace the values in angle brackets with actual values from the previous steps.
1. Create an instance group named `auto-group` using `specification.yaml`:

   {% list tabs group=instructions %}

   - CLI {#cli}

     Run this command:

     ```bash
     yc compute instance-group create --file=specification.yaml
     ```

     Result:

     ```text
     done (2m45s)
     id: cl0hmabc1nd2********
     folder_id: b0g12ga82bcv********
     ...
       target_group_id: enpoi5jhfps3********
     ...
         name: auto-group-tg
     service_account_id: ajelabcde12f********
     status: ACTIVE
     ```

   - API {#api}

     Use the [CreateFromYaml](../../instancegroup/api-ref/InstanceGroup/createFromYaml.md) method for the `InstanceGroup` resource.

   {% endlist %}

1. Check your instance group:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you created the instance group.
     1. Navigate to **Compute Cloud**.
     1. In the left-hand panel, click ![image](../../../_assets/console-icons/layers-3-diagonal.svg) **Instance groups**.
     1. Select `auto-group`.

   - CLI {#cli}

     ```bash
     yc compute instance-group list-instances auto-group
     ```

     Result:

     ```text
     +----------------------+---------------------------+----------------+--------------+------------------------+----------------+
     |     INSTANCE ID      |           NAME            |  EXTERNAL IP   | INTERNAL IP  |         STATUS         | STATUS MESSAGE |
     +----------------------+---------------------------+----------------+--------------+------------------------+----------------+
     | epdab0c1ji2a******** | cl0habce1nd2********-fned | 84.201.163.202 | 192.168.1.34 | RUNNING_ACTUAL [4m26s] |                |
     | ef0uabc1s2fb******** | cl0habce1nd2********-craq | 130.193.56.102 | 192.168.2.19 | RUNNING_ACTUAL [4m14s] |                |
     +----------------------+---------------------------+----------------+--------------+------------------------+----------------+
     ```

   - API {#api}

     To view a list of the instance groups you created, use the [list](../../instancegroup/api-ref/InstanceGroup/list.md) REST API method for the [InstanceGroup](../../instancegroup/api-ref/InstanceGroup/index.md) resource or the [InstanceGroupService/List](../../instancegroup/api-ref/grpc/InstanceGroup/list.md) gRPC API call.

   {% endlist %}

## Add a network load balancer with a target group {#connect-balancer}

1. Create a network load balancer named `group-balancer` and add it to the instance group you created:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you want to create a load balancer.
     1. Navigate to **Network Load Balancer**.
     1. Click **Create a network load balancer**.
     1. Enter `group-balancer` as the name.
     1. In the **Public address** field, specify `Auto`.
     1. Under **Listeners**, click **Add listener**. In the window that opens, specify:
        * **Name**: `http`.
        * **Port**: `80`. The load balancer will listen for inbound traffic on this port.
        * **Target port**: `80`. The load balancer will redirect traffic to this port.
        * Click **Add**.
     1. Under **Target groups**, click **Add target group**.
     1. In the **Target group** field, select `auto-group-tg` and click **Configure**. In the window that opens, specify:
        * **Name**: `tcp`
        * **Type**: `TCP`
        * **Port**: `80`
        * Click **Apply**.
     1. Click **Create**.

   - CLI {#cli}

     ```bash
     yc load-balancer network-load-balancer create \
       --listener external-ip-version=ipv4,name=http,port=80,protocol=tcp,target-port=80 \
       --name group-balancer \
       --target-group healthcheck-name=tcp,healthcheck-tcp-port=80,target-group-id=enpoi5jhfps3********
     ```

     Result:

     ```text
     done (16s)
     id: b0rbabc1m2ed********
     folder_id: b0g12ga82bcv********
     ...
         healthy_threshold: "2"
         tcp_options:
           port: "80"
     ```

   - API {#api}

     1. Create a load balancer using the [create](../../../network-load-balancer/api-ref/NetworkLoadBalancer/create.md) REST API method for the [NetworkLoadBalancer](../../../network-load-balancer/api-ref/NetworkLoadBalancer/index.md) resource or the [NetworkLoadBalancerService/Create](../../../network-load-balancer/api-ref/grpc/NetworkLoadBalancer/create.md) gRPC API call.
     1. Add a listener to the load balancer using the [addListener](../../../network-load-balancer/api-ref/NetworkLoadBalancer/addListener.md) REST API method for the `NetworkLoadBalancer` resource or the [NetworkLoadBalancerService/AddListener](../../../network-load-balancer/api-ref/grpc/NetworkLoadBalancer/addListener.md) gRPC API call.
     1. Attach the target group to the load balancer using the [attachTargetGroup](../../../network-load-balancer/api-ref/NetworkLoadBalancer/attachTargetGroup.md) REST API method for the `NetworkLoadBalancer` resource or the [NetworkLoadBalancerService/AttachTargetGroup](../../../network-load-balancer/api-ref/grpc/NetworkLoadBalancer/attachTargetGroup.md) gRPC API call.
     1. Add the load balancer to the instance group using the [addTargets](../../../network-load-balancer/api-ref/TargetGroup/addTargets.md) REST API method for the [TargetGroup](../../../network-load-balancer/api-ref/TargetGroup/index.md) resource or the [TargetGroupService/AddTargets](../../../network-load-balancer/api-ref/grpc/TargetGroup/addTargets.md) gRPC API call.

   {% endlist %}

1. Check the `group-balancer` network load balancer and make sure it is linked to the instance group:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you created the load balancer.
     1. Navigate to **Network Load Balancer**.
     1. Select `group-balancer`.

   - CLI {#cli}

     ```bash
     yc load-balancer network-load-balancer list
     ```

     Result:

     ```text
     +----------------------+----------------+-----------------+----------+----------------+------------------------+--------+
     |          ID          |      NAME      |    REGION ID    |   TYPE   | LISTENER COUNT | ATTACHED TARGET GROUPS | STATUS |
     +----------------------+----------------+-----------------+----------+----------------+------------------------+--------+
     | b0rbabc1m2ed******** | group-balancer | ru-central1 | EXTERNAL |              1 | b0rdabckribe********   | ACTIVE |
     +----------------------+----------------+-----------------+----------+----------------+------------------------+--------+
     ```

   - API {#api}

     Use the [list](../../../network-load-balancer/api-ref/NetworkLoadBalancer/list.md) REST API method for the [NetworkLoadBalancer](../../../network-load-balancer/api-ref/NetworkLoadBalancer/index.md) resource or the [NetworkLoadBalancerService/List](../../../network-load-balancer/api-ref/grpc/NetworkLoadBalancer/list.md) gRPC API call.

   {% endlist %}

## Test your instance group and network load balancer {#check-service}

1. Create a load on an instance.

   To do this, save the script named `request.sh` to the home directory. The script will send a request to one of the VMs through the `group-balancer` load balancer. The request will utilize 100% CPU for 30 seconds.

   ```bash
   EXTERNAL_IP=$(yc load-balancer network-load-balancer get group-balancer --format=json | jq -r .listeners[0].address)

   curl "http://$EXTERNAL_IP/burn-cpu?time=30000&load=100"
   ```

1. Run the script:

   {% list tabs group=instructions %}

   - CLI {#cli}

     ```bash
     sh request.sh
     ```

     Result:

     ```text
     projects/b0g12ga82bcv********/zones/ru-central1-b
     ```

   {% endlist %}

1. View the instance utilization:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you created the instance group.
     1. Navigate to **Compute Cloud**.
     1. In the left-hand panel, click ![image](../../../_assets/console-icons/layers-3-diagonal.svg) **Instance groups**.
     1. Select `auto-group`.
     1. Navigate to the **Monitoring** tab.

        The load balancer sent the request to an instance in the group. In the availability zone this instance belongs to, the average CPU utilization is higher than in other zones (see the **Average CPU utilization in zone** chart).

   {% endlist %}

### Autoscaling test {#check-highload}

To test autoscaling for your instance group, increase the CPU utilization of each instance. In the `specification.yaml` file, the `scale_policy.auto_scale.cpu_utilization_rule.utilization_target` parameter is set to `40`: it means that the target utilization level is 40% CPU. If you exceed the target utilization, the number of VMs in the group will increase.
1. Increase the utilization for the instance group.

   To do this, save the script named `load.sh` to the home directory. The script sends requests to the instance group through 12 threads for 10 minutes. Each VM instance utilizes 20% CPU on each core that processes the request. The instance group utilization is 240% CPU at any given time. To be sure that requests are evenly distributed across the instances in the group, the script executes multiple parallel requests utilizing 20% CPU rather than one request utilizing 240% CPU.

   ```bash
   EXTERNAL_IP=$(yc load-balancer network-load-balancer get group-balancer --format=json | jq -r .listeners[0].address)

   wrk -H "Connection: close" -t12 -c12 -d10m "http://$EXTERNAL_IP/burn-cpu?time=5000&load=20"
   ```

1. Run the script:

   {% list tabs group=instructions %}

   - CLI {#cli}

     ```bash
     sh load.sh
     ```

     Result:

     ```text
     Running 10m test @ http://130.193.56.111/burn-cpu?time=5000&load=20
       12 threads and 12 connections
       Thread Stats   Avg      Stdev     Max   +/- Stdev
     ...
     Requests/sec: 15.04
     Transfer/sec: 3.20KB
     ```

   {% endlist %}

1. View the utilization levels:

   {% list tabs group=instructions %}

   - Management console {#console}

     1. In the [management console](https://console.yandex.cloud), select the folder where you created the `auto-group` instance group.
     1. Navigate to **Compute Cloud**.
     1. In the left-hand panel, click ![image](../../../_assets/console-icons/layers-3-diagonal.svg) **Instance groups**.
     1. Select `auto-group`.
     1. Navigate to the **Monitoring** tab.
        The chart **Number of instances in zone** shows how the number of instances changed in each availability zone. The chart **Average CPU utilization in zone** shows average CPU utilization in each availability zone.
     1. Navigate to the **Logs** tab.
        The page displays messages relating to the instance group autoscaling.

     The total utilization of 240% CPU was evenly distributed between two instances in two availability zones and exceeded the target utilization of 40% CPU. [Yandex Compute Cloud](../../index.md) created one instance more in each availability zone to result in four instances in the group. When the script stopped utilizing the CPU, Compute Cloud automatically decreased the number of instances in the group to two.

   {% endlist %}

## How to delete the resources you created {#clear-out}

To stop paying for the resources you created:
1. [Delete](../../../network-load-balancer/operations/load-balancer-delete.md) the network load balancer.
1. [Delete](../../operations/instance-groups/delete.md) the instance group.

#### See also {#see-also}

* [Working with an instance group with autoscaling using Terraform](terraform.md)