Yandex Cloud
  • Services
  • Solutions
  • Why Yandex Cloud
  • Pricing
  • Documentation
  • Contact us
Get started
Language / Region
© 2022 Yandex.Cloud LLC
Practical guidelines
  • Web service
    • All tutorials
    • Static website in Object Storage
    • Website on LAMP or LEMP stack
    • Fault-tolerant website with load balancing by Network Load Balancer
    • Fault-tolerant website with load balancing by Application Load Balancer
    • Fault-tolerant website using DNS load balancing
    • Joomla website with PostgreSQL
    • WordPress website
    • WordPress website on a MySQL database
    • Transferring a WordPress website from a different hosting provider to Yandex Cloud
    • 1C-Bitrix website
    • Integrating an L7 load balancer with the Cloud CDN and Object Storage
    • Blue-green and canary deployment of service versions
  • Online stores
    • All tutorials
    • 1C-Bitrix online store
    • Opencart online store
  • Data archive
    • All tutorials
    • Single-node file server
    • Configuring an SFTP server on Centos 7
    • Backup to Object Storage via Acronis Backup
    • Backup to Object Storage via CloudBerry Desktop Backup
    • Backup to Object Storage via Duplicati
    • Backup to Object Storage via Bacula
    • Backup to Object Storage via Veritas Backup Exec
    • Digitizing archives in Yandex Vision
  • Test environment
    • All tutorials
    • Testing applications with GitLab
    • Creating test VMs using GitLab CI
    • High-performance computing on preemptible VMs
    • Emulating multiple IoT devices
    • gRPC service load testing
    • Using Phantom to run a fixed-load HTTPS test
    • Using Pandora to run a step-load HTTPS test
  • Performing infrastructure management
    • All tutorials
    • Getting started with Terraform
    • Uploading Terraform states to Object Storage
    • Getting started with Packer
    • Automating VM image builds using Jenkins
    • Continuous deployment of containerized applications using GitLab
    • Creating a cluster of 1C:Enterprise Linux servers with a Managed Service for PostgreSQL cluster
    • Creating a cluster of 1C:Enterprise Windows servers with SQL Server
    • Migrating to Yandex Cloud using Hystax Acura
    • Fault protection with Hystax Acura
    • Creating a VM backup with Hystax Acura Backup
    • Configuring a fault-tolerant architecture in Yandex Cloud
    • Creating an SAP program in Yandex Cloud
  • Building a data platform
    • All tutorials
    • Syncing MySQL data using Yandex Data Transfer
    • Migrating databases from Yandex Managed Service for MySQL to MySQL
    • Configuring a managed databased in a ClickHouse cluster for Graphite
    • Exchanging data between Yandex Managed Service for ClickHouse and Yandex Data Proc
    • Managing data schemas in Yandex Managed Service for Apache Kafka®
    • Using Managed Schema Registry with Yandex Managed Service for Apache Kafka®
    • Using Confluent Schema Registry with Yandex Managed Service for Apache Kafka®
    • Migrating databases from Yandex Managed Service for MySQL to MySQL
    • Delivering data from Yandex Managed Service for PostgreSQL to Yandex Managed Service for Apache Kafka® using Debezium
    • Delivering data from Yandex Managed Service for PostgreSQL to Yandex Managed Service for Apache Kafka® using Yandex Data Transfer
    • Migrating databases to Yandex Managed Service for SQL Server
    • Migrating databases from Yandex Managed Service for SQL Server to a third-party SQL Server cluster
    • Transferring data from PostgreSQL to ClickHouse using Yandex Data Transfer
    • Configuring Yandex Cloud DNS for accessing managed database clusters from other cloud networks
    • Transferring a database to Yandex Managed Service for Redis
    • Migrating to Yandex Managed Service for Elasticsearch using the Reindex API
    • Configuring Kafka Connect for Yandex Managed Service for Apache Kafka® clusters
    • Using initialization actions to configure GeeseFS in Yandex Data Proc
    • Migrating databases from a third-party MySQL cluster to a Yandex Managed Service for MySQL cluster
    • Importing data from Yandex Managed Service for MySQL to Yandex Data Proc using Sqoop
    • Importing data from Yandex Managed Service for PostgreSQL to Yandex Data Proc using Sqoop
  • Windows in Yandex Cloud
    • All tutorials
    • Deploying Active Directory
    • Deploying Microsoft Exchange
    • Deploying Remote Desktop Services
    • Deploying an Always On availability group
    • Deploying an Always On availability group with an internal network load balancer
    • Deploying Remote Desktop Gateway
  • Network routing
    • All tutorials
    • Routing through a NAT instance
    • Creating a VPN tunnel
    • Installing a Cisco CSR1000v virtual router
    • Installing a Mikrotik CHR virtual router
    • Connecting to a cloud network using OpenVPN
    • Configuring networks for Yandex Data Proc
  • Data visualization and analytics
    • All tutorials
    • Visualizing data from a CSV file
    • Creating and publishing a chart with a map of Moscow from a CSV file
    • Analyzing a store chain's sales based on data from a ClickHouse DB
    • Analyzing open data on road accidents in Russia
    • Analyzing sales and locations of pizzerias based on data from ClickHouse DB and Marketplace
    • Web analytics with a connection to Yandex.Metrica
    • Web analytics with funnels and cohorts calculated based on Yandex.Metrica data
    • Mobile app analytics based on AppMetrica data
    • Analyzing Yandex Music podcast statistics (for podcasters)
    • Visualizing data with a SQL chart
    • Mobile app customer journey analytics based on AppMetrica data
    • Analyzing Object Storage logs in DataLens
  • Internet of things
    • Operating manuals for the Internet of Things
    • Status monitoring of geographically distributed devices
    • Monitoring sensor readings and event notifications
  • Serverless technologies
    • URL shortener
    • Entering data into storage systems
    • Storing application runtime logs
  1. Performing infrastructure management
  2. Getting started with Terraform

Getting started with Terraform

Written by
Yandex Cloud
  • Before you start
    • Required paid resources
  • Install Terraform
    • From a mirror
    • From the Hashicorp website
  • Create a Terraform configuration file
  • Configure a provider
  • Prepare an infrastructure plan
    • Create users
  • Check and format the configuration files
  • Create resources
  • How to delete created resources

With Terraform, you can quickly create a cloud infrastructure in Yandex Cloud and manage it by configuration files. They store the infrastructure description in HashiCorp Configuration Language (HCL). Terraform and its providers are distributed under the Mozilla Public License.

For more information about the provider resources, see the documentation on the Terraform site or mirror site.

If you change the configuration files, Terraform automatically determines which part of your configuration is already deployed and what should be added or removed.

To create your first infrastructure in Yandex Cloud using Terraform:

  1. Before you start.
  2. Install Terraform.
  3. Create a Terraform configuration file.
  4. Configure a provider.
  5. Prepare an infrastructure plan.
  6. Check and format your configuration files.
  7. Create resources.

If you no longer need the resources, delete them.

Before you start

Before working, you need to register in Yandex Cloud and create a billing account:

  1. Go to the management console. Then log in to Yandex Cloud or sign up if don't already have an account.
  2. On the billing page, make sure you linked a billing account, and it has the ACTIVE or TRIAL_ACTIVE status. If you don't have a billing account, create one.

If you have an active billing account, you can create or select a folder to run your VM in from the Yandex Cloud page.

Learn more about clouds and folders.

Required paid resources

The cost of Terraform-created resources includes:

  • A fee for continuously running virtual machines (see Yandex Compute Cloud pricing).
  • A fee for using a dynamic public IP address (see Yandex Virtual Private Cloud pricing).

Install Terraform

From a mirror

You can download a Terraform distribution for your platform from a mirror. When the download is complete, add the path to the folder with the executable to the PATH variable:

