Введение

В этом руководстве мы развернем простое веб-приложение в выбранном вами облаке, состоящее из базы данных и виртуальной машины, на которой будет выполняться внешний код.
Чтобы конфигурация была многоразовой и согласованной, запишем ее в Терраформ.

Обычно конфигурации Terraform зависят от облака, а изменение облака требует полной перезаписи. В этом случае, чтобы вы могли повторно использовать одну и ту же конфигурацию в облаках, мы будем использовать Мульти.

Чтобы следовать этому руководству, не требуется глубоких знаний Terraform и Multy. Если вы хотите узнать больше об этих инструментах, ознакомьтесь с Много документации и Документация по терраформу.


Архитектура

Это веб-приложение будет содержать следующие компоненты:

  • Сеть — виртуальная сеть, к которой можно получить доступ из Интернета с соответствующей группой безопасности.
  • База данных — управляемая база данных MySQL, в которой будут храниться данные.
  • Виртуальная машина — сервер, настроенный для обслуживания простого приложения для заметок, которое хранит и извлекает данные из базы данных.

Диаграмма архитектуры


Инициализация Терраформ

Сначала инициализируйте Terraform.
Здесь мы настроим провайдера Multy и передадим все необходимые учетные данные.
Обратите внимание, что необходим ключ Multy API — вы можете получить его бесплатно на https://multy.dev/#бета.

Кроме того, мы объявим 2 переменные, cloud а также location, которые упрощают повторное развертывание веб-приложения в других облаках и местах. Вам нужно будет сгенерировать некоторые облачные учетные данные, если у вас их еще нет — ознакомьтесь с Начиная руководство.

Чтобы настроить провайдеров, откройте providers.tf файл со следующим содержимым:

