Серия терраформ
- Часть 1: Введение
- Часть 2: Создание сервера
- Часть 3: обеспечение сервера
- Часть 4: Управление государством Terraform
- Часть 5: Чистый код с модулями Terraform
- Часть 6: петли с терраформой
- Часть 7: условные с терраформи
- Часть 8: тестирование кода Terraform
До сих пор мы сосредоточились на предоставленной функциональности Terraform. Создание серверов, настройка настройки сети, настройка доменных имен, удаленно запустить сценарии Bash, создание единиц хранения и перемещение состояния Terraform в общее пространство.
В этом посте мы собираемся сделать перерыв и посмотреть, как мы можем написать чище, СУХОЙ Er, и многоразовый код Terraform. Основным ключевым словом здесь является «многоразовое», потому что этот пост в основном о модулях Terraform.
Модули являются ключевым ингредиентом для написания повторного использования, поддержания и проверки кода Terraform. [1]
Наличие модуля в Terraform Легко, потому что любой код Terraform, хранящийся в каталоге, рассматривается в одном и том же модуле. По тем же причинам мы также можем сказать, что модули в Terraform неявные, и именно поэтому создание модуля — это немного волшебство.
Давайте посмотрим на наши файлы Terraform, которые мы создали до сих пор:
Provider.tf: Определяет переменные SSH, используя Terraform для подключения к нашей капельке. Кстати,Provider.tfэто довольно паршивое имя для этого файла.:-) Мы рефактируем это.Domain.tf: Указывает наш домен на нашу каплю и определяет его запись CNAME.Space.tf: Объявляет нашу хранение. Это ведро в AWS и пространство в цифро -точке Lingo.main.tf: Настраивается в значительной степени то, что осталось, включая версию провайдера, удаленный бэкэнд и нашу любимую каплю.
Мы создали все эти файлы в одном и том же каталоге. Вот почему они все принадлежат к одному и тому же модулю Terraform. Теперь давайте разберем его, чтобы мы могли повторно использовать наш код, чтобы создать несколько капель, доступных к разным доменным именам. Таким образом, мы можем иметь инфраструктуру, поддерживающую как производственную, так и промежуточную среду. Мы собираемся оставить ведра и файлы отдаленного состояния из этой статьи, чтобы сделать вещи простыми.
Мы стремимся создать инфраструктуру как в производственной, так и в постановке. Мы собираемся создать их с помощью многоразовых модулей Terraform. После того, как мы преобразуем нашу кодовую базу, наша структура каталогов будет выглядеть следующим образом:
Позвольте мне сначала убрать одну вещь: Versions.tf Анкет Я использую Terraform v0.13, и вам нужно определить свой Требования поставщика Начиная с этой версии. Итак, все мои Versions.tf Файлы одинаковы:
terraform {
required_providers {
digitalocean = {
source = "terraform-providers/digitalocean"
}
}
required_version = ">= 0.13"
}
Структура каталога с модулями
Как я упоминал ранее, каждый каталог ведет себя как отдельный модуль. Я решил разделить свою инфраструктуру на два модуля: домен и сервер . Каждая из моих средств будет иметь свой сервер и другой домен, указывающий на этот сервер. Вот почему я создал каталог для каждого модуля под модули Анкет
Начнем с домен модуль. Я скопировал код из Domain.tf в модули/домен/main.tf :
resource "digitalocean_domain" "domain" {
name = var.domain_name
ip_address = var.server_ipv4
}
resource "digitalocean_record" "cname_www" {
domain = digitalocean_domain.domain.name
type = "CNAME"
name = "www"
value = "@"
}
Вы должны заметить изменение внутри Digitalocean_domain Ресурс: значения имя и ip_address больше не кодированы.
Модульные входы
Итак, я создал vars.tf Файл для определения переменных моего модуля:
variable "domain_name" {
description = "Domain name like yourdomain.com"
type = string
}
variable "server_ipv4" {
description = "Server's IP address where the domain should point to"
type = string
}
Теперь я могу использовать эти переменные в качестве входных данных в моем домен модуль. Всякий раз, когда мы используем домен Модуль, нам придется предоставить обе переменные для создания этого ресурса. Вот как мы сможем определить домен с разными доменными именами и отдельными IP -адресами, указывающими на разные серверы.
Теперь давайте перейдем к сервер модуль. Я снова скопировал свой код из моего старого main.tf Файл здесь:
resource "digitalocean_droplet" "server" {
image = "ubuntu-20-04-x64"
name = var.server_name
region = "ams3"
size = var.server_size
ssh_keys = [
var.ssh_fingerprint
]
connection {
host = self.ipv4_address
user = "root"
type = "ssh"
private_key = file(var.ssh_private_key)
timeout = "2m"
}
provisioner "remote-exec" {
inline = [
"export PATH=$PATH:/usr/bin",
# install nginx
"sudo apt-get update",
"sudo apt-get -y install nginx"
]
}
}
Я создал vars.tf Файл для моего сервер Модуль также:
variable "server_name" {
description = "The name of the server"
type = string
}
variable "server_size" {
description = "The size of the server"
type = string
}
variable "ssh_fingerprint" {
description = "Fingerprint of the SSH key that is allowed to connect to the server"
type = string
}
variable "ssh_private_key" {
description = "Private key of the SSH key that is allowed to connect to the server"
type = string
}
Если мы передаем переменные SSH, вы увидите, что теперь мы сможем настроить имя сервера и размер сервера в этом модуле. Вот как мы сможем создать производственный сервер с большим размером, сохраняя при этом проставочный сервер в меньшем размере.
Теперь у нас есть оба домен и сервер модули, чтобы создать себя в среде. Начнем с производство . Вот как это выглядит, чтобы создать среду с нашими модулями в Производство/main.tf :
module "server" {
source = "../modules/server"
server_name = "terraform-sandbox"
server_size = "s-1vcpu-1gb"
ssh_fingerprint = var.ssh_fingerprint
ssh_private_key = var.ssh_private_key
}
module "domain" {
source = "../modules/domain"
domain_name = "productiondomain.com"
server_ipv4 = module.server.server_ipv4
}
Я собираюсь передать здесь переменные SSH, так как мы собираемся предоставить их в качестве аргументов командной строки. Как видите, мы объявляем имя и размер для сервер модуль. Точно так же мы даем имя для нашего домен модуль. Все в твердом кодировании сейчас. Однако server_ipv4 Аргумент для домен Модуль выглядит немного странно, не так ли?:-)
Выходы модуля
Что вы видите как module.server.server_ipv4 это использование выходов модуля. Мы изолировали наш домен и сервер модули, но домен Конфигурация требует сервер S IP -адрес. Мы можем получить доступ к значениям модуля, определив вывод в этом модуле. Вот содержание модули/сервер/outs.tf :
output "server_ipv4" {
value = digitalocean_droplet.server.ipv4_address
}
Определяя server_ipv4 Вывод, мы предоставляем модуль пользовательский доступ к Digitalocean_droplet Ресурс ipv4_address Аргумент внутри сервер пример. Точно так же мы получаем доступ к выводу, следуя этой структуре:
module.MODULE_NAME.OUTPUT_NAME
В нашем случае это становится:
module.server.server_ipv4
Таким образом, Terraform сначала создаст сервер, а затем использует его IP -адрес для настройки нашего домена.
Модуль местные жители
Помимо входов и выходов, Terraform предоставляет другую структуру данных, чтобы сделать нашу кодовую базу сухой. Вместо входов и выходов мы не используем местных жителей между модулями. Их использование ограничено инкапсуляциями локальных значений, так же, как константы в языках программирования, но только в одном и том же модуле.
Например, вместо жесткого кодирования изображения и региона нашего сервера давайте инкапсулируем их в модули/сервер/vars.tf :
locals {
server_image = "ubuntu-20-04-x64"
server_region = "ams3"
}
Тогда мы можем пойти дальше и использовать их в нашем модули/сервер/main.tf файл:
resource "digitalocean_droplet" "server" {
image = local.server_image
name = var.server_name
region = local.server_region
size = var.server_size
ssh_keys = [
var.ssh_fingerprint
]
# ...
Я просто хотел сделать небольшую записку здесь и сказать, что все три структуры не являются уникальными для модулей. Как вы можете себе представить, модули являются неявными структурами. В теоретическом смысле это было бы правдой, если бы мы сказали, что мы также можем использовать входные данные, выходы и местных жителей за пределами контекста модуля. Хотя каждое из использования практически подпадает под использование модуля, поскольку каждый каталог в Terraform является модулем.
[1]: Terraform Up & Running: написание инфраструктуры как код Евгения Брикмана (2 -е издание)
Фотография обложки от Андрей Лишаков
Часть 4 …………………………………………………………………………………………….. Часть 6
Оригинал: «https://dev.to/gzg/what-i-ve-learned-learning-terraform-part-5-j4b»