export PATH=$PATH:/path/to/terraform

From the Hashicorp website

Windows
Linux
macOS

Use one of the following methods:

  • Download a Terraform distribution and install it by following the instructions.

  • Install Terraform using the Chocolatey package manager. To do this, run the command:

    choco install terraform
    

Download a Terraform distribution and install it by following the instructions.

Use one of the following methods:

  • Download a Terraform distribution and install it by following the instructions.

  • Install Terraform using the Homebrew package manager and the command below:

    brew install terraform
    

Create a Terraform configuration file

  1. Create a directory with any name, for example, cloud-terraform. It stores the configuration files and saved states for Terraform and your infrastructure.

    Warning

    Each configuration must be in a separate directory.

  2. Create a configuration file with the .tf extension in this directory, such as main.tf.

Configure a provider

Note

The settings apply to Terraform 0.13 and higher.

  1. Specify the source the provider will be installed from.

    Linux and macOS
    Windows

    Open the Terraform CLI configuration file:

    nano ~/.terraformrc
    

    Open the Terraform CLI terraform.rc configuration file located in your user's %APPDATA% folder.

    Add the following section to the file:

    provider_installation {
      network_mirror {
        url = "https://terraform-mirror.yandexcloud.net/"
        include = ["registry.terraform.io/*/*"]
      }
      direct {
        exclude = ["registry.terraform.io/*/*"]
      }
    }
    

    For more information about setting up mirrors, see the documentation.

  2. Add the following sections at the top of the .tf configuration file:

    terraform {
      required_providers {
        yandex = {
          source = "yandex-cloud/yandex"
        }
      }
      required_version = ">= 0.13"
    }
    
    provider "yandex" {
      token     = "<OAuth>"
      cloud_id  = "<cloud ID>"
      folder_id = "<folder ID>"
      zone      = "<default availability zone>"
    }
    

    Where:

    • source: Provider's global source address.
    • version: The minimum provider version that the module is compatible with. You can find the version number on the provider's page (click USE PROVIDER in the top right corner).
    • provider: The provider name.
    • token: OAuth token for Yandex Cloud access.
    • cloud_id: ID of the cloud where Terraform will create resources.
    • folder_id: ID of the folder where resources will be created by default.
    • zone: The availability zone where all cloud resources will be created by default.
  3. If you previously had a provider from the Hashicorp registry configured, delete its settings:

    rm -rf .terraform*
    
  4. Execute the terraform init command in the folder containing the .tf configuration file. This command initializes the providers specified in the configuration files and lets you work with the provider resources and data sources.

If the provider installation failed, create a support request indicating the provider name and version.

If you used the .terraform.lock.hcl file, run the terraform providers lock command before initializing, specifying the URL of the mirror that the provider will be uploaded from and the platforms that the configuration will be used on:

terraform providers lock -net-mirror=https://terraform-mirror.yandexcloud.net -platform=linux_amd64 -platform=darwin_arm64 yandex-cloud/yandex

If you used modules, first run terraform init, then delete the lock file. After that, run the terraform providers lock command.

Prepare an infrastructure plan

Using Terraform in Yandex Cloud, you can create cloud resources of any type, such as virtual machines, disks, images, and so on. For detailed information on resources you can create with Terraform, see the provider documentation.

To create a resource, specify a set of required and optional parameters that define the resource properties. Such resource descriptions make up an infrastructure plan.

The plan includes creating two virtual machines: terraform1 and terraform2, as well as a cloud network called network-1 with a subnet named subnet-1.

Resource names must meet the following requirements:

  • The length can be from 3 to 63 characters.
  • It may contain lowercase Latin letters, numbers, and hyphens.
  • The first character must be a letter. The last character can't be a hyphen.

The machines will have different vCPU and memory configurations: 2 vCPUs and 2 GB of RAM for terraform1 and 4 vCPUs and 4 GB of RAM for terraform2. The VMs will automatically get public and private IP addresses from the 192.168.10.0/24 range in the subnet-1 subnet located in the ru-central1-a availability zone and belonging to the network-1 cloud network. The Ubuntu OS will be installed on the VMs and the public part of the key used to access the VMs via SSH will be stored on them.

