Подготовка виртуальной машины Linux с помощью Terraform

Завершено

Terraform реализует и управляет целевой инфраструктурой с помощью файлов конфигурации, описывающих требуемое состояние компонентов. Базовый формат файлов и их общий синтаксис, выраженный в языке конфигурации Hashicorp (HCL), одинаковы независимо от выбора облака. Однако описания отдельных компонентов зависят от облака, как определено соответствующим поставщиком Terraform.

Хотя существует несколько поставщиков Terraform, которые поддерживают управление инфраструктурой Azure, AzureRM имеет особое значение. Поставщик AzureRM упрощает подготовку и настройку общих ресурсов Azure IaaS, таких как виртуальные машины, учетные записи хранения и сетевые интерфейсы. Существуют также дополнительные поставщики, не относящиеся к облаку, которые могут потребоваться включить в развертывания. К ним относятся случайный поставщик, который помогает избежать конфликтов именования ресурсов путем создания псевдо-случайных строк символов; и поставщик tls, который упрощает управление асимметричными ключами для защиты проверки подлинности Linux.

Terraform доступен как один двоичный файл, который можно скачать на веб-сайте Hashicorp. Этот двоичный файл реализует интерфейс командной строки Terraform (CLI), который затем можно вызвать из сеанса оболочки для инициализации Terraform и файлов конфигурации процесса. Интерфейс командной строки Terraform можно использовать из любой оболочки, поддерживающей Azure CLI.

Примечание.

При использовании Azure Cloud Shell убедитесь, что вы запускаете текущую версию Terraform, следуя инструкциям, приведенным в статье "Настройка Terraform в Azure Cloud Shell с помощью Bash".

Развертывание виртуальной машины Linux с помощью Terraform

Terraform позволяет определять, просматривать и развертывать ресурсы в облачной инфраструктуре для конкретного поставщика. Процесс подготовки начинается с создания файлов конфигурации, использующих синтаксис HCL, который позволяет назначить целевую облачную среду, например Azure, и ресурсы, составляющие облачную инфраструктуру. После создания всех соответствующих файлов конфигурации (обычно в одном расположении файловой системы) можно создать план выполнения, позволяющий предварительно просмотреть результирующий изменения инфраструктуры до фактического развертывания. Для этого необходимо инициализировать Terraform, чтобы скачать модули поставщика, необходимые для реализации облачных ресурсов. После проверки изменений можно применить план выполнения для развертывания инфраструктуры.

Примечание.

Создание плана выполнения является необязательным, но мы рекомендуем это сделать, так как это позволяет определить любое влияние планового развертывания, не влияя на целевую среду. При интерактивном развертывании ресурсов Azure Terraform поддерживает проверку подлинности Azure CLI прозрачно, повторно используя учетные данные для доступа к целевой подписке Azure.

Процесс подготовки виртуальной машины Azure под управлением Linux с помощью Terraform обычно включает в себя следующую последовательность высокоуровневых шагов:

  • Определите подходящий образ виртуальной машины.
  • Определите подходящий размер виртуальной машины.
  • Создайте файлы конфигурации, определяющие ресурс виртуальной машины Azure со своими зависимостями.
  • Инициализируйте Terraform.
  • Создайте план выполнения Terraform.
  • Инициируйте развертывание Terraform.

Чтобы определить подходящий образ виртуальной машины и размер, выполните действия, описанные в уроке 4 этого модуля. В этом уроке основное внимание уделяется задачам Terraform.

Создание файлов конфигурации

Примечание.

Имена файлов, выбранные для файлов Terraform, являются произвольными, хотя рекомендуется выбрать имя, которое отражает содержимое файла или назначение. Для расширения файла следует использовать .tf.

Чтобы развернуть виртуальную машину Linux с помощью Terraform, сначала создайте каталог для размещения файлов конфигурации. Затем создайте файл с именем providers.tf , который применяет версию Terraform и назначает поставщиков, которые будут полагаться при определении ресурсов, включенных в развертывание. Этот файл должен содержать содержимое, отображаемое в следующем фрагменте кода:

terraform {
  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~>3.0"
    }
    tls = {
      source = "hashicorp/tls"
      version = "~>4.0"
    }
  }
}

provider "azurerm" {
  features {}
}

В том же каталоге создайте файл с именем main.tf с помощью следующего кода, который определяет конфигурацию виртуальной машины Azure и ее зависимости:

resource "random_pet" "rg_name" {
  prefix = var.resource_group_name_prefix
}

resource "azurerm_resource_group" "rg" {
  location = var.resource_group_location
  name     = random_pet.rg_name.id
}

