Серия терраформ
- Часть 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»