Задание:
a) Создайте все необходимые инстансы:
- i. Cloud-HA01, Cloud-HA02: 1vCPU, 512 МБ ОЗУ, 10 ГБ размер диска;
- ii. Cloud-DB01, Cloud-DB02 , Cloud-WEB01, Cloud-WEB02: 1vCPU, 1 ГБ ОЗУ, 10 ГБ размер диска;
- iii. В качестве операционной системы используйте Альт Starterkit (оптимизированная сборка под облака), шаблон alt-p10-cloud-x86_64 (размер: 385 МиБ).
i. Обеспечьте правильное подключение создаваемых инстансов к соответствующим виртуальным сетям в рамках заданной топологии (см. Топология L-3).
i. Доступ ко всем инстансам должен быть реализован по протоколу SSH только с виртуальной машины Cloud-ADM на основе открытых ключей;
2. Имена инстансов, виртуальных сетей, и балансировщика нагрузки должны соответствовать именованиям, указанным в Топологии (см. Топология L-3).
Основные моменты на что стоит обратить внимание перед написанием скрипта с использованием Terraform:
-
Чтобы с инстанса Cloud-ADM был доступ по SSH до всех создаваемых инстансов, используется cloud-init.yml
-
в данном файле можно как передать содержимое публичного ключа - сегенрированного на инстансе Cloud-ADM, так и задать пароль для пользователя altlinux, если это необходимо;
- например:
-
#cloud-config
chpasswd:
expire: false
users:
- {name: altlinux, password: <PASSWORD>, type: text}
ssh_pwauth: false
users:
- name: altlinux
sudo: ALL=(ALL) NOPASSWD:ALL
groups: wheel
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa <PUBLIC_KEY>
-
Для добавления нескольких интерфейсов - network с указанием port - указывается необходимое количество раз;
Вариант реализации:
Cloud-ADM:
- Вся дальнейшая работа реализуется в контексте директории /home/altlinux/bin/terraform:
cd /home/altlinux/bin/terraform
- Создадим файл 'instance.tf', в котором последовательно будем описывать всё что касается создаваемых инстансов в контексте данного задания:
vim instance.tf
- Добавляем следующее содержимое:
- см. комментарии в коде;
# Создание инстанса Cloud-HA01
resource "openstack_compute_instance_v2" "cloud_ha01" {
name = "Cloud-HA01"
flavor_id = var.flavor_id_512ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_externalnet_ha01.id
}
network {
port = openstack_networking_port_v2.port_internalnet_ha01.id
}
network {
port = openstack_networking_port_v2.port_management_ha01.id
}
}
# Создание инстанса Cloud-HA02
resource "openstack_compute_instance_v2" "cloud_ha02" {
name = "Cloud-HA02"
flavor_id = var.flavor_id_512ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_externalnet_ha02.id
}
network {
port = openstack_networking_port_v2.port_internalnet_ha02.id
}
network {
port = openstack_networking_port_v2.port_management_ha02.id
}
}
# Создание инстанса Cloud-WEB01
resource "openstack_compute_instance_v2" "cloud_web01" {
name = "Cloud-WEB01"
flavor_id = var.flavor_id_1ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_internalnet_web01.id
}
network {
port = openstack_networking_port_v2.port_management_web01.id
}
}
# Создание инстанса Cloud-WEB02
resource "openstack_compute_instance_v2" "cloud_web02" {
name = "Cloud-WEB02"
flavor_id = var.flavor_id_1ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_internalnet_web02.id
}
network {
port = openstack_networking_port_v2.port_management_web02.id
}
}
# Создание инстанса Cloud-DB01
resource "openstack_compute_instance_v2" "cloud_db01" {
name = "Cloud-DB01"
flavor_id = var.flavor_id_1ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_internalnet_db01.id
}
network {
port = openstack_networking_port_v2.port_management_db01.id
}
}
# Создание инстанса Cloud-DB02
resource "openstack_compute_instance_v2" "cloud_db02" {
name = "Cloud-DB02"
flavor_id = var.flavor_id_1ram_1vcpu
user_data = file("cloud-init.yml")
block_device {
uuid = var.image_id
source_type = "image"
volume_size = 10
boot_index = 0
destination_type = "volume"
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.port_internalnet_db02.id
}
network {
port = openstack_networking_port_v2.port_management_db02.id
}
}
- Выполняем проверку синтаксиса и структуры файлов конфигурации Terraform
terraform validate
-
- В результате увидим ряд ошибок связанных с большим количеством не объявленных переменных.
- Поэтому открываем файл variables.tf:
vim variables.tf
-
- И объявляем все неодостающие переменные с присвоением необходимых значений:
- см. комментарии в коде;
- И объявляем все неодостающие переменные с присвоением необходимых значений:
# ID для flavor 0,5 RAM и 1 vCPU
# узнать можно: openstack --insecure flavor list
variable "flavor_id_512ram_1vcpu" {
type = string
default = "100"
}
# ID для flavor 1 RAM и 1 vCPU
# узнать можно: openstack --insecure flavor list
variable "flavor_id_1ram_1vcpu" {
type = string
default = "f0a74551-ec6e-42cc-96e7-6403989d17ea"
}
# ID для образа alt-p10-cloud-x86_64.qcow2 (358 МиБ)
# узнать можно: openstack --insecure image list
variable "image_id" {
type = string
default = "05d06ced-de0e-426a-b21e-798bfa0dbaa9"
}
- После чего, при повторной проверки синтаксиса - будет теперь уже ошибка связаная с отсутствием файла cloud-init.yml который должен быть отправлен на каждый создаваемый инстанс
- Для этого генерируем предварительно ключевую пару SSH на инстансе Cloud-ADM:
ssh-keygen -t rsa
-
- Результат:
- также копируем содержимое открытого ключа, чтобы указать его в файле cloud-init.yml
- таким образом, с инстанса Cloud-ADM будет реализован доступ по SSH до всех создаваемых инстансов на основе ключевой пары
- Результат:
- Создаём файл cloud-init.yml:
vim cloud-init.yml
-
- и помещаем в него следующее содержимое:
#cloud-config
chpasswd:
expire: false
users:
- {name: altlinux, password: P@ssw0rd, type: text}
ssh_pwauth: false
users:
- name: altlinux
sudo: ALL=(ALL) NOPASSWD:ALL
groups: wheel
shell: /bin/bash
ssh_authorized_keys: <СОДЕРЖИМОЕ_ПУБЛИЧНОГО_КЛЮЧА_SSH>
-
- например:
- После чего, при повторной проверки синтаксиса - ошибок быть не должно:
- Запускаем развёртывание данных ресурсов:
terraform apply
-
- Подтверждаем развёртывание введя yes:
-
- Результат:
- Проверяем наличие созданных ресурсов средствами openstack-cli:
- сразу же видим подключённые необходимые сети и адреса в соответствие с Топологией L-3
- Проверяем наличие созданных ресурсов средствами веб-интерфейса: