Wróć do katalogu
Season 27 10 Odcinki 41 min 2026

Pulumi: Infrastructure as Code

Edycja 2026. Przewodnik krok po kroku po używaniu Pulumi do Infrastructure as Code, obejmujący podstawowe koncepcje, wdrożenia na platformie Azure i migrację z Terraform.

Infrastruktura jako kod DevOps
Pulumi: Infrastructure as Code
Teraz odtwarzane
Click play to start
0:00
0:00
1
Infrastruktura programisty: Dlaczego Pulumi?
Odkryj, dlaczego programiści odchodzą od języków dziedzinowych i YAML przy wdrażaniu chmury. Badamy, jak Pulumi umożliwia Infrastructure as Code przy użyciu języków programowania ogólnego przeznaczenia. Poznasz podstawową różnicę między deklaratywnym stanem chmury a imperatywnymi językami używanymi do jego definiowania.
4m 24s
2
Pod maską: Architektura Pulumi
Zanurz się w wewnętrzne mechanizmy wdrożeń Pulumi. Omawiamy role hosta języka, silnika wdrożeniowego i dostawców zasobów. Zrozumiesz dokładnie, w jaki sposób wywołanie funkcji w Twoim kodzie staje się fizycznym zasobem w chmurze.
3m 41s
3
Witaj Azure: Tworzenie pierwszego projektu
Rozpocznij swoją przygodę z infrastrukturą, tworząc projekt Pulumi docelowo dla Microsoft Azure. Przechodzimy przez proces konfiguracji w CLI i analizujemy automatycznie wygenerowane pliki. Dowiesz się, jak w kilka sekund zainicjować czysty, gotowy do wdrożenia projekt chmurowy.
3m 56s
4
Projekty i ścieżki: Strukturyzacja kodu
Zrozum anatomię projektu Pulumi i dowiedz się, jak poprawnie odwoływać się do plików lokalnych. Analizujemy plik Pulumi.yaml oraz kluczową różnicę między ścieżkami bezwzględnymi a względnymi względem projektu. Dowiesz się, jak zapewnić bezproblemowe wdrażanie kodu na różnych maszynach i w potokach CI.
4m 07s
5
Stacks: Zarządzanie środowiskami
Odkryj, jak bezpiecznie zarządzać wieloma środowiskami, takimi jak Development, Staging i Production. Wprowadzamy pojęcie Stacks i pokazujemy, jak izolują one stan wdrożenia. Dowiesz się, jak współdzielić dane między środowiskami za pomocą Stack References.
4m 28s
6
Bloki konstrukcyjne: Zasoby Pulumi
Zanurz się w to, jak zasoby chmurowe są reprezentowane i nazywane w kodzie. Porównujemy Custom Resources z Component Resources i odkrywamy tajemnicę nazw logicznych w stosunku do fizycznych. Dowiesz się, jak automatyczne nazywanie zapobiega globalnym kolizjom i dba o bezpieczeństwo Twoich wdrożeń.
4m 16s
7
Ochrona sekretów: Zarządzanie konfiguracją
Dowiedz się, jak wstrzykiwać dynamiczne dane i wrażliwe sekrety do kodu infrastruktury. Omawiamy polecenia konfiguracyjne Pulumi CLI, konfigurację strukturalną oraz natywne szyfrowanie sekretów. Zdobędziesz wiedzę, jak zabezpieczyć klucze API bez ujawniania ich otwartym tekstem.
4m 14s
8
Skalowanie: Component Resources na platformie Azure
Wznieś swoją infrastrukturę na wyższy poziom, tworząc komponenty wielokrotnego użytku. Przechodzimy przez proces budowania komponentu Azure Static Website, który hermetyzuje wiele zasobów. Poznasz znaczenie relacji rodzic-dziecko dla przejrzystego śledzenia infrastruktury.
4m 25s
9
Pokojowe współistnienie: Odczytywanie stanu Terraform
Wypełnij lukę między starszą infrastrukturą a nowoczesnym kodem. Badamy, w jaki sposób Pulumi może bezpośrednio odczytywać istniejące pliki stanu Terraform. Poznasz potężny wzorzec współistnienia, który pozwala na przyrostowe wdrażanie Pulumi bez konieczności przepisywania całego stosu.
4m 05s
10
Wielka migracja: Konwersja HCL na Pulumi
Zrób ostatni krok, tłumacząc Terraform HCL na w pełni funkcjonalny kod programistyczny. Analizujemy narzędzie `pulumi convert` i omawiamy, kiedy i dlaczego warto konwertować starsze konfiguracje. Dowiesz się, jak prawdziwe języki odblokowują zaawansowane testy jednostkowe dla infrastruktury.
3m 59s

Odcinki

1

Infrastruktura programisty: Dlaczego Pulumi?

4m 24s

Odkryj, dlaczego programiści odchodzą od języków dziedzinowych i YAML przy wdrażaniu chmury. Badamy, jak Pulumi umożliwia Infrastructure as Code przy użyciu języków programowania ogólnego przeznaczenia. Poznasz podstawową różnicę między deklaratywnym stanem chmury a imperatywnymi językami używanymi do jego definiowania.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 1 z 10. A co, gdybyś mógł napisać swoją infrastrukturę chmurową w dokładnie tym samym języku programowania, którego używasz w swojej aplikacji? Koniec z context-switchingiem między logiką aplikacji a tysiącami linijek customowego markupu. The Developer's Infrastructure: Why Pulumi? omawia dokładnie tę zmianę. Historycznie Infrastructure as Code oznaczało pisanie w domain-specific languages albo tworzenie nieskończonych bloków YAML-a. Jeśli chciałeś zdeployować bazę danych i serwer, musiałeś nauczyć się składni przeznaczonej wyłącznie dla tego konkretnego narzędzia do provisioningu. Traciłeś bogaty ekosystem standardowej inżynierii oprogramowania. Nie mogłeś łatwo napisać pętli, zintegrować standardowych frameworków testowych ani współdzielić logiki za pomocą standardowych package registries. Pulumi zmienia ten fundament. To platforma Infrastructure as Code, która pozwala ci budować, deployować i zarządzać zasobami chmurowymi za pomocą języków programowania ogólnego przeznaczenia. Zamiast uczyć się dedykowanego języka konfiguracji, używasz TypeScriptu, Pythona, Go, C# lub Javy. Wyobraź sobie programistę definiującego zasoby chmurowe za pomocą TypeScriptu. W przypadku tradycyjnych narzędzi stale robisz context-switching, żeby sprawdzać schematy YAML-a w przeglądarce. Z Pulumi zostajesz w swoim edytorze. Tworzysz instancję klasy zasobu, wpisujesz kropkę, a standardowe auto-completion w IDE pokazuje ci dokładnie, jakie właściwości są dostępne. Masz inline'owe type-checking, zanim w ogóle uruchomisz deployment. Jeśli potrzebujesz trzech identycznych storage bucketów, piszesz standardowy for-loop. Jeśli twoja firma wymusza określone reguły bezpieczeństwa na każdym serwerze, abstrahujesz tę logikę do standardowej funkcji, publikujesz ją w standardowym package registry i pozwalasz innym zespołom ją importować, tak jak każdą zwykłą bibliotekę kodu. Oto kluczowa sprawa. Ponieważ piszesz tę infrastrukturę w językach imperatywnych, możesz założyć, że Pulumi to po prostu skrypt automatyzacji, który sekwencyjnie wywołuje cloud API. To nie jest imperatywny skrypt wykonawczy. Pulumi pod spodem nadal wykorzystuje bardzo solidny, deklaratywny model stanu. Kiedy wykonujesz swój program w Pulumi, nie provisionuje on od razu zasobów linijka po linijce. Zamiast tego, twój kod uruchamia się, żeby skonstruować pożądany stan końcowy twojej infrastruktury. Silnik Pulumi przechwytuje te definicje zasobów i buduje ścisły graf zależności. Następnie porównuje ten pożądany stan z aktualnym, rzeczywistym stanem twojego środowiska chmurowego. Pulumi oblicza dokładną różnicę i wykonuje tylko te konkretne operacje create, update lub delete, które są wymagane, żeby rzeczywistość odpowiadała twojemu kodowi. Piszesz z ekspresją języka imperatywnego, ale zyskujesz bezpieczeństwo i przewidywalność deklaratywnego silnika deploymentu. Używając języków ogólnego przeznaczenia, odblokowujesz dostęp do istniejących linterów, frameworków do unit testingu i continuous integration pipelines. Pulumi po prostu przestaje traktować infrastrukturę jako odrębną domenę konfiguracji i przekształca ją w standardowe oprogramowanie, podlegające dokładnie tym samym rygorom i toolingowi, co twoja główna aplikacja. Jeśli chciałbyś wesprzeć nasz program, możesz nas znaleźć, wyszukując DevStoriesEU w serwisie Patreon. Chciałbym poświęcić chwilę, żeby podziękować ci za słuchanie — to bardzo nam pomaga. Miłego dnia!
2

Pod maską: Architektura Pulumi

3m 41s

Zanurz się w wewnętrzne mechanizmy wdrożeń Pulumi. Omawiamy role hosta języka, silnika wdrożeniowego i dostawców zasobów. Zrozumiesz dokładnie, w jaki sposób wywołanie funkcji w Twoim kodzie staje się fizycznym zasobem w chmurze.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 2 z 10. Tworzysz instancję standardowej klasy Pythona w edytorze, klikasz deploy, a kilka sekund później w chmurze istnieje już storage bucket. Jak dokładnie lokalny obiekt w pamięci przekłada się na zdalny zasób fizyczny? Dzisiaj odpowiemy na to pytanie, zaglądając pod maskę architektury Pulumi. Krąży powszechne, błędne przekonanie na temat tego, jak działa to narzędzie. Kiedy piszesz skrypt deploymentowy, twój kod nie komunikuje się z cloudowymi API. Runtime twojego kodu w Pythonie, Node lub Go nie ma absolutnie pojęcia, jak dogadać się z Amazon Web Services. Zamiast tego Pulumi dzieli proces deploymentu na trzy odrębne komponenty: Language Host, Deployment Engine i Resource Providers. Wszystko zaczyna się od Language Hosta. Ten komponent ewaluuje twój program i wyciąga z niego twoje intencje. Weźmy na przykład skrypt w Pythonie, w którym deklarujesz bucket AWS S3 poprzez inicjalizację obiektu bucket. Pythonowy Language Host uruchamia twój skrypt linijka po linijce. Kiedy trafia na deklarację tego bucketa, nie robi żadnego requestu sieciowego do AWS. Po prostu wysyła request rejestracji do Deployment Engine. Mówi silnikowi, że chcesz, aby istniał bucket o określonych properties. Language Host komunikuje ten pożądany state przez lokalne połączenie, a następnie się zatrzymuje, czekając na odpowiedź przed ewaluacją kolejnej linijki kodu. Deployment Engine odbiera ten request rejestracji. Ten komponent to orkiestrator. Silnik nie wie nic o składni Pythona i nie wie nic o AWS API. Jego jedynym zadaniem jest state management. Patrzy na pożądany state wysłany przez Language Host i porównuje go z ostatnim znanym, rzeczywistym statem twojej infrastruktury. Jeśli silnik widzi, że ten konkretny bucket S3 nie istnieje w obecnym state, kalkuluje diffa i ustala, że wymagana jest operacja create. Aby faktycznie zbudować ten bucket, silnik przekazuje zadanie trzeciemu komponentowi, czyli Resource Providerowi. Providery to samodzielne pluginy pobierane dla konkretnych platform, takich jak AWS, Azure czy Kubernetes. Deployment Engine wysyła instrukcję do AWS Resource Providera, mówiąc mu, żeby utworzył bucket z żądanymi properties. I tu jest kluczowa sprawa. Resource Provider to jedyny komponent w całym tym chainie, który wie, jak gadać z chmurą. Bierze generyczną komendę create od silnika, tłumaczy ją na konkretne calle REST API wymagane przez AWS i wykonuje je przez sieć. Kiedy AWS sprovisionuje bucket S3, zwraca fizyczne ID zasobu. Resource Provider przechwytuje to fizyczne ID i przekazuje je z powrotem do Deployment Engine. Silnik aktualizuje swój wewnętrzny state, aby zapisać, że bucket istnieje już w prawdziwym świecie. Na koniec silnik daje znać z powrotem do Language Hosta, że zasób jest gotowy, przekazując wszystkie output properties, takie jak nazwa bucketa czy URL. Language Host wznawia egzekucję, a twój skrypt w Pythonie przechodzi do następnej instrukcji. Ta ścisła separacja ewaluacji języka, orkiestracji state'u i egzekucji w chmurze to coś, co daje tej architekturze jej elastyczność. Możesz dodać nowy język programowania bez dotykania cloud providerów, i dodać nowego cloud providera bez modyfikowania Language Hostów. To wszystko w tym odcinku. Do usłyszenia następnym razem!
3

Witaj Azure: Tworzenie pierwszego projektu

3m 56s

Rozpocznij swoją przygodę z infrastrukturą, tworząc projekt Pulumi docelowo dla Microsoft Azure. Przechodzimy przez proces konfiguracji w CLI i analizujemy automatycznie wygenerowane pliki. Dowiesz się, jak w kilka sekund zainicjować czysty, gotowy do wdrożenia projekt chmurowy.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 3 z 10. Konfiguracja projektu infrastruktury chmurowej oznaczała kiedyś godziny walki z plikami typu boilerplate i strukturą folderów, zanim mogłeś napisać choćby jedną linijkę logiki. Dziś możesz zescaffoldować kompletne środowisko w kilka sekund. Skupiamy się na Hello Azure: Creating Your First Project, aby zobaczyć dokładnie, jak to się dzieje. Częstym błędem jest myślenie, że odpalenie komendy tworzącej projekt natychmiast buduje infrastrukturę w chmurze. Wcale tak nie jest. Komenda, którą omawiamy, generuje tylko lokalne pliki i przygotowuje śledzenie twojego state'u. Żadne rzeczywiste zasoby na Azure nie zostaną utworzone, dopóki później jawnie nie odpalisz komendy deploy. Aby zbootstrapować nowy projekt, używasz CLI. Najpierw tworzysz pusty katalog i do niego przechodzisz. Następnie odpalasz komendę pulumi new, a po niej podajesz nazwę template'u. Dla Azure ten template to zazwyczaj azure myślnik i twój wybrany język programowania, na przykład azure myślnik typescript albo azure myślnik python. Kiedy to zrobisz, interfejs staje się interaktywny. Przeprowadzi cię przez serię promptów, żeby skonfigurować twoje środowisko. Najpierw zapyta o nazwę projektu, która domyślnie jest nazwą twojego katalogu. Następnie poprosi o opis projektu. Potem zapyta o nazwę stacka. Stack to izolowana instancja twojego projektu, zazwyczaj reprezentująca środowisko, takie jak development czy produkcja. Domyślny stack nazywa się dev. Na koniec, template'y Azure wyświetlą prompt o lokalizację Azure, na przykład WestUS, która zostanie zapisana jako twój domyślny region do deployu. Kiedy odpowiesz na prompty, narzędzie pobierze template, zainstaluje niezbędne zależności językowe i utworzy kilka plików w twoim katalogu. Oto kluczowa sprawa. Najważniejszym wygenerowanym plikiem jest Pulumi dot yaml. To twój główny plik projektu. Definiuje nazwę projektu, używany runtime oraz opis. W zasadzie mówi systemowi, jak wykonać twój kod. Zobaczysz też plik o nazwie Pulumi dot dev dot yaml, jeśli zaakceptowałeś domyślną nazwę stacka. Ten dodatkowy plik przechowuje wartości konfiguracyjne specyficzne dla tego stacka, w tym region Azure, który właśnie wybrałeś. Oprócz nich dostajesz standardowe pliki zależności, które różnią się w zależności od wybranego języka, oraz twój plik entrypoint. Wewnątrz pliku entrypoint, domyślny template Azure dostarcza działający przykład Azure Storage Account. Logika kodu przebiega w trzech jasnych krokach. Po pierwsze, importuje pakiet Azure Native. Po drugie, deklaruje nową Azure Resource Group, nadając jej logiczną nazwę, żeby plik state'u mógł ją śledzić. Po trzecie, deklaruje Azure Storage Account. Tutaj robi się ciekawie. Zamiast hardcodować nazwę resource group, storage account pobiera property name bezpośrednio z obiektu resource group utworzonego w poprzednim kroku. To tworzy niejawną zależność. System wie teraz, że musi skończyć tworzenie resource group, zanim spróbuje utworzyć storage account. Template automatycznie wypełnia też wymagane argumenty dla storage account, takie jak account replication type i account tier. Na samym końcu pliku, kod eksportuje wartość. W tym zescaffoldowanym przykładzie, eksportuje primary storage key nowo zdefiniowanego storage account. Kiedy w końcu zrobisz deploy, ta wyeksportowana wartość zostanie wypisana bezpośrednio w twojej konsoli, co ułatwi ci pobranie connection strings lub endpointów bez logowania się do Azure portal. Przechodzisz od pustego folderu do w pełni spiętego programu infrastrukturalnego po prostu odpowiadając na kilka promptów, co daje ci solidną, poprawną składniowo podstawę do rozpoczęcia budowania własnej architektury. Dzięki za wysłuchanie, udanego kodowania wszystkim!
4

Projekty i ścieżki: Strukturyzacja kodu

4m 07s

Zrozum anatomię projektu Pulumi i dowiedz się, jak poprawnie odwoływać się do plików lokalnych. Analizujemy plik Pulumi.yaml oraz kluczową różnicę między ścieżkami bezwzględnymi a względnymi względem projektu. Dowiesz się, jak zapewnić bezproblemowe wdrażanie kodu na różnych maszynach i w potokach CI.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 4 z 10. Twój skrypt deploymentowy działa idealnie na twoim laptopie. Robisz pusha, twój zautomatyzowany pipeline się uruchamia, a build natychmiast failuje, bo nie może znaleźć pliku źródłowego. Nic w kodzie się nie zmieniło, ale katalog, w którym wykonano komendę, trochę się zmienił. To klasyczna pułapka ze ścieżkami, a żeby jej uniknąć, musisz zrozumieć temat Projekty i ścieżki: Strukturyzacja kodu. W istocie projekt Pulumi to po prostu folder zawierający plik o nazwie Pulumi.yaml. Ten plik jest kotwicą. Informuje on CLI, że w tym konkretnym katalogu znajduje się logika twojej infrastruktury. W pliku Pulumi.yaml deklarujesz metadane, takie jak nazwa projektu, opis i język runtime'u. Właściwość runtime decyduje o tym, jak twój kod faktycznie się wykonuje. Jeśli wskażesz Pythona, runtime będzie szukać głównego pliku Pythona w tym katalogu. Jeśli wskażesz Node'a, poszuka on entrypointu zdefiniowanego w twoim pliku package, którym zazwyczaj jest plik index. Jeśli wolisz trzymać swój kod źródłowy w podfolderze, a nie w głównym katalogu projektu, możesz jawnie nadpisać to zachowanie, ustawiając właściwość main w pliku Pulumi.yaml tak, aby wskazywała na ten konkretny podfolder. Przyjrzyjmy się teraz częstym nieporozumieniom dotyczącym ścieżek plików. Załóżmy, że budujesz obraz dockerowy jako część swojej infrastruktury, a twój Dockerfile siedzi w podkatalogu o nazwie app, tuż obok twojego kodu Pulumi. Inżynierowie często przekazują ścieżkę absolutną ze swojej lokalnej maszyny, żeby powiedzieć Pulumi, gdzie jest Dockerfile. Ale ścieżka absolutna zawiera twój osobisty katalog użytkownika. Kiedy ktoś z zespołu robi pulla kodu i odpala update, engine widzi inną ścieżkę absolutną na jego maszynie. Rejestruje to jako zmianę strukturalną zasobu, tworząc niepotrzebny drift w stanie twojej infrastruktury. Żeby to naprawić, możesz przejść na standardową ścieżkę względną, taką jak kropka slash app. Standardowe ścieżki względne polegają całkowicie na bieżącym katalogu roboczym terminala, który wykonuje kod. Jeśli twój system CI odpala komendę z katalogu wyżej w repozytorium, ścieżka względna resolvuje się nieprawidłowo i deployment crashuje. Oto kluczowy wniosek. Potrzebujesz ścieżek, które są całkowicie niezależne od maszyny, na której działają, i niezależne od miejsca, w którym użytkownik wpisał komendę. Potrzebujesz ścieżek relatywnych do projektu. Pulumi dostarcza wbudowaną funkcję do pobierania dokładnej lokalizacji pliku Pulumi.yaml podczas działania kodu. W zależności od twojego języka programowania, ta funkcja zazwyczaj nazywa się get root directory lub podobnie. Kiedy wywołasz tę funkcję, runtime zwraca ścieżkę absolutną do folderu zawierającego twój plik Pulumi.yaml. Zamiast hardcodować ścieżkę do twojego Dockerfile'a, konstruujesz ją dynamicznie. Bierzesz wynik funkcji root directory i doklejasz do niego swój podkatalog app. Ponieważ ta funkcja ewaluuje się dynamicznie przy każdym uruchomieniu, wynikowa ścieżka jest zawsze idealnie dopasowana do środowiska, w którym działa kod. Twoja lokalna maszyna, laptop kogoś z zespołu i zdalny build server wygenerują poprawną ścieżkę absolutną dla swoich specyficznych systemów plików. Ścieżka pliku resolvuje się spójnie za każdym razem, a engine wykrywa zero zmian w definicji zasobu. Twój kod infrastruktury nigdy nie powinien się przejmować tym, gdzie żyje na dysku twardym. Zawsze kotwicz swoje assety plikowe do funkcji root directory w Pulumi, upewniając się, że twój projekt pozostaje całkowicie przenośny w każdym środowisku. To wszystko w tym odcinku. Dzięki za wysłuchanie i budujcie dalej!
5

Stacks: Zarządzanie środowiskami

4m 28s

Odkryj, jak bezpiecznie zarządzać wieloma środowiskami, takimi jak Development, Staging i Production. Wprowadzamy pojęcie Stacks i pokazujemy, jak izolują one stan wdrożenia. Dowiesz się, jak współdzielić dane między środowiskami za pomocą Stack References.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 5 z 10. Copy-pasting twojego kodu infrastruktury, żeby stworzyć środowisko stagingowe, to przepis na drift i katastrofę. W efekcie utrzymujesz wiele folderów z niemal identycznymi plikami, a w końcu ktoś zapomina zaktualizować produkcję. Rozwiązaniem jest traktowanie twoich środowisk jako izolowanych instancji jednego codebase'u przy użyciu Stacks. Zanim przejdziemy dalej, wyjaśnijmy częste nieporozumienie. Project w Pulumi to po prostu katalog zawierający twój kod źródłowy. To tylko instrukcje. Stack to aktywna instancja deploymentu tego kodu. Piszesz Project raz i robisz jego deploy wielokrotnie jako różne Stacks. Stacks pozwalają ci zarządzać różnymi środowiskami, takimi jak dev, staging i produkcja, bez duplikowania jakiegokolwiek kodu. Kiedy odpalasz Pulumi update, aplikuje kod z twojego Projectu do tego Stacka, który jest aktualnie aktywny. Każdy Stack utrzymuje swój własny, izolowany plik state, śledząc tylko zasoby utworzone dla tego konkretnego środowiska. Zarządzanie tymi środowiskami odbywa się bezpośrednio w twoim terminalu. Tworzysz nowe środowisko, odpalając komendę stack initialize i nadając mu nazwę, taką jak dev lub prod. Pulumi rejestruje tę nową instancję i tworzy dla niej świeży state. Żeby zmienić context, używasz komendy stack select. Pulumi CLI zapamiętuje, który stack jest aktywny. Jeśli wybierzesz stack dev i odpalisz update, Pulumi patrzy tylko na deweloperski state. Provisionuje lub modyfikuje infrastrukturę deweloperską, zostawiając twoje środowiska stagingowe i produkcyjne całkowicie nietknięte. To by było na tyle, jeśli chodzi o deploy izolowanych środowisk. Ale co się dzieje, kiedy te środowiska muszą się komunikować? Czasami jeden stack polega na informacjach wygenerowanych przez inny. Możesz mieć jeden Project zarządzający core'ową infrastrukturą i całkowicie oddzielny Project obsługujący kod aplikacji. Powiedzmy, że masz Project infrastruktury, który provisionuje klaster Kubernetes. Robisz jego deploy jako stack o nazwie base-infra-prod. Podczas deploymentu klaster generuje dynamiczny connection string. Teraz masz drugi Project dla microservice'u, który musi zrobić deploy do dokładnie tego samego klastra. Nie chcesz hardcodować connection stringa i nie chcesz mergować obu Projectów w jeden ogromny, powolny plik state. Tutaj robi się ciekawie. Możesz bezpiecznie połączyć te deploymenty, używając Stack Reference. Stack Reference pozwala jednemu stackowi odczytać wyeksportowane outputy z innego stacka. Żeby to skonfigurować, twój program klastra Kubernetes musi jawnie zrobić export connection stringa na końcu swojego działania. Export to po prostu zmienna, którą Pulumi zapisuje w state stacka specjalnie po to, żeby można ją było odczytać z zewnątrz. Następnie, w twoim programie microservice'u, tworzysz obiekt Stack Reference. Przekazujesz mu nazwę stacka infrastruktury, z którego chcesz czytać. Następnie wywołujesz metodę get output na tej referencji, prosząc o connection string po jego wyeksportowanej nazwie. Twój microservice może teraz użyć tej wartości do skonfigurowania swojego deploymentu. Stack microservice'u nie może modyfikować stacka klastra. Może jedynie odczytać konkretne wartości, które stack klastra zdecydował się wyeksportować. To wymusza czystą granicę. Możesz robić update i skalować swoją core'ową infrastrukturę sieciową całkowicie niezależnie od workloadów aplikacji, jednocześnie bezpiecznie przekazując niezbędne szczegóły połączenia przez tę granicę. Decouplując twój kod od instancji środowiska, gwarantujesz, że każda warstwa twojego systemu przechodzi przez dokładnie tę samą logikę, usuwając ukryte ryzyko ręcznej duplikacji. To wszystko w tym odcinku. Dzięki za wysłuchanie i kodujcie dalej!
6

Bloki konstrukcyjne: Zasoby Pulumi

4m 16s

Zanurz się w to, jak zasoby chmurowe są reprezentowane i nazywane w kodzie. Porównujemy Custom Resources z Component Resources i odkrywamy tajemnicę nazw logicznych w stosunku do fizycznych. Dowiesz się, jak automatyczne nazywanie zapobiega globalnym kolizjom i dba o bezpieczeństwo Twoich wdrożeń.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 6 z 10. Robisz deploy kodu infrastruktury, składnia jest bezbłędna, i od razu wywala błąd, bo nazwa storage bucketu jest już zajęta. Albo co gorsza, aktualizujesz instancję bazy danych, a twoje narzędzie usuwa starą przed utworzeniem nowej, powodując poważny outage. Możesz rozwiązać oba te problemy, jeśli zrozumiesz, jak twoje narzędzie do infrastruktury obsługuje tożsamość. I to jest dokładnie to, co dzisiaj omawiamy: Podstawowe elementy, czyli Pulumi Resources. W Pulumi zasób to obiekt reprezentujący kawałek infrastruktury. Są dwa główne typy, z którymi będziesz pracować. Pierwszy z nich to Custom Resource. Mapuje się on bezpośrednio na fizyczny obiekt zarządzany przez cloud providera. Kiedy deklarujesz Custom Resource, Pulumi robi API call do Amazona, Azure'a lub Google Cloud, żeby utworzyć dokładnie ten obiekt, na przykład maszynę wirtualną albo load balancer. Drugi typ to Component Resource. Component Resource nie mapuje się na pojedynczy element infrastruktury w chmurze. Zamiast tego, jest to logiczny kontener na inne zasoby. Używasz Component Resources do budowania abstrakcji wyższego poziomu. Na przykład, możesz utworzyć pojedynczy Component Resource o nazwie Secure Web Server, który pod spodem provisionuje maszynę wirtualną, security group i adres IP. Sam Component Resource po prostu grupuje je w twoim state file'u, dzięki czemu twój kod jest czystszy i łatwiejszy w zarządzaniu. Niezależnie od tego, czy definiujesz Custom Resource, czy Component Resource, każdy z nich wymaga nazwy. I tu pojawia się częste źródło frustracji. Ludzie wpisują nazwę w kodzie, robią deploy, a potem sprawdzają konsolę chmurową tylko po to, by odkryć, że ich zasób ma losowy string znaków doklejony na końcu nazwy. To nie jest bug. To kluczowy feature tego, jak działa Pulumi, i musisz zrozumieć różnicę między nazwą logiczną a nazwą fizyczną. Nazwa logiczna to ta, którą wpisujesz w kodzie jako argument. Pulumi używa tej logicznej nazwy do śledzenia zasobu w swoim state file'u. To dzięki niej Pulumi wie, że baza danych w twoim dzisiejszym kodzie to dokładnie ta sama baza, którą zdeployowałeś wczoraj. Nazwa fizyczna to to, jak cloud provider faktycznie nazywa ten zasób w swoim własnym systemie. Domyślnie Pulumi bierze twoją logiczną nazwę, dodaje losowy sufiks i używa tego połączonego stringa jako nazwy fizycznej. To się nazywa auto-naming. Oto kluczowa sprawa. Auto-naming zapobiega globalnym kolizjom nazw i umożliwia replacementy z zero-downtime. Pomyśl o provisionowaniu wielu identycznych storage bucketów w pętli przy użyciu Azure. Azure wymaga, żeby nazwy storage accountów były globalnie unikalne wśród wszystkich klientów. Jeśli spróbujesz wymusić sztywną nazwę fizyczną, drugi bucket w twojej pętli wywali błąd, bo nazwa jest zajęta, albo co gorsza, ktoś inny na świecie może już ją mieć. Dzięki auto-namingowi możesz po prostu użyć logicznej nazwy, takiej jak archive-bucket, wewnątrz pętli. Pulumi będzie logicznie śledzić każdą iterację, zapewniając, że każdy bucket dostanie matematycznie unikalną nazwę fizyczną w Azure. Auto-naming chroni również uptime twojego systemu. Jeśli wprowadzisz zmianę, która wymusza replacement zasobu, Pulumi najpierw tworzy nowy zasób, weryfikuje, czy działa, a dopiero potem usuwa stary. Jeśli nadpiszesz auto-naming i wymusisz sztywną nazwę fizyczną, cloud provider nie pozwoli dwóm zasobom na współdzielenie tej samej nazwy w tym samym czasie. Pulumi byłoby zmuszone najpierw usunąć twój stary zasób, powodując downtime podczas gdy nowy się provisionuje. Jeśli chcesz pomóc w utrzymaniu podcastu, możesz wyszukać DevStoriesEU na Patreonie. Utrzymuj elastyczność swoich nazw fizycznych. Pozwól narzędziu zarządzać losowymi sufiksami, ponieważ podczas gdy twój state file wymaga logicznej nazwy do utrzymania porządku, twoje środowisko produkcyjne polega na fizycznej elastyczności, żeby pozostać online. Dzięki za wysłuchanie. Trzymajcie się wszyscy.
7