In the VM configuration, you'll need to specify the boot disk image ID. You can retrieve a list of available public images by using the CLI command yc compute image list --folder-id standard-images.

To access the VMs over SSH, generate an SSH key pair and pass the public key to the virtual machine in the ssh-keys parameter in the metadata section.

Resource configurations are specified immediately after the provider's configuration:

terraform {
  required_providers {
    yandex = {
      source = "yandex-cloud/yandex"
    }
  }
}

provider "yandex" {
  token     = "<OAuth>"
  cloud_id  = "<cloud-id>"
  folder_id = "<folder-id>"
  zone      = "<ru-central1-a>"
}

resource "yandex_compute_instance" "vm-1" {
  name = "terraform1"
}
Creating a Linux VM
Creating a Windows VM

According to the plan, the following resources are created:

  • A cloud network named network-1 with a subnet named subnet-1 in the ru-central1-a availability zone.
  • Two Linux VMs: terraform1 (2 cores and 2 GB of RAM) and terraform2 (4 cores and 4 GB of RAM). The VMs are automatically assigned public and private IP addresses from the range 192.168.10.0/24 in subnet-1.
  1. Get the ID of the boot disk image from Cloud Marketplace, such as Ubuntu 16.04 LTS, that will be installed on the VM. Get a list of available public images by running the following command in the CLI:

    yc compute image list --folder-id standard-images
    
  2. Generate an SSH key pair to access the VM over SSH.

  3. Describe the resource parameters in the main.tf file:

    • In the ssh-keys parameter under metadata, specify the path to the public part of the SSH key.
    • In the image_id parameter, set the boot disk image ID.
    File main.tf
    <provider settings>
    
    resource "yandex_compute_instance" "vm-1" {
    name = "terraform1"
    
    resources {
        cores  = 2
        memory = 2
    }
    
    boot_disk {
        initialize_params {
        image_id = "fd87va5cc00gaq2f5qfb"
        }
    }
    
    network_interface {
        subnet_id = yandex_vpc_subnet.subnet-1.id
        nat       = true
    }
    
    metadata = {
        ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}"
    }
    }
    
    resource "yandex_compute_instance" "vm-2" {
    name = "terraform2"
    
    resources {
        cores  = 4
        memory = 4
    }
    
    boot_disk {
        initialize_params {
        image_id = "fd87va5cc00gaq2f5qfb"
        }
    }
    
    network_interface {
        subnet_id = yandex_vpc_subnet.subnet-1.id
        nat       = true
    }
    
    metadata = {
        ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}"
    }
    }
    
    resource "yandex_vpc_network" "network-1" {
    name = "network1"
    }
    
    resource "yandex_vpc_subnet" "subnet-1" {
    name           = "subnet1"
    zone           = "ru-central1-a"
    network_id     = yandex_vpc_network.network-1.id
    v4_cidr_blocks = ["192.168.10.0/24"]
    }
    
    output "internal_ip_address_vm_1" {
    value = yandex_compute_instance.vm-1.network_interface.0.ip_address
    }
    
    output "internal_ip_address_vm_2" {
    value = yandex_compute_instance.vm-2.network_interface.0.ip_address
    }
    
    
    output "external_ip_address_vm_1" {
    value = yandex_compute_instance.vm-1.network_interface.0.nat_ip_address
    }
    
    output "external_ip_address_vm_2" {
    value = yandex_compute_instance.vm-2.network_interface.0.nat_ip_address
    }
    

According to the plan, the following resources are created:

  • A cloud network named ya-network with a subnet named ya-network in the default availability zone.
  • Two Windows VMs: terraform1 (2 cores and 4 GB of RAM) and terraform2 (4 cores and 4 GB of RAM). The VM will automatically get public and private IP addresses from the range 192.168.10.0/24 in the ya-network subnet.

