Yandex Cloud
Search
Contact UsGet started
  • Pricing
  • Customer Stories
  • Documentation
  • Blog
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • AI Studio
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Center for Technologies and Society
    • Yandex Cloud Partner program
  • Pricing
  • Customer Stories
  • Documentation
  • Blog
© 2025 Direct Cursus Technology L.L.C.
Tutorials
    • All tutorials
    • Architecture and protection of a basic web service
    • Cost analysis by resource using Object Storage
      • Configuring a fault-tolerant architecture in Yandex Cloud
      • Integrating an L7 load balancer with Cloud CDN and Object Storage
        • Overview
        • Management console, CLI, and API
        • Terraform
      • Autoscaling an instance group to process messages enqueued in Message Queue
      • Updating an instance group under load
      • Creating a budget trigger that invokes a function to stop a VM
      • Deploying a fault-tolerant architecture with preemptible VMs
      • Creating triggers that invoke a function to stop a VM and send a Telegram notification

In this article:

  • Get your cloud ready
  • Required paid resources
  • Create your infrastructure
  • Test your instance group and network load balancer
  • Autoscaling test
  • How to delete the resources you created
  1. Basic infrastructure
  2. Fault tolerance and scaling
  3. Working with an autoscaling instance group
  4. Terraform

Running a VM group with autoscaling using Terraform

Written by
Yandex Cloud
Updated at August 14, 2025
  • Get your cloud ready
    • Required paid resources
  • Create your infrastructure
  • Test your instance group and network load balancer
    • Autoscaling test
  • How to delete the resources you created

To create an infrastructure for an instance group with an autoscaling policy using Terraform:

  1. Get your cloud ready.
  2. Create your infrastructure.
  3. Test your instance group and network load balancer.

If you no longer need the resources you created, delete them.

Get your cloud readyGet your cloud ready

Sign up for Yandex Cloud and create a billing account:

  1. Navigate to the management console and log in to Yandex Cloud or create a new account.
  2. On the Yandex Cloud Billing page, make sure you have a billing account linked and it has the ACTIVE or TRIAL_ACTIVE status. If you do not have a billing account, create one and link a cloud to it.

If you have an active billing account, you can navigate to the cloud page to create or select a folder for your infrastructure.

Learn more about clouds and folders here.

  1. If you do not have the Yandex Cloud CLI yet, install it.

  2. To make sure the scripts from the step-by-step guide run correctly, download and install jq.

  3. To check autoscaling, install wrk.

Required paid resourcesRequired paid resources

The infrastructure cost includes:

  • Fee for continuously running VMs (see Compute Cloud pricing).
  • Fee for network load balancers and traffic balancing (see Network Load Balancer pricing).

Create your infrastructureCreate your infrastructure

With Terraform, you can quickly create a cloud infrastructure in Yandex Cloud and manage it using configuration files. These files store the infrastructure description written in HashiCorp Configuration Language (HCL). If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.

Terraform is distributed under the Business Source License. The Yandex Cloud provider for Terraform is distributed under the MPL-2.0 license.

For more information about the provider resources, see the relevant documentation on the Terraform website or its mirror.

