
Привет, Хабр! Сегодня поговорим про инфраструктуру как код. Почему Terraform уже не единственный игрок в мире IaC, а Pulumi становится всё более актуальным. Я расскажу, как эти инструменты работают, чем отличаются, и почему стоит присмотреться к Pulumi, особенно, если вы хотите гибкости и мощи в управлении облаками.
Почему IaC — это важно
В наше время автоматизация инфраструктуры — это не просто модный тренд, а необходимость. Вспомните старые времена: ручная настройка серверов, бесконечные конфиги, куча времени на развёртывание. Сейчас это как копать яму лопатой, стоя на ступени экскаватора. Мир ускорился до предела: бизнес требует гибкости, быстрого масштабирования и развёртывания новых фич. Если будем настраивать каждый сервер вручную, просто не успеем за рынком. IaC решает эту проблему. Мы просто описываем инфраструктуру кодом, а машина всё делает сама. И на этом пути уже есть свои классики.
Terraform даёт понятный декларативный язык HCL, с которым легко стартовать, особенно небольшим командам и стартапам. Всё просто: описал ресурсы, запустил — и инфраструктура создаётся. Удобно, надёжно и предсказуемо.
Но есть и минус — Terraform довольно консервативен. Когда хочется сделать что-то нестандартное, приходится туго. Его шаблоны ограничивают, гибкости мало.
Знакомьтесь, Pulumi — IaC нового поколения
Но законы рынка работают везде. Если есть спрос — будут и предложения. С появлением Pulumi — IaC стал проще. Вместо собственного языка Terraform появились привычные нам языки программирования, такие как JavaScript, Python, Go, .NET. Значит, мы можем писать инфраструктуру так, как пишем приложения — с циклами, условными операторами, функциями. Хотим динамическую инфраструктуру, которая меняется в зависимости от нагрузки — пожалуйста! Нужно интегрировать вызовы API, запускать AWS Lambda прямо из кода инфраструктуры — без проблем.
Pulumi поддерживает динамические провайдеры — это огромный плюс, потому что облачные API постоянно меняются, а ждать обновления провайдера от Terraform бывает довольно долго. С Pulumi намного быстрее адаптироваться. Достаточно написать свой провайдер и сразу использовать новые возможности облака.
Как Pulumi меняет правила игры на примере Netbox
Netbox — популярный инструмент для учёта ресурсов. У него есть Terraform-провайдер, но он довольно жёсткий и не даёт быстро добавлять свою логику, например, для кастомных плагинов. С Pulumi можно написать простой Python-код, который создаст полноценного провайдера для Netbox, и управлять виртуальными машинами, интерфейсами и IP-адресами. Без громоздких бинарных провайдеров, без долгого ожидания обновлений. Это даёт свободу быстро менять и расширять инфраструктуру под свои нужды.
Можно быстро набросать простой код. Для примера возьмём Python (потому что я знаю его лучше других), который будет выполнять нужные нам функции:
import pulumi
import os
from pulumi.dynamic import ResourceProvider, CreateResult, UpdateResult, Resource, DiffResult
import pynetbox
import json
api_url = os.getenv('NETBOX_URL')
api_token = os.getenv('NETBOX_TOKEN')
class NetboxVMProvider(ResourceProvider):
def __init__(self, api_url, token):
self.nb = pynetbox.api(api_url, token=token)
def create(self, props):
vm = self.nb.virtualization.virtual_machines.create(
name=props["name"],
disk=props.get("disk"),
vcpus=props.get("vcpus"),
memory=props.get("memory"),
site=props.get("site"),
tenant=props.get("tenant"),
platform=props.get("platform"),
status='active',
custom_fields={
'Environments': f'{props.get("Environments")}',
"ResourceID": f'{props.get("ResourceID")}'
}
)
netbox_interface = self.nb.virtualization.interfaces.create(
virtual_machine=vm.id,
name="eth0"
)
netbox_ip_address = self.nb.ipam.ip_addresses.create(
address=props.get("address"),
assigned_object_type='virtualization.vminterface',
assigned_object_id=netbox_interface.id,
dns_name=props.get("dns_name"),
status='active'
)
vm.update({
'primary_ip4': netbox_ip_address.id
})
vm_id = vm.id
return CreateResult(id_=str(vm_id), outs={**props, "vm_id": vm_id})
def update(self, id, olds, news):
vm = self.nb.virtualization.virtual_machines.get(id)
for key, value in news.items():
setattr(vm, key, value)
vm.save()
return UpdateResult(outs={**news, "vm_id": id})
def delete(self, id, props):
vm = self.nb.virtualization.virtual_machines.get(id)
vm.delete()
class NetboxVM(Resource, module="NetBox", name="VirtualMachine"):
def __init__(self, name, props, opts=None):
super().__init__(NetboxVMProvider(api_url, api_token), name, props, opts)
Таким вот нехитрым образом у нас получается полноценный провайдер без больших бинарников провайдера от Terraform. Причем мы можем менять его прямо на ходу! В этом нам помогают:
from pulumi.dynamic import ResourceProvider, CreateResult, UpdateResult, Resource, DiffResult
Далее остаётся описать взаимодействие с созданным динамическим провайдером:
vm = NetboxVM(
f"netboxvm-{config.name}",
{
"name": config.name,
"api_url": NETBOX_URL,
"tenant": netbox_tenant.id,
"platform": netbox_platform.id,
"vcpus": cpu_core_count,
"site": netbox_site.id,
"memory": memory_size,
"disk": config.system_disk_size,
"dns_name": config.name,
"address": network.ip4_addr,
"Environments": SYS_ENV,
"ResourceID": instance.id
},
opts=pulumi.ResourceOptions(
parent=instance,
depends_on=instance,
ignore_changes=["__provider"]
)
)
И готово!
Инфраструктура как часть приложения
Ещё один важный момент: с Pulumi IaC становится частью приложения. Можно создавать инфраструктуру, которая сама подстраивается под нагрузку, автоматически разворачивает тестовые окружения, оптимизирует затраты. Например, можно настроить автоматическую отправку уведомлений сотрудникам с безопасной передачей паролей через зашифрованные ссылки — всё это прямо в коде инфраструктуры. В Terraform такие сценарии требуют сложных обходных путей и внешних скриптов. С Pulumi всё намного проще. Вы можете брать свой любимый язык, а я для примера снова воспользуюсь Python.
Представьте, что мы создали учётные записи для нового сотрудника через Pulumi. Теперь нужно оповестить его и передать все доступы. При этом нельзя отправлять его пароль, даже одноразовый, через почту, мессенджер, смс и другие незащищенные каналы. Всё-таки безопасность должна быть безопасной.
Terraform не позволит выполнить произвольный код, если у него нет подходящего провайдера, а Pulumi создан для такого. Берём и пишем простой код:
def send_email(msg_to: str, msg_from: str, subject: str, body: str) -> None:
msg = EmailMessage()
msg.set_content(body)
msg['Subject'] = subject
msg['From'] = msg_from
msg['To'] = msg_to
s = smtplib.SMTP("SOME_SERVER")
s.send_message(msg)
s.quit()
def send_secret_email(msg_to: str, url: str) -> None:
api_url = PULUMI_CONFIG.require("secrets_url")
api_puburl = PULUMI_CONFIG.require("secrets_puburl")
url = url.replace(api_url, api_puburl)
body = (
"Здравствуйте!\r\n\r\n"
f"Ваш пароль от консоли Вы можете получить по ссылке {url}.\r\n\r\n"
"Ссылка действительна в течении недели.\r\n"
"для авторизации нажмите на IAM User Login и введите Account name: 123123"
)
subject = "Your password"
msg_from = "no-reply-pulumi@example.com"
send_email(msg_to, msg_from, subject, body)
Этот код поместит наш сгенерированный пароль в любую систему шифрования и отправит ссылку в почту. И всё это без какого-либо вмешательства ручных действий.
Конечно, мы можем взять Terraform, покрыть его большой кучей внешних скриптов bash или Python и получить почти то же самое, но… Через Pulumi мы всё получаем из коробки. Прямо как джинн, но не из бутылки, а из коробки. И желаний не три, а сколько хочешь.
Импорт и миграция из других инструментов
Pulumi умеет импортировать конфигурации из Terraform и CloudFormation, что облегчает переход. Вы не теряете наработки, а постепенно расширяете возможности, добавляя динамику и логику.
Так как у нас в распоряжении множество языков программирования, ничего не мешает дополнять наш IaC любыми функциями:
взаимодействие с собственными API;
вызов и взаимодействие с любыми внешними приложениями посредством SDK;
использование Lambda в любом моменте выполнения IaC.
И это далеко не весь список преимуществ, которые мы получаем. По факту он ограничен только нашей фантазией и…
Есть нюанс — нужен опыт
Pulumi не панацея, если вы вдруг подумали, что я работаю на Pulumi Corporation и продвигаю этот проект. Во-первых, это Open Source. Во-вторых, минусы тоже есть.
Pulumi — это не про «нажать кнопку и получить». Здесь нужна команда с хорошими навыками программирования. Если в Terraform можно взять готовый шаблон и чуть подправить, то для Pulumi, как это ни прискорбно, нужно уметь писать код, проектировать архитектуру и рефакторить. Это вызов, особенно для команд, где DevOps не программисты. Но если освоить Pulumi, вы получите безграничные возможности для автоматизации и управления. Это отличная альтернатива, особенно для крупных компаний, где идеи рождаются очень быстро, а архитектура «меняется каждую минуту».
Итоги. Когда что выбрать
Terraform — простой и надёжный выбор для проектов с понятными требованиями и небольшими командами.
Pulumi — для тех, кто хочет гибкости, динамики и готов инвестировать в развитие навыков программирования. В больших компаниях с быстро меняющейся архитектурой Pulumi становится незаменимым инструментом.
В итоге, не стоит смотреть на Terraform и Pulumi как на конкурентов. Они отлично дополняют друг друга. Можно использовать Terraform для стабильных базовых задач, а Pulumi — для сложных сценариев и кастомизации. Главное понимать, что IaC — это не просто код, а инструмент, который должен работать на вас и вашу команду.
Если хотите выйти за рамки шаблонов и сделать инфраструктуру живой и адаптивной — выберите Pulumi. Если нужна простота и проверенность — Terraform остаётся отличным вариантом. Решение за вами, просто расширяйте свои возможности новыми инструментами.
https://www.pulumi.com/ - Pulumi
https://www.terraform.io/ - Terraform
https://t.me/pulumi_ru - Русскоговорящие сообщество Pulumi
https://t.me/masikmos - Автор статьи
Andy_U
У вас все отступы в коде пропали...
masikm Автор
Спасибо. Поправил