0

practicum

Практическая работа. Создаём виртуальную машину из образа и базу данных

26.04.2022

На этой практической работе вы установите Terraform и подготовите спецификацию, с помощью которой создадите виртуальную машину (ВМ), а затем управляемую базу данных (БД).Подсказки для создания спецификации смотрите в документации Yandex.Cloud и в справочнике ресурсов (раздел Resources).

  1. Скачайте и установите дистрибутив Terraform.
  2. Создайте файл спецификации my-config.tf и укажите в нём Yandex.Cloud в качестве провайдера.
terraform {
  required_providers {
    yandex = {
      source = "yandex-cloud/yandex"
    }
  }
}
 
provider "yandex" {
  token  =  "ваш OAuth токен"
  cloud_id  = "идентификатор облака"
  folder_id = "идентификатор каталога"
  zone      = "ru-central1-a"
} 
  1. Добавьте в файл блок, описывающий создание ВМ. Его сложно написать с нуля, поэтому опирайтесь на пример из документации. Чтобы вам было проще опознать в веб-консоли объекты, созданные по этой спецификации, указывайте уникальные имена для ВМ, сети и подсети, а не оставляйте имена по умолчанию (default).
  • Для создания ВМ используйте образ, созданный с помощью Packer на предыдущей практической работе.Можно использовать переменные в спецификации Terraform и передавать в них разные значения при запуске команд. Например, если сделать переменную для идентификатора образа image-id, тогда с помощью одного и того же файла спецификации вы сможете создавать ВМ с разным наполнением.Переменные Terraform хранятся в файлах с расширением tfvars. Создайте файл my-variables.tfvars и укажите в нём идентификатор своего образа Packer:
image-id = "идентификатор образа" 

В файле спецификации my-config.tf объявите эту переменную (ключевое слово variable). Тогда в секции, где описываются настройки ВМ, вы сможете обратиться к переменной как var.image-id:

variable "image-id" {
    type = string
}

resource "yandex_compute_instance" "vm-1" {
...   

    boot_disk {
        initialize_params {
            image_id = var.image-id
        }
    }
... 
  • Скорректируйте описание для сети и подсети.Для сети достаточно указать имя:
resource "yandex_vpc_network" "network-1" {
    name = "from-terraform-network"
} 

Для подсети укажите зону доступности и сеть, а также внутренние IP-адреса, уникальные в рамках сети. Используйте адреса 10.0.0.0/16.

resource "yandex_vpc_subnet" "subnet-1" {
    name           = "from-terraform-subnet"
    zone           = "ru-central1-a"
    network_id     = yandex_vpc_network.network-1.id
    v4_cidr_blocks = ["10.2.0.0/16"]
} 

Проверьте синтаксис спецификации:

variable "image-id" {
  type = string
}
 
resource "yandex_compute_instance" "vm-1" {
  name = "from-terraform-vm"
  platform_id = "standard-v1"
  zone = "ru-central1-a"
 
  resources {
    cores  = 2
    memory = 2
  }
 
  boot_disk {
    initialize_params {
      image_id = var.image-id
    }
  }
 
  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 = "from-terraform-network"
}
 
resource "yandex_vpc_subnet" "subnet-1" {
  name           = "from-terraform-subnet"
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.network-1.id
  v4_cidr_blocks = ["10.2.0.0/16"]
}
 
output "internal_ip_address_vm_1" {
  value = yandex_compute_instance.vm-1.network_interface.0.ip_address
}
 
output "external_ip_address_vm_1" {
  value = yandex_compute_instance.vm-1.network_interface.0.nat_ip_address
} 
  1. Теперь попробуйте применить спецификацию. Перейдите в папку с файлом спецификации и выполните инициализацию.
terraform init 

Если всё сделано верно, Terraform покажет сообщение:

...
Terraform has been successfully initialized!
... 

Важно: выполняйте команды Terraform в папке, где находится файл спецификации.

  1. Проверьте спецификацию с помощью команды plan.

Terraform использует все файлы .tf из папки, в которой запущена команда. Поэтому название файла спецификации my-config.tf указывать не нужно: его Terraform и так подхватит.Если бы файл с переменными назывался стандартно, например terraform.tfvars, его тоже можно было бы не указывать при запуске команды. Но нестандартное название файла нужно указать:

terraform plan -var-file=my-variables.tfvars 

Terraform выведет план: объекты, которые будут созданы, и т. п.:

...
An execution plan has been generated and is shown below.
... 

На самом деле необязательно помещать переменные в файл, их можно просто указывать при запуске команды. Поскольку у вас только одна переменная, это было бы несложно:

terraform init -var="image-id=идентификатор образа" 
  1. Создайте в облаке инфраструктуру по описанной вами спецификации. Выполните команду:
terraform apply -var-file=my-variables.tfvars 

Terraform запросит подтверждение:

...
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
 
  Enter a value: 

В ответ введите yes.Когда команда будет выполнена, вы увидите сообщение:

Apply complete! Resources: ... added, 0 changed, 0 destroyed.
 
Outputs:
 
external_ip_address_vm_1 = "84.201.133.49"
internal_ip_address_vm_1 = "10.2.0.24" 
  1. В веб-консоли убедитесь, что ВМ создана. Откройте в браузере страницу с указанным IP-адресом и проверьте, доступна ли ВМ.
  2. Как мы говорили на предыдущем уроке, Terraform хранит описание инфраструктуры в стейт-файлах. Посмотрите, как выглядит стейт-файл сейчас:
terraform state list 

Вы увидите список объектов:

yandex_compute_instance.vm-1
yandex_vpc_network.network-1
yandex_vpc_subnet.subnet-1 
  1. Теперь добавьте в файл спецификации блок, описывающий создание БД PostgreSQL. Подсказки ищите в справочнике ресурсов. Не забудьте заменить в спецификации имя подсети.

Проверьте синтаксис спецификации:

resource "yandex_mdb_postgresql_cluster" "postgres-1" {
  name        = "postgres-1"
  environment = "PRESTABLE"
  network_id  = yandex_vpc_network.network-1.id
 
  config {
    version = 12
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 16
    }
    postgresql_config = {
      max_connections                   = 395
      enable_parallel_hash              = true
      vacuum_cleanup_index_scale_factor = 0.2
      autovacuum_vacuum_scale_factor    = 0.34
      default_transaction_isolation     = "TRANSACTION_ISOLATION_READ_COMMITTED"
      shared_preload_libraries          = "SHARED_PRELOAD_LIBRARIES_AUTO_EXPLAIN,SHARED_PRELOAD_LIBRARIES_PG_HINT_PLAN"
    }
  }
 
  database {
    name  = "postgres-1"
    owner = "my-name"
  }
 
  user {
    name       = "my-name"
    password   = "Test1234"
    conn_limit = 50
    permission {
      database_name = "postgres-1"
    }
    settings = {
      default_transaction_isolation = "read committed"
      log_min_duration_statement    = 5000
    }
  }
 
  host {
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet-1.id
  }
} 