Create the following files:

  1. main.tf: The main file with the infrastructure description.

    Content of file main.tf
    terraform {
      required_providers {
        yandex = {
          source = "yandex-cloud/yandex"
        }
      }
    }
    
    provider "yandex" {
      cloud_id  = var.cloud_id
      folder_id = var.folder_id
      zone      = var.zone
      token     = var.token
    }
    
    resource "yandex_vpc_network" "default" {
      name = var.network
    }
    
    resource "yandex_vpc_subnet" "default" {
      network_id     = yandex_vpc_network.default.id
      name           = var.subnet
      v4_cidr_blocks = var.subnet_v4_cidr_blocks
      zone           = var.zone
    }
    
    data "yandex_compute_image" "default" {
      family = var.image_family
    }
    
    data "template_file" "default" {
      template = file("${path.module}/init.ps1")
      vars = {
        user_name  = var.user_name
        user_pass  = var.user_pass
        admin_pass = var.admin_pass
      }
    }
    
    resource "yandex_compute_instance" "default" {
      name     = var.name
      hostname = var.name
      zone     = var.zone
    
      resources {
        cores  = var.cores
        memory = var.memory
      }
    
      boot_disk {
        initialize_params {
          image_id = data.yandex_compute_image.default.id
          size     = var.disk_size
          type     = var.disk_type
        }
      }
    
      network_interface {
        subnet_id = yandex_vpc_subnet.default.id
        nat       = var.nat
      }
    
      metadata = {
        user-data = data.template_file.default.rendered
      }
    
      timeouts {
        create = var.timeout_create
        delete = var.timeout_delete
      }
    }
    
    output "name" {
      value = yandex_compute_instance.default.name
    }
    
    output "address" {
      value = yandex_compute_instance.default.network_interface.0.nat_ip_address
    }
    
  2. variables.tf: A file that describes variables for the resources being created.

    File variables.tf
    variable "cloud_id" {
    type    = string
    }
    
    variable "folder_id" {
    type    = string
    }
    
    variable "zone" {
    type    = string
    default = "ru-central1-a"
    }
    
    variable "token" {
    type    = string
    }
    
    variable "network" {
    type    = string
    default = "ya-network"
    }
    
    variable "subnet" {
    type    = string
    default = "ya-network"
    }
    
    variable "subnet_v4_cidr_blocks" {
    type    = list(string)
    default = ["192.168.10.0/16"]
    }
    
    variable "nat" {
    type    = bool
    default = true
    }
    
    variable "image_family" {
    type    = string
    default = "windows-2019-dc-gvlk"
    }
    
    variable "name" {
    type    = string
    }
    
    variable "cores" {
    type    = number
    default = 2
    }
    
    variable "memory" {
    type    = number
    default = 4
    }
    
    variable "disk_size" {
    type    = number
    default = 50
    }
    
    variable "disk_type" {
    type    = string
    default = "network-nvme"
    }
    
    variable "user_name" {
    default = ""
    type    = string
    }
    
    variable "user_pass" {
    default = ""
    type    = string
    }
    
    variable "admin_pass" {
    default = ""
    type    = string
    }
    
    variable "timeout_create" {
    default = "10m"
    }
    
    variable "timeout_delete" {
    default = "10m"
    }
    
  3. terraform.tfvars: A file that stores the values of variables for accounts created inside the VM and access tokens.

    File terraform.tfvars
    token      = "<token>"
    cloud_id   = "<cloud_id>"
    folder_id  = "<folder_id>"
    
    name       = "<my_server_name>"
    user_name  = "<my_user>"
    user_pass  = "<my_password>"
    admin_pass = "<my_password>"
    

Create users

Linux
Windows