Ochrona sekretów: Zarządzanie konfiguracją

4m 14s

Dowiedz się, jak wstrzykiwać dynamiczne dane i wrażliwe sekrety do kodu infrastruktury. Omawiamy polecenia konfiguracyjne Pulumi CLI, konfigurację strukturalną oraz natywne szyfrowanie sekretów. Zdobędziesz wiedzę, jak zabezpieczyć klucze API bez ujawniania ich otwartym tekstem.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 7 z 10. Hardcodowanie hasła do bazy danych w kodzie infrastruktury to gwarantowana katastrofa bezpieczeństwa. Ale ręczne wstrzykiwanie zmiennych środowiskowych do każdego deployment pipeline'u jest kruche i trudne do śledzenia. Potrzebujesz sposobu na automatyczne powiązanie konkretnych, zaszyfrowanych wartości z konkretnymi środowiskami. To jest Keeping Secrets: Configuration Management. Główna idea to oddzielenie twojego kodu od konfiguracji. Chcesz napisać logikę swojej infrastruktury dokładnie raz. Następnie, kiedy robisz deploy na swój stack deweloperski, kod provisionuje małe instancje. Kiedy robisz deploy na produkcję, provisionuje duże instancje i używa produkcyjnych credentials do bazy danych. Pulumi ogarnia to za pomocą wbudowanego systemu konfiguracji. Często mylące jest to, jak te wartości są właściwie przechowywane. Ustawienie wartości konfiguracji w Pulumi nie ustawia lokalnych zmiennych środowiskowych systemu operacyjnego. Zamiast tego, zapisuje wartości bezpośrednio w pliku o nazwie Pulumi kropka stack-name kropka yaml. Ponieważ każdy stack dostaje swój własny, osobny plik konfiguracyjny, twoja konfiguracja dev i konfiguracja prod żyją obok siebie w repozytorium, czysto oddzielone nazwą pliku. Dodajesz dane do tego pliku używając CLI Pulumi. Jeśli odpalisz komendę pulumi config set frontendPort 8080, Pulumi zapisze tę parę klucz-wartość bezpośrednio w pliku yaml dla twojego obecnie aktywnego stacku. Aby użyć tej wartości w swoim kodzie infrastruktury, tworzysz instancję obiektu Config. Następnie wywołujesz na tym obiekcie metodę taką jak get lub require, przekazując nazwę klucza. Różnica jest prosta. Wywołanie get zwraca wartość, jeśli ta istnieje, lub nic, jeśli jej nie ma. Wywołanie require wyrzuci błąd i zatrzyma twój deploy, jeśli brakuje klucza konfiguracji. To świetny sposób, by upewnić się, że deploy nigdy nie pójdzie dalej bez wymaganego ustawienia. Nie ograniczasz się tylko do prostych stringów. Możesz przechowywać i pobierać ustrukturyzowane dane, takie jak blok JSON definiujący parametry skalowania, i parsować je bezpośrednio do obiektu w swoim kodzie. A co się dzieje, gdy ta wartość konfiguracji jest bardzo wrażliwa? Załóżmy, że twoja aplikacja musi połączyć się z zewnętrzną bazą danych i musisz przekazać hasło do bazy do swojej infrastruktury. Absolutnie nie możesz przechowywać tego jako plaintext w swoim pliku yaml, ponieważ ten plik jest commitowany do kontroli wersji. I tu wkraczają sekrety Pulumi. Używasz dokładnie tego samego CLI, ale dodajesz flagę secret. Odpalasz pulumi config set dbPassword your-password myślnik myślnik secret. Pulumi szyfruje tę wartość przed zapisaniem jej w pliku yaml. Jeśli ktoś zajrzy do pliku w twoim repozytorium, zobaczy tylko string w postaci ciphertextu, bezpiecznie zaszyfrowany przez encryption providera twojego stacku. W swoim kodzie pobierasz to bezpiecznie, wywołując specjalną metodę secret na obiekcie Config, taką jak requireSecret. I tu jest kluczowa sprawa. Kiedy pobierasz sekret w ten sposób, Pulumi opakowuje go w specjalny typ secret. Kiedy ta wartość przepływa przez twój kod infrastruktury i jest przekazywana do zasobów, silnik Pulumi ją śledzi. Upewnia się, że wartość plaintext jest zamaskowana w outpucie konsoli podczas deployu, i gwarantuje, że wartość pozostaje zaszyfrowana w twoim pliku state Pulumi. Konfiguracja pozwala ci napisać kod infrastruktury raz i bezpiecznie promować go pomiędzy środowiskami. Natywne szyfrowanie sekretów gwarantuje, że twoje wrażliwe credentials napędzają te deploye bez wyciekania do kontroli wersji czy plików state. Dzięki za spędzenie ze mną tych kilku minut. Do usłyszenia następnym razem, trzymaj się.
8

Skalowanie: Component Resources na platformie Azure

4m 25s