Сохраните файл спецификации.Проверьте синтаксис спецификации:

terraform {
  required_providers {
    yandex = {
      source = "yandex-cloud/yandex"
    }
  }
}
 
provider "yandex" {
  token  =  "XXXXXXXXXXXXXXXXXXXXXXX"
  cloud_id  = "b1gttd235imdk2fdud9p"
  folder_id = "b1gfdbij3ijgopgqv9m9"
  zone      = "ru-central1-a"
}
 
variable "image-id" {
  type = string
}
 
resource "yandex_compute_instance" "vm-1" {
  name = "from-terraform-vm"
  platform_id = "standard-v1"
  zone = "ru-central1-a"
 
  resources {
    cores  = 2
    memory = 2
  }
 
  boot_disk {
    initialize_params {
      image_id = var.image-id
    }
  }
 
  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 = "from-terraform-network"
}
 
resource "yandex_vpc_subnet" "subnet-1" {
  name           = "from-terraform-subnet"
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.network-1.id
  v4_cidr_blocks = ["10.2.0.0/16"]
}
 
resource "yandex_mdb_postgresql_cluster" "postgres-1" {
  name        = "postgres-1"
  environment = "PRESTABLE"
  network_id  = yandex_vpc_network.network-1.id
 
  config {
    version = 12
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 16
    }
    postgresql_config = {
      max_connections                   = 395
      enable_parallel_hash              = true
      vacuum_cleanup_index_scale_factor = 0.2
      autovacuum_vacuum_scale_factor    = 0.34
      default_transaction_isolation     = "TRANSACTION_ISOLATION_READ_COMMITTED"
      shared_preload_libraries          = "SHARED_PRELOAD_LIBRARIES_AUTO_EXPLAIN,SHARED_PRELOAD_LIBRARIES_PG_HINT_PLAN"
    }
  }
 
  database {
    name  = "postgres-1"
    owner = "my-name"
  }
 
  user {
    name       = "my-name"
    password   = "Test1234"
    conn_limit = 50
    permission {
      database_name = "postgres-1"
    }
    settings = {
      default_transaction_isolation = "read committed"
      log_min_duration_statement    = 5000
    }
  }
 
  host {
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet-1.id
  }
}
 
output "internal_ip_address_vm_1" {
  value = yandex_compute_instance.vm-1.network_interface.0.ip_address
}
 
output "external_ip_address_vm_1" {
  value = yandex_compute_instance.vm-1.network_interface.0.nat_ip_address
} 
  1. Теперь примените обновлённую спецификацию. В папке с файлом спецификации выполните команду plan:
terraform plan -var-file=my-variables.tfvars 

Если появляются сообщения об ошибках — исправьте ошибки и снова выполните команду.

  1. Обновите инфраструктуру в соответствии с дополненной спецификацией командой apply:
terraform apply -var-file=my-variables.tfvars 

Поскольку спецификация теперь включает создание БД, команда может выполняться довольно долго: около 10 минут.

  1. В консоли откройте раздел Managed Service for PostgreSQL и убедитесь, что кластер postgres-1 создан и имеет статус Alive.
  2. Проверьте, как изменился стейт-файл:
terraform state list 

В списке появился новый объект:

yandex_compute_instance.vm-1
yandex_mdb_postgresql_cluster.postgres-1
yandex_vpc_network.network-1
yandex_vpc_subnet.subnet-1 
  1. Удалите инфраструктуру.
terraform destroy -var-file=my-variables.tfvars 

В конце вы увидите сообщение о выполнении команды:

...
Destroy complete! Resources: 4 destroyed. 

В веб-консоли убедитесь, что объекты удалены.

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:380 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(837): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(417): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 380