Рубрики
Uncategorized

Начало работы с Terraform на Azure: Переменные

ВВЕДЕНИЕ СОДЕРЖАНИЕ СОДЕРЖАНИЕ Предварительные условия Шаг 1 — Входные переменные Шаг 2 —… Tagged с Azure, DevOps, Terraform.

Начало работы с Terraform на Azure (серия 9 деталей)

Введение

  • Предварительные условия
  • Шаг 1 — Входные переменные
  • Шаг 2 — Карты, списки и объекты
  • Шаг 3 — Выходные значения
  • Шаг 4 — Развертывание полной конфигурации
  • Вывод

Способность повторного использования является одним из основных преимуществ инфраструктуры в качестве кода. Когда мы кодифицируем нашу сеть, хранение и вычисляем таким образом, чтобы мы могли повторно использовать тот же код для развертывания наших ресурсов, мы можем двигаться очень быстро. Запросы на инфраструктуру, которая обычно занимает неделю или две, теперь занимают пару часов, потому что у нас уже есть стандартный шаблон, нанесенный на карту для этой инфраструктуры. Мы также получаем возможность разрешить товарищи по команде любых навыков для развертывания сложной инфраструктуры, которая уже была определена в коде. Например, нам больше не нужен эксперт SQL для установки и настройки SQL Services каждый раз, когда это необходимо. Теперь стандартная сборка может быть определена в коде и повторно развернута любым.

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

Предварительные условия

Прежде чем начать, вам нужно настроить следующее:

Шаг 1 — Входные переменные

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

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

development
└── server
    └── main.tf
    └── variables.tf

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

Переменная определяется в Terraform с использованием переменного блока с меткой. Метка должна быть уникальным именем, вы не можете иметь переменные с тем же именем в конфигурации. Также хорошая практика включать описание и тип. Тип переменной указывает Тип ограничения что определенная переменная примет. Это позволяет нам подтвердить, что мы не используем строковое значение для переменной, которая должна быть номером или типом Bool. Ниже приведены два переменных блока для система и Место Оба типа строки. Место переменная имеет дополнительное по умолчанию Аргумент с westus2 выражение. Это означает, что если значение для переменной местоположения не указано, когда мы запускаем наш терраформ применить , это по умолчанию westus2 :

variable "system" {
    type = string
    description = "Name of the system or environment"
}

variable "location" {
    type = string
    description = "Azure location of terraform server environment"
    default = "westus2"

}

Теперь, когда мы объявили наши переменные в переменные.tf файл. Мы можем использовать переменные в нашем main.tf Файл, вызывая эту переменную в var. <имя> формат. Таким образом, системная переменная будет представлена как Var.System и значение нашей системной переменной, которая назначена во время терраформ применить или План терраформ Затем можно ссылаться в нашем azurerm_resource_group Блок ресурсов:

provider "azurerm" {
  version = "1.38.0"
}

#create resource group
resource "azurerm_resource_group" "rg" {
    name     = "rg-${var.system}"
    location = var.location
    tags      = {
      Environment = var.system
    }
}

Также обратите внимание, что мы также можем включить наше имя переменной как часть строки, обернув его в кудрявые кронштейны, такие как $ {var.system} Анкет В приведенном выше примере это приведет к тому, что наш аргумент — это значение Var.System но префикс с rg- . Это чрезвычайно полезно, когда динамически называть ресурсы, такие как учетная запись хранения или подсеть, которая должна иметь схему именования, которая включает имя системы.

Итак, теперь мы объявили несколько переменных в нашем переменные.tf Файл и мы ссылаемся на них в main.tf файл. Как мы на самом деле присваиваем значения этим переменным, которые мы создали? В Terraform есть несколько методов назначения значений переменных, и все они имеют свой вариант использования. Самый простой способ назначить значение переменной — это использование -Вар Опция в командной строке при запуске нашей терраформ применить или План терраформ :

terraform apply -var="system=terraformdemo" -var="location=eastus"

Если у нас есть много значений переменных для ввода, мы можем определить их в файле определения переменной с именем Terraform.tfvars В следующем формате:

system ="terraformdemo"
location = "eastus"

Terraform автоматически загрузит значения переменной из файла определения переменной, если она называется Terraform.tfvars или заканчивается в .auto.tvfars и помещен в тот же каталог, что и другие файлы конфигурации, как ниже:

development
└── server
    └── main.tf
    └── variables.tf
    └── terraform.tfvars

Мы также можем поместить значения переменных в переменные среды ОС, которая будет выполнять конфигурацию Terraform. Terraform сканирует систему на наличие любых переменных, которые начинаются с Tf_var_ и используйте их в качестве переменных значений для Terraform. Это полезно, если вы собираетесь запустить несколько конфигураций Terraform в системе. Если бы мы установили значение для система Переменная, мы создали бы переменную среды, которая выглядит следующей:

 export TF_VAR_system=terraformdemo

Для наших друзей PowerShell это было бы больше похоже на это:

$Env:TF_VAR_system="terraformdemo"

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

Шаг 2 — Карты, списки и объекты

