
Привет, Хабр! Сегодня поговорим про инфраструктуру как код. Почему 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 - Автор статьи
Комментарии (8)
gred
14.05.2025 10:12ну, как бы... нормальных пакетов (.deb, .rpm) - нету. поддержки *BSD в качестве run platform - нету. поставить через go install на не поддерживаемой платформе - нету. от вашего покорного слуги есть issue по данному поводу. от разрабов реакции - 0
masikm Автор
14.05.2025 10:12deb и rpm нету потому что другая логика доставки https://www.pulumi.com/docs/iac/download-install/versions/ и https://github.com/pulumi/pulumi/releases просто качаете архив с бинарниками и используете
под *BSD даже не знал что нету, давно не использовал unix
видимо логика у разрабов такая что или сам клади в go и сам собирай deb, rpm и под unix тоже. Как я говорил pulumi не панацея и статья не нацелена на то что бы сказать что terraform плохо. Тут вопрос гибкости, иногда без pulumi просто не обойтись а terraform что называется не вывозит.
PetyaUmniy
14.05.2025 10:12Использую Ansible + Terraform.
Анлиблом делаю конфигурации не требующие трекинга ресурсов и генерю конфиги терраформа, терраформом - требующее трекинга. Пишу модули и фильтры для первого, поэтому подерживаю ansible код в достаточно декларативном стиле (императивный подход остается под капотом).Концеп Pulumi вообще не понимаю.
Помоему это тулза не нового поколения, это шаг назад в 70-80e к шелл портянам с размазаным по всему файлу контекстом выполнения и императивщиной в полный рост.А вот это заявление:
появились привычные нам языки программирования... Go, .NET.
вызывает у меня опасения за тех кто это придумал, за их ментальное здоровье. Почему бы не пойти дальше? Где C, Fortran, Cobol... и asm разумеется?
Такое чувство что люди совершенно оторвались от реальности. Зачем вам интеграция инфраструктурной тулзы в ваш язык программирования, а особенно компилируемые? Вам что нужно запускать её раз в 100мкс? Точно нужно, да? А зачем? Ведь в противном случае задача решается самым прямым образом: запускайте самые обычные инструменты через exec. Это не настолько плохо как люди об этом думают, особенно если вы делаете это реже чем раз в секунды. Или если вы делаете не mvp колхоз, лишь бы заработало, и вам нужна изоляция, границы модулей - вот это все, то дергаете их по API (например ansible можно дергать через AWX или Semaphore, terraform тоже чем-то, вроде тоже через последний). Зачем миксовать в коде приложения принципильно разные сущности? Не понимаю.
А еще к вопросу безопасности, вы забиваете в свой код credentials позволяющие, допустим, управлять инстансами VM... Угадайте что произойдет если это сервис сломают? На каком количестве инстансов вылезет злоумышленик? Конечно, можно сделать и безопасно. Но это как будто бы вариант тем кому "нужны шашечки", в другом случае (обычная тулза по api) у тех кому "ехать" сразу работает достаточно безопасно.
Тезис про собственные языки ansible и terraform на мой взгляд ошибочен. Их нельзя сравнивать с обычными языками программирования - это dsl поверх стандартного формата сериализации. В ансибле точно можно юзать для сериализаци json вместо yml, в terraform вроде тоже можно json вместо hcl. Таким образом остается только ознакомиться с самим dsl, который очень простой, потому что ограниченный. Это близко нельзя сравнить с изучением языка программирования. Разные порядки сложности.
Вобщем очередной раз не убедили.masikm Автор
14.05.2025 10:12Статья не для убедить а открыть глаза тем кому нужно что-то больше чем скудные возможности terraform. В наших реалиях большим корпорациям требуются большие и гибкие возможности и множество устоявшихся приложений уже просто так сказать не вывозят
Все что вы написали 7 лет назад я читал про Kubernetes. Делайте выводы
cadmi
14.05.2025 10:12А еще к вопросу безопасности, вы забиваете в свой код credentials позволяющие, допустим, управлять инстансами VM... Угадайте что произойдет если это сервис сломают?
Ну вот с этого места всё понятно - автор комментария не то что не использовал, а даже документацию не читал. Но осуждает.
Этот бы возмущенный комментарий да в производительное русло.
masikm Автор
14.05.2025 10:12Ой, сплю уже, комvентарий удалил случайно про отсутствие dry run\plan
как же отсутствует - ну pulumi preview же
Andy_U
У вас все отступы в коде пропали...
masikm Автор
Спасибо. Поправил