To create an autoscaling instance group infrastructure with Terraform:

  1. Install Terraform and specify the Yandex Cloud provider installation source (see Configure a provider, step 1).

  2. Prepare your infrastructure description files:

    Ready-made configuration
    Manually
    1. Clone the repository with configuration files:

      git clone https://github.com/yandex-cloud-examples/yc-vm-group-with-autoscale.git
      
    2. Navigate to the repository directory. Make sure it now contains the following files:

      • vm-autoscale.tf: New infrastructure configuration.
      • declaration.yaml: Description of the Docker container with a web server that will simulate the VM load.
      • config.tpl: VM user description.
      • vm-autoscale.auto.tfvars: User data.
    1. Create a directory for configuration files.
    2. In the directory, create:
      1. vm-autoscale.tf configuration file:

        vm-autoscale.tf
        # Declaring variables for confidential parameters
        
        variable "folder_id" {
          type = string
        }
        
        variable "vm_user" {
          type = string
        }
        
        variable "ssh_key" {
          type      = string
          sensitive = true
        }
        
        # Configuring a provider
        
        terraform {
          required_providers {
            yandex = {
              source = "yandex-cloud/yandex"
              version = ">= 0.47.0"
            }
          }
        }
        
        provider "yandex" {
          zone = "ru-central1-a"
        }
        
        # Creating a service account and assigning roles to it
        
        resource "yandex_iam_service_account" "for-autoscale" {
          name = "for-autoscale"
        }
        
        resource "yandex_resourcemanager_folder_iam_member" "vm-autoscale-sa-role-compute" {
          folder_id = var.folder_id
          role      = "editor"
          member    = "serviceAccount:${yandex_iam_service_account.for-autoscale.id}"
        }
        
        # Creating a cloud network and subnets
        
        resource "yandex_vpc_network" "vm-autoscale-network" {
          name = "vm-autoscale-network"
        }
        
        resource "yandex_vpc_subnet" "vm-autoscale-subnet-a" {
          name           = "vm-autoscale-subnet-a"
          zone           = "ru-central1-a"
          v4_cidr_blocks = ["192.168.1.0/24"]
          network_id     = yandex_vpc_network.vm-autoscale-network.id
        }
        
        resource "yandex_vpc_subnet" "vm-autoscale-subnet-b" {
          name           = "vm-autoscale-subnet-b"
          zone           = "ru-central1-b"
          v4_cidr_blocks = ["192.168.2.0/24"]
          network_id     = yandex_vpc_network.vm-autoscale-network.id
        }
        
        # Creating a security group
        
        resource "yandex_vpc_security_group" "sg-1" {
          name                = "sg-autoscale"
          network_id          = yandex_vpc_network.vm-autoscale-network.id
          egress {
            protocol          = "ANY"
            description       = "any"
            v4_cidr_blocks    = ["0.0.0.0/0"]
          }
          ingress {
            protocol          = "TCP"
            description       = "ext-http"
            v4_cidr_blocks    = ["0.0.0.0/0"]
            port              = 80
          }
          ingress {
            protocol          = "TCP"
            description       = "healthchecks"
            predefined_target = "loadbalancer_healthchecks"
            port              = 80
          }
        }
        
        # Specifying a prebuilt VM image
        
        data "yandex_compute_image" "autoscale-image" {
          family = "container-optimized-image"
        }
        
        # Creating an instance group
        
        resource "yandex_compute_instance_group" "autoscale-group" {
          name                = "autoscale-vm-ig"
          folder_id           = var.folder_id
          service_account_id  = yandex_iam_service_account.for-autoscale.id
          instance_template {
        
            platform_id = "standard-v3"
            resources {
              memory = 2
              cores  = 2
            }
          
            boot_disk {
              mode = "READ_WRITE"
              initialize_params {
                image_id = data.yandex_compute_image.autoscale-image.id
                size     = 30
              }
            }
        
            network_interface {
              network_id = yandex_vpc_network.vm-autoscale-network.id
              subnet_ids = [
                yandex_vpc_subnet.vm-autoscale-subnet-a.id,
                yandex_vpc_subnet.vm-autoscale-subnet-b.id
              ]
              security_group_ids = [ yandex_vpc_security_group.sg-1.id ]
              nat                = true
            }
        
            metadata = {
              user-data = templatefile("config.tpl", {
                VM_USER = var.vm_user
                SSH_KEY = var.ssh_key
              })
              docker-container-declaration = file("declaration.yaml")
            }
          }
        
          scale_policy {
            auto_scale {
              initial_size           = 2
              measurement_duration   = 60
              cpu_utilization_target = 40
              min_zone_size          = 1
              max_size               = 6
              warmup_duration        = 120
            }
          }
        
          allocation_policy {
            zones = [
              "ru-central1-a",
              "ru-central1-b"
            ]
          }
        
          deploy_policy {
            max_unavailable = 1
            max_expansion   = 0
          }
        
          load_balancer {
            target_group_name        = "auto-group-tg"
            target_group_description = "load balancer target group"
          }
        }
        
        # Creating a network load balancer
        
        resource "yandex_lb_network_load_balancer" "balancer" {
          name = "group-balancer"
        
          listener {
            name        = "http"
            port        = 80
            target_port = 80
          }
        
          attached_target_group {
            target_group_id = yandex_compute_instance_group.autoscale-group.load_balancer[0].target_group_id
            healthcheck {
              name = "tcp"
              tcp_options {
                port = 80
              }
            }
          }
        }
        
      2. declaration.yaml file with a description of the Docker container with a web server that will simulate the VM load:

        declaration.yaml
        spec:
        containers:
        - image: cr.yandex/yc/demo/web-app:v1
          securityContext:
            privileged: false
          tty: false
          stdin: false
        
      3. config.tpl VM user description file:

        config.tpl
        users:
          - name: "${VM_USER}"
            groups: sudo
            shell: /bin/bash
            sudo: 'ALL=(ALL) NOPASSWD:ALL'
            ssh_authorized_keys:
              - "${SSH_KEY}"
        
      4. vm-autoscale.auto.tfvars user data file:

        vm-autoscale.auto.tfvars
        folder_id = "<folder_ID>"
        vm_user   = "<VM_username>"
        ssh_key   = "<public_SSH_key_contents>"
        

    Learn more about the properties of Terraform resources in the relevant Terraform articles:

    • Service account: yandex_iam_service_account.
    • Network: yandex_vpc_network.
    • Subnets: yandex_vpc_subnet.
    • Security group: yandex_vpc_security_group.
    • Instance group: yandex_compute_instance_group.
    • Network load balancer: yandex_lb_network_load_balancer.
  3. In the vm-autoscale.auto.tfvars file, set the following user-defined properties:

    • folder_id: Folder ID.
    • vm_user: VM user name.
    • ssh_key: Public SSH key file contents required to authenticate the user on the VM. For more information, see Creating an SSH key pair.
  4. Create the resources:

    1. In the terminal, go to the directory where you edited the configuration file.

    2. Make sure the configuration file is correct using this command:

      terraform validate
      

      If the configuration is correct, you will get this message:

      Success! The configuration is valid.
      
    3. Run this command:

      terraform plan
      

      You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.

    4. Apply the changes:

      terraform apply
      
    5. Type yes and press Enter to confirm the changes.