terraform {
  required_providers {
    multy = {
      source = "multycloud/multy"
    }
  }
}
provider "multy" {
  api_key = "xxx"
  aws     = {}
}
variable "cloud" {
  type    = string
  default = "aws"
}
variable "location" {
  type    = string
  default = "eu_west_1"
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

После этого выполните следующую команду в той же папке:

terraform init
Войти в полноэкранный режим

Выйти из полноэкранного режима

Эта команда загрузит Мульти провайдер и инициализируйте все, что нужно Terraform, в .terraform папка.


Настройка сети

Чтобы веб-приложение было доступно из-за пределов облака, нам нужно создать виртуальную сеть с соответствующей таблицей маршрутов.

Нам нужно:

  • Виртуальная сеть и подсеть
  • Группа безопасности, которая открывает порт 22 (для доступа по SSH) и порт 4000 (чтобы веб-сайт был доступен), а также доступ по HTTP и HTTPS для загрузки кода и пакетов Linux.
  • Таблица маршрутов, которая направляет весь трафик в Интернет.

Хотя в каждом облаке это сильно отличается, с Multy мы можем описать это независимо от облака:

resource "multy_virtual_network" "vn" {
  cloud      = var.cloud
  location   = var.location
  name       = "multy-vm"
  cidr_block = "10.0.0.0/16"
}
resource "multy_subnet" "subnet" {
  name               = "multy-subnet"
  cidr_block         = "10.0.10.0/24"
  virtual_network_id = multy_virtual_network.vn.id
}
resource "multy_network_security_group" "nsg" {
  cloud              = var.cloud
  location           = var.location

  name               = "multy_nsg"
  virtual_network_id = multy_virtual_network.vn.id
  rule {
    protocol   = "tcp"
    priority   = 133
    from_port  = 443
    to_port    = 443
    cidr_block = "0.0.0.0/0"
    direction  = "egress"
  }
  rule {
    protocol   = "tcp"
    priority   = 131
    from_port  = 80
    to_port    = 80
    cidr_block = "0.0.0.0/0"
    direction  = "egress"
  }
  rule {
    protocol   = "tcp"
    priority   = 132
    from_port  = 4000
    to_port    = 4000
    cidr_block = "0.0.0.0/0"
    direction  = "ingress"
  }
  rule {
    protocol   = "tcp"
    priority   = 130
    from_port  = 22
    to_port    = 22
    cidr_block = "0.0.0.0/0"
    direction  = "ingress"
  }
}
resource "multy_route_table" "rt" {
  name               = "multy-rt"
  virtual_network_id = multy_virtual_network.vn.id
  route {
    cidr_block  = "0.0.0.0/0"
    destination = "internet"
  }
}
resource "multy_route_table_association" "rta" {
  route_table_id = multy_route_table.rt.id
  subnet_id      = multy_subnet.subnet.id
}
Войти в полноэкранный режим

Выйти из полноэкранного режима


Настройка базы данных

Далее нам нужно настроить нашу базу данных. Нам нужна небольшая база данных MySQL со случайным паролем в том же месте, где мы разместили нашу виртуальную сеть.

resource "random_password" "password" {
  length = 16
  override_special = "!#"
  special = true
}
resource "multy_database" "db" {
  cloud          = var.cloud
  location       = var.location

  storage_gb     = 10
  name           = "multydb"
  engine         = "mysql"
  engine_version = "5.7"
  username       = "multyadmin"
  password       = random_password.password.result
  size           = "micro"
  subnet_id      = multy_subnet.subnet.id
  depends_on = [multy_route_table_association.rta]
}
Войти в полноэкранный режим

Выйти из полноэкранного режима


Настройка виртуальной машины

Наконец, нам нужно настроить сервер. Для этой демонстрации мы будем использовать самый маленький сервер, который мы можем использовать. Для его инициализации мы будем использовать пользовательские данные, скрипт, который выполняется cloud-init при первой загрузке виртуальной машины.

resource "multy_virtual_machine" "vm" {
  cloud          = var.cloud
  location       = var.location

  name               = "web_app_vm"
  size               = "general_micro"
  image_reference    = {
    os      = "ubuntu"
    version = "18.04"
  }
  subnet_id          = multy_subnet.subnet.id
  generate_public_ip = true
  user_data_base64   = base64encode(local.init_script)
  # uncomment this line to allow ssh access
  # public_ssh_key = file("~/.ssh/id_rsa.pub")

  network_security_group_ids = [multy_network_security_group.nsg.id]
}
locals {
  init_script = <<EOT
#!/bin/bash -xe
sudo apt-get update -y && sudo apt-get -y install git npm mysql-client curl jq
curl -fsSL  | sudo -E bash -
sudo apt-get install -y nodejs
sudo chmod a+rwx .
# putting secrets into user data is not best practice, you can use multy_vault instead
export DATABASE_HOST=${multy_database.db.hostname}
export DATABASE_USER=${multy_database.db.connection_username}
export DATABASE_PASSWORD='${multy_database.db.password}'
git clone 
cd nodejs-mysql-links
mysql -h $DATABASE_HOST -P 3306 -u $DATABASE_USER --password=$DATABASE_PASSWORD -e 'source database/db.sql' || true
npm i && npm run build && npm start
EOT
}
output "endpoint" {
  value = "
}
Войти в полноэкранный режим

Выйти из полноэкранного режима


Развертывание

После того, как вы все написали, вы можете развернуть ресурсы с помощью Terraform. Выполните следующую команду, используя облако и расположение Вы предпочитаете:

terraform apply -var="cloud=aws" -var="location=eu_west_1"
Войти в полноэкранный режим

Выйти из полноэкранного режима

Через несколько минут вы должны увидеть конечную точку, где вы можете получить доступ к примеру приложения!


Резюме

Terraform — очень мощный инструмент, который позволяет повторять развертывание с использованием единого унифицированного языка (HCL) для любого облака. Однако облака сильно отличаются друг от друга, а это означает, что файлы Terraform сильно отличаются от облака к облаку. В этом руководстве мы рассмотрели пример того, как использовать Multy для переноса развертываний между несколькими облачными провайдерами — просто изменив один cloud параметр. Если вы хотите продолжить изучение других примеров, взгляните на Несколько примеров.