Карта — это набор значений, каждое значение помечено строкой. Значения могут быть различными типами элементов, такие как Bool, Int, String. Однако все они должны быть одинакового типа. В приведенном ниже примере — переменная карты с именем Managed_disk_type Анкет В по умолчанию Блок — два строковых значения, "Premium_lrs" и "Standard_lrs" с названной меткой, чтобы идентифицировать каждый westus2 и Истусус . Это позволяет нам выбрать значение на основе имени метки. Итак, для нашего примера у нас есть значение ключа строки для westus2 и Истусус . Мы можем использовать эту группировку, чтобы определить тип хранилища, который мы хотим использовать на основе региона в Azure. Пример использования будет, если бы мы хотели серверов в westus2 Для размещения наших рабочих нагрузок и использовать диск Premium_lrs для быстрой производительности, в то время как серверы размещены в Истусус будет использоваться для рабочих нагрузок аварийного восстановления и использовать диск Standard_lrs для сэкономить на затратах:

variable "managed_disk_type" { 
    type = map
    description = "Disk type Premium in Primary location Standard in DR location"

    default = {
        westus2 = "Premium_LRS"
        eastus = "Standard_LRS"
    }
}

Теперь, когда у нас определена наша карта переменная, нам все еще нужно создать логику, для которой диск использовать в нашем main.tf файл. В Storage_os_disk Блок azurerm_virtual_machine Ресурс мы будем использовать поиск функция, которая следует за поиск (карта, ключ, по умолчанию) формат. Во -первых, мы объявляем переменную карты, которую мы хотим искать, которая будет var.managed_disk_type В этом примере. Далее мы получим значение нашей карты на основе ключа, которую мы указываем, который является var.location Анкет Эта переменная должна решить до westus2 или любое значение местоположения, которое мы вводим для этой переменной. Если он сочетается с парой значений ключей в нашей карте, это получит это значение. Итак, наш пример должен получить Premium_lrs Если наш var.location Переменная настроена с westus2 ценность. Если пара значений ключей не существует, потому что var.location Переменная не содержит тоже westus2 или Истусус Это по умолчанию в Standard_lrs :

 storage_os_disk {
    name              = "stvm${var.servername}os"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = lookup(var.managed_disk_type, var.location, "Standard_LRS")
  }

Теперь, когда мы создали переменную карты, мы создадим еще одну тип переменной, переменные списка. Типы переменных списка — это последовательность значений, которые могут быть любым типом элемента, если они все одинаковые типа. Списки переменных полезны для назначения значений, которые требуют типа списка. В приведенном ниже примере мы используем переменную списка для vnet_address_space Этот атрибут может принимать значения списка, поэтому объявление списка для переменной позволяет нам указать список адресов для настройки:

variable "vnet_address_space" { 
    type = list
    description = "Address space for Virtual Network"
    default = ["10.0.0.0/16"]
}

Мы указали аргумент по умолчанию с [10.0.0.0/16] как адресное пространство по умолчанию. Обратите внимание, что он обернут в квадратные скобки. Это представляет собой значение, которое является списком. Передать эту переменную нашу main.tf Мы просто использовали бы var.vnet_address_space выражение, как с обычной переменной строки.

Другой тип переменной — тип объекта. Типы объектов — это структурный тип, который позволяет каждому атрибуту иметь свой собственный уникальный тип, в отличие от карты или списка. В этом примере мы объявляем переменную ОС с типом объекта для изображения ОС, которое мы хотим, чтобы наша виртуальная машина использовала. Переменные типа объекта отлично подходят для передачи общего набора значений переменных между модулями. У нас может быть еще один модуль, который выводит эту необходимую информацию о изображении, и легко передавать ее в переменную ОС, уменьшая количество необходимых переменных блоков:

variable "os" {
    description = "OS image to deploy"
    type = object({
        publisher = string
        offer = string
        sku = string
        version = string
  })
}    

Когда мы используем переменную типа объекта в нашем main.tf конфигурация. Нам нужно будет указать ОС переменная и каждый атрибут внутри, чтобы ссылаться на каждое значение:

storage_image_reference {
    publisher = var.os.publisher
    offer     = var.os.offer
    sku       = var.os.sku
    version   = var.os.version
  }

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

Шаг 3 — Выходные значения

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

output "pip" {
    description = "Public IP Address of Virtual Machine"
    value = azurerm_public_ip.publicip.ip_address
}

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

Шаг 4 — Развертывание полной конфигурации

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

terraformdemo
    └── main.tf
    └── variables.tf
    └── terraform.tfvars
    └── output.tf

Ниже приведены полные конфигурации для каждого файла, включая изменения, чтобы сделать нашу конфигурацию более динамичной. Скопируйте каждую конфигурацию и вставьте ее в редактор Azure Cloud Shell, используя Код <файл имени> команда для создания каждого файла:

main.tf

provider "azurerm" {
  version = "1.38.0"
}

#create resource group
resource "azurerm_resource_group" "rg" {
    name     = "rg-${var.system}"
    location = var.location
    tags      = {
      Environment = var.system
    }
}