Wznieś swoją infrastrukturę na wyższy poziom, tworząc komponenty wielokrotnego użytku. Przechodzimy przez proces budowania komponentu Azure Static Website, który hermetyzuje wiele zasobów. Poznasz znaczenie relacji rodzic-dziecko dla przejrzystego śledzenia infrastruktury.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 8 z 10. Kopiujesz i wklejasz blok kodu storage'u i sieci po raz piąty w tym tygodniu. Twój kod infrastruktury rośnie, ale nie staje się mądrzejszy. Zamiast powtarzać identyczne konfiguracje chmurowe za każdym razem, gdy potrzebujesz standardowego setupu, możesz je generować za pomocą jednej jednostki logicznej. Na tym skupia się ten odcinek: Skalowanie w górę: Component Resources na Azure. Kiedy zaczynasz korzystać z Pulumi, deklarujesz surowe zasoby. Resource Group tu, Storage Account tam. Jednak wraz z rozwojem systemu, deployowanie standardowego kawałka architektury wymaga prowizjonowania dokładnie tego samego zestawu prymitywów raz za razem. To łamie zasadę Don't Repeat Yourself. Component Resources rozwiązują ten problem, pozwalając ci enkapsulować wiele fizycznych zasobów chmurowych w jedną abstrakcję wielokrotnego użytku. Pomyśl o Component Resource jak o customowej klasie, którą definiujesz w wybranym języku programowania. Po zdefiniowaniu, tworzysz jej instancję dokładnie tak samo, jak wbudowanego zasobu Pulumi. Wyobraź sobie scenariusz, w którym często deployujesz statyczne strony na Azure. Minimalny setup wymaga Azure Resource Group, Storage Account skonfigurowanego pod hosting statycznych stron oraz obiektu Blob, który służy jako dokument index. Zamiast pisać te trzy definicje w głównym programie za każdym razem, tworzysz komponent statycznej strony na Azure. Aby go zbudować, definiujesz nową klasę, która dziedziczy po klasie bazowej Pulumi ComponentResource. Konstruktor twojej klasy przyjmuje nazwę, zestaw argumentów do customizacji i standardowe resource options. Pierwszą rzeczą, którą robi twój konstruktor, jest wywołanie konstruktora klasy bazowej. Przekazujesz mu unikalny type token, na przykład custom dwukropek infrastructure dwukropek static website, razem z nazwą. Ten type token mówi silnikowi, jak śledzić twoją nową abstrakcję w state file'u. Następnie definiujesz właściwe prymitywy Azure wewnątrz konstruktora. Deklarujesz Resource Group. Deklarujesz Storage Account wewnątrz tej grupy. Wrzucasz index blob na to konto. I tu jest kluczowa sprawa. Kiedy tworzysz te wewnętrzne zasoby, musisz jawnie powiedzieć silnikowi, że należą one do twojego nowego komponentu. Robisz to, przekazując samą instancję komponentu do resource options pod właściwością parent. Wielu inżynierów zapomina o tym kroku. Jeśli pominiesz opcję parent, child resources zostaną sprowizjonowane pomyślnie, ale będą traktowane jako zasoby top-level. Twój output w command line będzie płaską, mylącą listą. Ustawiając właściwość parent na instancję twojego komponentu, silnik organizuje state tree. Kiedy odpalasz update, interfejs wizualnie zagnieżdża Resource Group, Storage Account i Blob bezpośrednio pod twoim customowym komponentem strony. Dzięki temu twój state jest łatwy w zarządzaniu, a output czytelny. Na koniec, twój główny program prawdopodobnie musi znać adres webowy nowo utworzonej strony. Wewnątrz komponentu, po zdefiniowaniu Storage Account, mapujesz jego główny web endpoint na publiczną właściwość w twojej klasie. Następnie wywołujesz metodę o nazwie register outputs. To finalizuje inicjalizację i zapewnia, że końcowy adres jest wyeksponowany dla reszty twojego programu i wypisany w konsoli po zakończeniu deployu. W twoim głównym pliku nie widzisz już boilerplate'u. Po prostu tworzysz instancję swojego komponentu strony, przekazujesz mu plik index i robisz deploy. Zasoby pod spodem są bezpiecznie zarządzane za tą abstrakcją. Prawdziwa siła Infrastructure as Code polega na traktowaniu architektury chmurowej jak oprogramowania, a Component Resources to sposób na zbudowanie standardowej, niezawodnej biblioteki dla twojego zespołu. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
9

Pokojowe współistnienie: Odczytywanie stanu Terraform

4m 05s

Wypełnij lukę między starszą infrastrukturą a nowoczesnym kodem. Badamy, w jaki sposób Pulumi może bezpośrednio odczytywać istniejące pliki stanu Terraform. Poznasz potężny wzorzec współistnienia, który pozwala na przyrostowe wdrażanie Pulumi bez konieczności przepisywania całego stosu.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 9 z 10. Nie musisz wyrzucać lat istniejącego kodu, żeby już dziś zacząć korzystać z nowego narzędzia do infrastruktury. Przerażający, masowy rewrite systemu to ogromne ryzyko i na szczęście jest całkowicie opcjonalny. Strategia, która to umożliwia, nazywa się Peaceful Coexistence: Reading Terraform State. Powszechnym mitem jest to, że przejście na Pulumi oznacza konieczność zmigrowania całej istniejącej infrastruktury za jednym zamachem. To nieprawda. Pulumi potrafi natywnie odczytywać i tworzyć zależności od zasobów, którymi aktywnie zarządza Terraform. Możesz adoptować nowe narzędzia stopniowo, ramię w ramię z twoimi obecnymi pipeline'ami do deploymentu. Weźmy pod uwagę typowe środowisko enterprise. Twoja firma ma główne AWS Virtual Private Cloud, zarządzane przez centralny zespół sieciowy przy użyciu Terraform. Jesteś developerem budującym nową aplikację i chcesz użyć Pulumi, żeby zrobić deploy tasków Elastic Container Service. Twoje kontenery muszą działać dokładnie w tym VPC. Nie chcesz przepisywać kodu VPC do Pulumi i na pewno nie chcesz przejmować zarządzania całą tą siecią. Żeby to ogarnąć, używasz providera Pulumi Terraform. Ten provider zawiera specjalny komponent zaprojektowany do odczytywania plików state, nazywany remote state reference. Ten proces opiera się na tym, jak Terraform przechowuje swoje dane z wykonania. Po pierwsze, kod Terraform zarządzający siecią musi jawnie wystawić dane, których potrzebuje twoja nowa aplikacja. Robi to przy użyciu standardowych bloków output w Terraform. Zespół sieciowy konfiguruje swój kod tak, żeby zwracał w outputach identyfikator VPC i listę identyfikatorów prywatnych subnetów. Kiedy Terraform robi apply swojej konfiguracji, te outputy są zapisywane w pliku Terraform state, który zazwyczaj jest przechowywany zdalnie w backendzie, takim jak bucket AWS S3 albo Terraform Cloud. Następnie przechodzisz do swojego programu w Pulumi. Piszesz kod, żeby utworzyć instancję remote state reference. Przekazujesz do tego obiektu dokładnie te same szczegóły konfiguracji backendu, których Terraform używa do znalezienia swojego pliku state. Obejmuje to typ backendu, lokalizację storage'u, region i konkretny klucz pliku state. Kiedy odpalasz swój deployment w Pulumi, silnik łączy się z tym zdalnym backendem, otwiera plik Terraform state i parsuje dostępne outputy. I tu jest kluczowa sprawa. Pulumi traktuje Terraform state jako ściśle read-only. Nigdy nie modyfikuje pliku Terraform state i nie przejmuje własności nad zasobami sieciowymi. Po prostu odpytuje o obecne, znane wartości infrastruktury. Kiedy Pulumi pobierze identyfikatory VPC i subnetów ze state'u, traktujesz te wartości jak każdą inną zmienną w swoim kodzie. Przekazujesz je bezpośrednio do logiki deploymentu dla twojego nowego klastra kontenerów. Pulumi płynnie provisionuje twoje nowe kontenery w istniejącej sieci. Taka architektura zapewnia całkowite rozdzielenie odpowiedzialności. Centralny zespół nadal zarządza cyklem życia sieci przy użyciu Terraform. Jeśli zaktualizują route table albo dodadzą tag, używają swojego standardowego workflow. Jeśli zmodyfikują jakiś output, na przykład tworząc nowy subnet, Pulumi automatycznie odczyta zaktualizowany plik state podczas swojego kolejnego update'u i odpowiednio dostosuje deployment twoich kontenerów. Użycie remote state references tworzy czystą, jednokierunkową granicę zależności, pozwalając ci pewnie budować nowe systemy z nowoczesnymi możliwościami, jednocześnie polegając na stabilnym fundamencie zarządzanym przez legacy code. To wszystko w tym odcinku. Dzięki za wysłuchanie i koduj dalej!
10