# Create virtual network
resource "azurerm_virtual_network" "terraform_network" {
  name                = "lnx-tf-vnet"
  address_space       = ["10.1.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

# Create subnet
resource "azurerm_subnet" "terraform_subnet" {
  name                 = "subnet0"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.terraform_network.name
  address_prefixes     = ["10.1.0.0/24"]
}

# Create public IPs
resource "azurerm_public_ip" "terraform_public_ip" {
  name                = "lnx-tf-pip"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  allocation_method   = "Dynamic"
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "terraform_nsg" {
  name                = "lnx-tf-nsg"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "ssh"
    priority                   = 300
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# Create network interface
resource "azurerm_network_interface" "terraform_nic" {
  name                = "lnx-tf-nic"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "nic_configuration"
    subnet_id                     = azurerm_subnet.terraform_subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.terraform_public_ip.id
  }
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "lnx-tf-nic-nsg" {
  network_interface_id      = azurerm_network_interface.terraform_nic.id
  network_security_group_id = azurerm_network_security_group.terraform_nsg.id
}

# Generate random text for a unique storage account name
resource "random_id" "random_id" {
  keepers = {
    # Generate a new ID only when a new resource group is defined
    resource_group = azurerm_resource_group.rg.name
  }

  byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "storage_account" {
  name                     = "diag${random_id.random_id.hex}"
  location                 = azurerm_resource_group.rg.location
  resource_group_name      = azurerm_resource_group.rg.name
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

# Create (and display) an SSH key
resource "tls_private_key" "lnx-tf-ssh" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

# Create virtual machine
resource "azurerm_linux_virtual_machine" "lnx-tf-vm" {
  name                  = "lnx-tf-vm"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.terraform_nic.id]
  size                  = "Standard_F4s"

  os_disk {
    name                 = "lnx-tf-vm-osdisk"
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts-gen2"
    version   = "latest"
  }

  computer_name                   = "lnx-tf-vm"
  admin_username                  = "azureuser"
  disable_password_authentication = true

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.lnx-tf-ssh.public_key_openssh
  }

  boot_diagnostics {
    storage_account_uri = azurerm_storage_account.storage_account.primary_blob_endpoint
  }
}

В том же каталоге создайте другой файл с именем variables.tf с помощью следующего кода, который назначает значение переменным, отображаемым в файле main.tf :

variable "resource_group_location" {
  default     = "eastus"
  description = "Location of the resource group"
}

variable "resource_group_name_prefix" {
  default     = "rg"
  description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription"
}

Наконец, создайте файл с именем outputs.tf с помощью следующего кода, который определяет выходные данные, отображаемые после успешного развертывания:

output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}

output "public_ip_address" {
  value = azurerm_linux_virtual_machine.lnx-tf-vm.public_ip_address
}

output "tls_private_key" {
  value     = tls_private_key.lnx-tf-ssh.private_key_pem
  sensitive = true
}

Инициализация Terraform

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

terraform init

Эта команда скачивает модули Azure, необходимые для подготовки ресурсов Azure и управления ими.

Создание плана выполнения

После инициализации создайте план выполнения, выполнив план terraform. Команда создает план выполнения, но не выполняет его. Вместо этого он определяет, какие действия необходимы для создания ресурсов, определенных в файлах конфигурации. Необязательный -out параметр позволяет указать выходной файл для плана, который можно ссылаться во время фактического развертывания. Использование этого файла гарантирует, что план, который вы просматриваете, соответствует точному результату развертывания. Чтобы создать план выполнения, используйте следующую команду:

terraform plan -out <terraform_plan>.tfplan

Запуск развертывания

Когда вы будете готовы применить план выполнения к среде Azure, выполните команду terraform apply, включая имя файла, созданного на предыдущем шаге. У вас будет еще один шанс проверить ожидаемый результат. Terraform запрашивает подтверждение, хотя вы можете исключить запрос, добавив переключатель -auto-approve . Чтобы инициировать развертывание, используйте следующую команду:

terraform apply <terraform_plan>.tfplan

Виртуальная машина Azure скоро начнет работать, как правило, в течение нескольких минут. Выходные terraform apply данные команды включают список выходных данных, но terraform заменит значение конфиденциальной tls_private_key<> метки:

Apply complete! Resources: 12 added, 0 changed, 0 destroyed.

Выходные данные:

public_ip_address = "74.235.10.136"
resource_group_name = "rg-flexible-shark"
tls_private_key = <sensitive>

Чтобы использовать автоматически созданный закрытый ключ для проверки подлинности подключения SSH, сохраните его в файле и задайте разрешения файла, чтобы убедиться, что он недоступен другими пользователями. Для этого выполните следующие команды:

terraform output -raw tls_private_key > id_rsa
chmod 600 id_rsa

На этом этапе вы сможете подключиться к виртуальной машине Azure, выполнив следующую команду (после замены <заполнителя public_ip_address> IP-адресом, который вы определили в выходных данных terraform, созданных на основе terraform):

ssh -i id_rsa azureuser@<public_ip_address>