Once you created the infrastructure, test your instance group and network load balancer.

Test your instance group and network load balancerTest your instance group and network load balancer

  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.

    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"
    
  2. Run the script:

    CLI
    sh request.sh
    

    Result:

    projects/b0g12ga82bcv********/zones/ru-central1-b
    
  3. View the instance utilization:

    Management console
    1. In the management console, select the folder where you created the instance group.

    2. Select Compute Cloud.

    3. In the left-hand panel, click Instance groups.

    4. Select auto-group.

    5. 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).

Autoscaling testAutoscaling test

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.

    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"
    
  2. Run the script:

    CLI
    sh load.sh
    

    Result:

    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
    
  3. View the utilization levels:

    Management console
    1. In the management console, select the folder where you created the auto-group instance group.
    2. Select Compute Cloud.
    3. In the left-hand panel, click Instance groups.
    4. Select auto-group.
    5. 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.
    6. 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 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.

How to delete the resources you createdHow to delete the resources you created

To stop paying for the resources you created:

  1. Open the vm-autoscale.tf configuration file and delete your infrastructure description from it.

  2. Apply the changes:

    1. In the terminal, go to the directory where you edited the configuration file.

    2. Make sure the configuration file is correct using this command:

      terraform validate
      

      If the configuration is correct, you will get this message:

      Success! The configuration is valid.
      
    3. Run this command:

      terraform plan
      

      You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.

    4. Apply the changes:

      terraform apply
      
    5. Type yes and press Enter to confirm the changes.

See alsoSee also

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

Was the article helpful?

Previous
Management console, CLI, and API
Next
Overview
© 2025 Direct Cursus Technology L.L.C.