To add a user to the created VM, specify the user-data parameter with user metadata under metadata. To do this:

  1. Create a text metadata file, for example:

    #cloud-config
    users:
      - name: <username>
        groups: sudo
        shell: /bin/bash
        sudo: ['ALL=(ALL) NOPASSWD:ALL']
        ssh-authorized-keys:
          - ssh-rsa AAAAB3Nza......OjbSMRX user@example.com
          - ssh-rsa AAAAB3Nza......Pu00jRN user@desktop
    
  2. In the main.tf file, replace ssh-keys with the user-data parameter and specify the metadata file path:

    metadata = {
        user-data = "${file("<file path>/meta.txt")}"
    }
    

To learn more about working with metadata, see VM instance metadata.

You can create a user and set the Administrator account password on a VM in Yandex Cloud using the cloudbase-init agent. To do this, create a script named init.ps1 that the agent will run on the initial boot of the system. Variables from the variables.tf file will be used as credentials.

init.ps1 file
#ps1
# ^^^ 'ps1' is only for cloudbase-init, some sort of sha-bang in linux

# logging
Start-Transcript -Path "$ENV:SystemDrive\provision.txt" -IncludeInvocationHeader -Force
"Bootstrap script started" | Write-Host

# inserting value's from terraform
$MyUserName = "${ user_name }"
$MyPlainTextPassword = "${ user_pass }"
if (-not [string]::IsNullOrEmpty($MyUserName) -and -not [string]::IsNullOrEmpty($MyPlainTextPassword))
{
    "Create user" | Write-Host
    $MyPassword = $MyPlainTextPassword | ConvertTo-SecureString -AsPlainText -Force
    $MyUser = New-LocalUser -Name $MyUserName -Password $MyPassword -PasswordNeverExpires -AccountNeverExpires
    $MyUser | Add-LocalGroupMember -Group 'Administrators'
    $MyUser | Add-LocalGroupMember -Group 'Remote Management Users'
}

# inserting value's from terraform
$MyAdministratorPlainTextPassword = "${ admin_pass }"
if (-not [string]::IsNullOrEmpty($MyAdministratorPlainTextPassword)) {
    "Set local administrator password" | Write-Host
    $MyAdministratorPassword = $MyAdministratorPlainTextPassword | ConvertTo-SecureString -AsPlainText -Force
    # S-1-5-21domain-500 is a well-known SID for Administrator
    # https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows
    $MyAdministrator = Get-LocalUser | Where-Object -Property "SID" -like "S-1-5-21-*-500"
    $MyAdministrator | Set-LocalUser -Password $MyAdministratorPassword
}

"Bootstrap script ended" | Write-Host

Check and format the configuration files

  1. Check the configuration using the command:

    terraform validate
    

    If the configuration is valid, the following message is returned:

    Success! The configuration is valid.
    
  2. Format the configuration files in the current folder and subfolders:

    terraform fmt
    

    Result:

    main.tf
    variables.tf
    

Create resources

  1. After checking the configuration, run the command:

    terraform plan
    

    The terminal will display a list of resources with parameters. This is a test step. No resources are created. If there are errors in the configuration, Terraform points them out.

    Alert

    You're charged for all resources created using Terraform. Check the plan carefully.

  2. To create resources, run the command:

    terraform apply
    
  3. Confirm the resource creation: type yes in the terminal and press Enter.

    Terraform will create all the required resources and the terminal will display the IP addresses of the created VMs. You can check resource availability and their settings in the management console.

How to delete created resources

To delete resources created using Terraform:

  1. Run the command:

    terraform destroy
    

    After the command is executed, the terminal will display a list of resources to be deleted.

  2. Type yes to confirm their deletion and press Enter.

You can use the management console to check that the resources have been deleted.

Was the article helpful?

Language / Region
© 2022 Yandex.Cloud LLC
In this article:
  • Before you start
  • Required paid resources
  • Install Terraform
  • From a mirror
  • From the Hashicorp website
  • Create a Terraform configuration file
  • Configure a provider
  • Prepare an infrastructure plan
  • Create users
  • Check and format the configuration files
  • Create resources
  • How to delete created resources