Wielka migracja: Konwersja HCL na Pulumi

3m 59s

Zrób ostatni krok, tłumacząc Terraform HCL na w pełni funkcjonalny kod programistyczny. Analizujemy narzędzie `pulumi convert` i omawiamy, kiedy i dlaczego warto konwertować starsze konfiguracje. Dowiesz się, jak prawdziwe języki odblokowują zaawansowane testy jednostkowe dla infrastruktury.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Pulumi: Infrastructure as Code, odcinek 10 z 10. Testowanie złożonej logiki infrastruktury bywa niezwykle trudne. Piszesz tysiące linii konfiguracji, ale weryfikacja, czy konkretna kombinacja reguł firewalla faktycznie działa zgodnie z oczekiwaniami przed deployem, często przypomina zgadywankę. Wielka Migracja: Konwersja HCL do Pulumi to sposób, w jaki możesz to naprawić. Przejście z Terraform do Pulumi nie polega na prostym, składniowym znajdź i zamień. Nie chodzi o zamianę nawiasów klamrowych na okrągłe. Chodzi o przekształcenie statycznej konfiguracji w program wykonywalny, dający ci natychmiastowy dostęp do natywnych pętli, funkcji i standardowych frameworków testowych. Pomyśl o bardzo złożonej, powtarzalnej konfiguracji security group w Terraformie. Prawdopodobnie masz dziesiątki nakładających się na siebie zakresów portów, specyficzne allowlisty IP i rozbudowane definicje bloków. W HCL zarządzanie tym wymaga sztywnych struktur, a walidacja logiki wymaga odpalenia planu na live state chmury. Przejście zaczyna się od komendy pulumi convert. Wchodzisz do katalogu z istniejącymi plikami Terraform i odpalasz tę komendę, określając język docelowy, taki jak TypeScript czy Python. Narzędzie parsuje twój kod źródłowy HCL, odczytuje zmienne, główne zasoby i outputy, a następnie generuje odpowiedni program w Pulumi. Tłumaczy deklaratywną intencję HCL na imperatywną strukturę wybranego języka programowania. Po wygenerowaniu tego kodu, strategiczne korzyści płynące z migracji stają się jasne. Możesz teraz zrefaktorować tę ogromną listę reguł security group do czystej tablicy obiektów danych lub zaciągnąć je z zewnętrznego pliku konfiguracyjnego. Możesz iterować po tej tablicy, aby dynamicznie generować reguły firewalla za pomocą standardowych pętli w TypeScripcie lub Pythonie. Oto kluczowa kwestia. Ponieważ twoja infrastruktura jest teraz napisana w języku ogólnego przeznaczenia, możesz ją testować dokładnie tak samo, jak kod aplikacji. Możesz napisać unit test używając standardowych frameworków, takich jak Jest czy PyTest. Tworzysz test case, który mockuje runtime Pulumi i sprawdza, czy twoja funkcja budująca security group nigdy przypadkowo nie wystawia portu dwadzieścia dwa na cały internet. Odpalasz te testy w milisekundy, całkowicie offline, wyłapując błędy logiczne, zanim faza planowania infrastruktury w ogóle się zacznie. Ta zmiana odblokowuje głęboką integrację z językiem. Twój kod infrastruktury może współdzielić standardowe biblioteki, logikę walidacji i definicje typów bezpośrednio z kodem aplikacji. Zyskujesz dostęp do dojrzałych ekosystemów menedżerów pakietów, takich jak NPM czy pip, co pozwala ci paczkować i dystrybuować wzorce infrastruktury tak łatwo, jak każdą inną bibliotekę. Komenda convert odwala czarną robotę tłumacząc twój obecny state, ale prawdziwa migracja następuje, gdy zmieniasz mindset z pisania statycznych plików na inżynierię testowalnych systemów. Największą zaletą konwersji kodu jest przejście od prostej konfiguracji infrastruktury do jej rzeczywistego programowania. Gorąco zachęcam cię do przeczytania oficjalnej dokumentacji Pulumi, wzięcia małego modułu Terraform i samodzielnego odpalenia konwersji, żeby zobaczyć output. Jeśli masz pomysły na techniczne tematy, które powinniśmy poruszyć w naszej kolejnej serii, wejdź na devstories dot eu i daj nam znać. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!