#Create virtual network
resource "azurerm_virtual_network" "vnet" {
    name                = "vnet-dev-${var.location}-001"
    address_space       = var.vnet_address_space
    location            = azurerm_resource_group.rg.location
    resource_group_name = azurerm_resource_group.rg.name
}

# Create subnet
resource "azurerm_subnet" "subnet" {
  name                 = "snet-dev-${var.location}-001 "
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefix       = "10.0.0.0/24"
}

# Create public IP
resource "azurerm_public_ip" "publicip" {
  name                = "pip-${var.servername}-dev-${var.location}-001"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  allocation_method   = "Static"
}


# Create network security group and rule
resource "azurerm_network_security_group" "nsg" {
  name                = "nsg-sshallow-${var.system}-001 "
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    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" "nic" {
  name                      = "nic-01-${var.servername}-dev-001 "
  location                  = azurerm_resource_group.rg.location
  resource_group_name       = azurerm_resource_group.rg.name
  network_security_group_id = azurerm_network_security_group.nsg.id

  ip_configuration {
    name                          = "niccfg-${var.servername}"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "dynamic"
    public_ip_address_id          = azurerm_public_ip.publicip.id
  }
}

# Create virtual machine
resource "azurerm_virtual_machine" "vm" {
  name                  = var.servername
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.nic.id]
  vm_size               = "Standard_B1s"

  storage_os_disk {
    name              = "stvm${var.servername}os"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = lookup(var.managed_disk_type, var.location, "Standard_LRS")
  }

  storage_image_reference {
    publisher = var.os.publisher
    offer     = var.os.offer
    sku       = var.os.sku
    version   = var.os.version
  }

  os_profile {
    computer_name  = var.servername
    admin_username = var.admin_username
    admin_password = var.admin_password
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }
}

variables.tf

variable "system" {
    type = string
    description = "Name of the system or environment"
}

variable "servername" {
    type = string
    description = "Server name of the virtual machine"
}

variable "location" {
    type = string
    description = "Azure location of terraform server environment"
    default = "westus2"

}

variable "admin_username" {
    type = string
    description = "Administrator username for server"
}

variable "admin_password" {
    type = string
    description = "Administrator password for server"
}

variable "vnet_address_space" { 
    type = list
    description = "Address space for Virtual Network"
    default = ["10.0.0.0/16"]
}

variable "managed_disk_type" { 
    type = map
    description = "Disk type Premium in Primary location Standard in DR location"

    default = {
        westus2 = "Premium_LRS"
        eastus = "Standard_LRS"
    }
}

variable "vm_size" {
    type = string
    description = "Size of VM"
    default = "Standard_B1s"
}

variable "os" {
    description = "OS image to deploy"
    type = object({
        publisher = string
        offer = string
        sku = string
        version = string
  })
}      

Terraform.tfvars

system = "terraexample"
servername = "vmterraform"
location = "westus2"
admin_username = "terraadmin"
vnet_address_space = ["10.0.0.0/16","10.1.0.0/16"]
os = {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04.0-LTS"
    version   = "latest"
}

output.tf

output "pip" {
    description = "Public IP Address of Virtual Machine"
    value = azurerm_public_ip.publicip.ip_address
}

Теперь, когда у нас есть наш каталог, созданный с четырьмя файлами конфигурации, мы запустим наш Terraform Init Чтобы инициализировать каталог и загрузить наши плагины поставщика. Мы будем следить за этим терраформ применить Анкет Обратите внимание, что теперь нас предложено для переменной пароля администратора. Это потому, что мы следовали передовым практикам и оставили значение пароля локального администратора из Terraform.tfvars Файл и никогда не устанавливайте значение по умолчанию в переменные.tf файл. Terraform будет автоматически запрашивать переменные, которые не определены и не имеют настроенного значения по умолчанию:

После ввода пароля подтвердите применение, чтобы начать развертывание инфраструктуры:

azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 2s [id=/subscriptions/f7c32571-81bd-4e23-5321-7e216164bae3/resourceGroups/rg-terraexample]
azurerm_network_security_group.nsg: Creating...
azurerm_virtual_network.vnet: Creating...
azurerm_public_ip.publicip: Creating...
azurerm_public_ip.publicip: Creation complete after 3s [id=/subscriptions/f7c32571-81bd-4e23-5321-7e216164bae3/resourceGroups/rg-terraexample/providers/Microsoft.Network/publicIPAddresses/pip-vmterraform-dev-westus2-001]
...

Когда наша виртуальная машина будет успешно создана, мы увидим, что общедоступный IP -адрес, назначенный нашей виртуальной машине, генерируется в выводе:

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

Outputs:

pip = 52.183.4.46

Теперь у нас есть многоразовая конфигурация Terraform для развертывания виртуальных машин в Azure! Теперь мы можем изменить Terraform.tfvars с разными значениями для настройки наших развертываний.

Вывод

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

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

Начало работы с Terraform на Azure (серия 9 деталей)

Оригинал: «https://dev.to/cloudskills/getting-started-with-terraform-on-azure-variables-20gb»