Jeśli pracujesz w branży technologicznej, z pewnością widziałeś już wiele postów w mediach społecznościowych na temat ChatGPT. Dużo się o nim mówi. Jak każde nowe i błyszczące narzędzie, które trafia na rynek, ChatGPT wzbudza spore zainteresowanie.
Wielu programistów już teraz używa go do generowania różnego rodzaju kodu – od prostych funkcji w wybranym języku po pełne strony internetowe czy aplikacje. Pojawiają się więc pytania:
- czy ChatGPT naprawdę jest wart tego całego szumu?
- do czego można go wykorzystać?
- jak można go używać w pracy?
- czy ChatGPT jest tylko dla programistów?
- jak można używać ChatGPT w DevOps, administracji systemami lub inżynierii platform?
Jeśli pracujesz w DevOps lub innym obszarze niezwiązanym bezpośrednio z tworzeniem oprogramowania, najprawdopodobniej nie piszesz kodu produktu, ale wspierasz tych, którzy to robią – ułatwiając im pracę i automatyzując cykl życia produktu tak bardzo, jak to możliwe. Oznacza to pracę nad pipeline’ami wdrożeniowymi, ciągłą integracją (CI) i infrastrukturą jako kodem (IaC), służącą do przygotowywania różnych zasobów, takich jak klastry EKS, Amazon EC2, monitorowanie oprogramowania produkcyjnego itd.
W dzisiejszym wpisie skupimy się na używaniu ChatGPT w jednym z typowych zadań DevOps – infrastrukturze jako kodzie (IaC). Przetestujemy wiedzę ChatGPT na temat infrastruktur chmurowych i sprawdzimy, jak dokładne są jego odpowiedzi.
Zanim jednak przejdziemy do praktyki, poznajmy odpowiedź na pytanie – czym właściwie jest ChatGPT?
Czym jest ChatGPT?
ChatGPT to wytrenowany model sztucznej inteligencji, z którym można rozmawiać w sposób konwersacyjny. Mówiąc prosto – zadajesz pytanie, a ChatGPT odpowiada. Jeśli nie miałeś jeszcze okazji go wypróbować, dla jasności przyjmijmy przykład: chcesz wygenerować funkcję w języku Go, która oblicza ciąg Fibonacciego – poniżej znajduje się odpowiedź, którą otrzymałem od ChatGPT (wraz z wyjaśnieniem i kodem):
Oto przykład funkcji w języku Go, która generuje ciąg Fibonacciego do zadanej liczby elementów:
package main
import "fmt"
func fibonacci(n int) []int {
fibSeq := make([]int, n)
fibSeq[0] = 0
fibSeq[1] = 1
for i := 2; i < n; i++ {
fibSeq[i] = fibSeq[i-1] + fibSeq[i-2]
}
return fibSeq
}
func main() {
n := 10
fmt.Println(fibonacci(n))
}
W tym przykładzie funkcja Fibonacci przyjmuje argument całkowity n, który określa liczbę elementów w oczekiwanym ciągu Fibonacciego. Funkcja zwraca slice (tablicę dynamiczną) liczb całkowitych reprezentujących ciąg Fibonacciego.
Funkcja najpierw tworzy slice fibSeq o długości n i ustawia pierwsze dwa elementy ciągu na 0 i 1. Pętla for następnie iteracyjnie oblicza i zapisuje kolejne elementy ciągu, dodając do siebie dwa poprzednie elementy.
Na końcu funkcja zwraca cały ciąg Fibonacciego jako slice liczb całkowitych.
Scenariusze
- Generowanie szablonu IaC (CloudFormation i Terraform).
- Konwersja kodu Terraform do innego narzędzia IaC (z CloudFormation do Terraform, z Terraform do Terragrunt, z Terraform do Pulumi).
- Konwersja szablonu IaC do innego dostawcy usług chmurowych (z AWS do Azure).
Wymagania wstępne
- Konfiguracja ChatGPT – jeśli nie masz jeszcze konta osobistego, a chciałbyś je założyć, kliknij tutaj.
- Edytor kodu – potrzebujemy edytora kodu, aby przetestować wygenerowane szablony. Polecam Visual Studio Code, ponieważ posiada rozszerzenia dla większości dostawców i narzędzi.
- Terminal – potrzebny do uruchamiania poleceń dla każdego z narzędzi.
- CLI – AWS CLI, Azure CLI, Pulumi CLI itd.
jeśli widzisz okno podobne do tego poniżej, jesteś gotowy do pracy z ChatGPT

Jak widać na powyższym obrazku, ChatGPT już podpowiada przykłady, możliwości i ograniczenia. Pasek tekstowy na dole służy do wpisywania pytań – po ich wysłaniu, reszta „magii” dzieje się niemal natychmiast.
Generowanie szablonów IaC
Aby lepiej zrozumieć, jak działa ChatGPT, przetestujmy pierwszy scenariusz.
Szablon EC2 w CloudFormation
Nigdy wcześniej nie pracowałem z CloudFormation – dla mnie to była wartość dodana. Zamiast spędzać czas na pełnej nauce CloudFormation, mogę po prostu wygenerować kod dla tych fragmentów, których potrzebuję. Zadałem więc ChatGPT poniższe pytanie:
wygeneruj szablon CloudFormation tworzący instancję EC2
Po kilku sekundach ChatGPT wygenerował odpowiedź widoczną na poniższym obrazku.

Jeśli znasz YAML i masz wiedzę na temat chmury oraz oferowanych przez nią usług, łatwo zauważysz, że mimo iż to wygląda imponująco, nie jest to coś, co po prostu skopiujesz do edytora kodu i wdrożysz na środowisku produkcyjnym.
Nie mam doświadczenia z CloudFormation, ale widzę, że ten kod tworzy grupę zabezpieczeń i umożliwia połączenia SSH z dowolnego adresu – co raczej nie jest zalecane w środowisku produkcyjnym. Jeśli chcemy hostować aplikację webową lub użyć tej instancji jako serwera www, musimy dodać reguły wejściowe (ingress) dla HTTP/HTTPS.
Odpowiedź, jaką otrzymasz od ChatGPT, w dużej mierze zależy od tego, jak dobrze wyjaśnisz swoje potrzeby. Spróbujmy teraz sformułować coś bardziej szczegółowego i od razu to przetestujmy. Ponieważ Terraform działa w modelu multi-cloud i daje więcej możliwości, przechodzę do Terraform.
Szablon EC2 w Terraform
Dotąd testowaliśmy możliwości ChatGPT w generowaniu kodu infrastruktury – i jak widać, to działa. Wystarczy dobrze opisać przypadek użycia, a ChatGPT wygeneruje odpowiedni szablon Terraform. Oto polecenie, jakie wpisałem do ChatGPT ( pochylony tekst):
Write a Terraform template to create the following:
- VPC z blokiem CIDR 10.2.0.0/16 w regionie eu-central-1 i nazwą
test_vpc
. - Podsieć z blokiem CIDR 10.2.0.0/24, przypisana do VPC, bez publicznych adresów IP, z nazwą
test_subnet
. - Grupę zabezpieczeń pozwalającą na ruch przychodzący na porty 22, 80 i 443 z bloku CIDR 10.2.0.0/16, z
nazwą
test_security_group
. - Instancję EC2 typu
t2.micro
, zimageId = ami-06c39ed6b42908a36
, przypisaną do wskazanej podsieci i używającą wskazanej grupy zabezpieczeń, bez klucza SSH.
Zgodnie z oczekiwaniami, ChatGPT wygenerował szablon Terraform i krótko wyjaśnił kod oraz to, co należy zmodyfikować przed jego użyciem. Kod został wygenerowany poniżej, a objaśnienie znajduje się w pochylonym tekście pod nim.
provider "aws" {
region = "eu-central-1"
}
resource "aws_vpc" "test_vpc" {
cidr_block = "10.2.0.0/16"
name = "test_vpc"
}
resource "aws_subnet" "test_subnet" {
cidr_block = "10.2.0.0/24"
vpc_id = aws_vpc.test_vpc.id
map_public_ip_on_launch = false
name = "test_subnet"
}
resource "aws_security_group" "test_security_group" {
name = "test_security_group"
description = "Allow SSH and HTTP/HTTPS traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.2.0.0/16"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["10.2.0.0/16"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.2.0.0/16"]
}
}
resource "aws_instance" "example_instance" {
ami = "ami-06c39ed6b42908a36"
instance_type = "t2.micro"
subnet_id = aws_subnet.test_subnet.id
vpc_security_group_ids = [aws_security_group.test_security_group.id]
}
- W tym przykładzie provider AWS został skonfigurowany do użycia regionu eu-central-1.
- Zasób aws_vpc tworzy VPC z blokiem CIDR 10.2.0.0/16 i nazwą test_vpc.
- Zasób aws_subnet tworzy podsieć z blokiem CIDR 10.2.0.0/24, przypisaną do VPC, bez włączonych publicznych adresów IP i z nazwą test_subnet.
- Zasób aws_security_group tworzy grupę zabezpieczeń, która umożliwia ruch przychodzący na porty 22, 80 i 443 z bloku CIDR 10.2.0.0/16, z nazwą test_security_group.
- Na końcu zasób aws_instance tworzy instancję EC2 typu t2.micro, z podanym identyfikatorem AMI, przypisaną do wskazanej podsieci, używającą grupy zabezpieczeń i bez klucza SSH.
Jeśli porównamy powyższy szablon Terraform z wcześniej wygenerowanym szablonem CloudFormation, zobaczymy, że dzieje się tu o wiele więcej. I jest to jak najbardziej oczekiwane – tym razem nie poprosiliśmy tylko o wygenerowanie instancji EC2, ale byliśmy też bardziej szczegółowi co do komponentów, które chcemy stworzyć oraz preferowanej konfiguracji (np. nazwy, adresy CIDR/IP itd.).
Teraz uruchomimy ten kod i zobaczymy, czy zadziała bez konieczności wprowadzania ręcznych zmian. Zakładam, że masz już skonfigurowane AWS CLI.
Utworzyłem katalog o nazwie chatgpt-for-iac i plik o nazwie main.tf. Otwórz swój edytor kodu i wklej kod wygenerowany przez ChatGPT do pliku main.tf.
Mamy już wszystko, co potrzebne, by sprawdzić, czy kod działa zgodnie z oczekiwaniami. Pierwszym krokiem będzie
zainicjowanie backendu Terraform oraz pobranie wtyczek providera, a następnie uruchomienie komendy terraform plan
, by
zobaczyć, co kod zamierza zrobić.
> terraform init
> terraform plan
Uruchomiłem komendę plan
i – jak można się było spodziewać – wystąpił błąd. Prawdę mówiąc, spodziewałem się tego.
Istnieje wiele powodów, dla których tak się stało. Nie mam pewności, jaka wersja Terraform została użyta do
wygenerowania kodu, ponieważ w wygenerowanym pliku nie określono wersji, a także nie wiem, czy odpowiada ona wersji
zainstalowanej na moim komputerze.
W moim przypadku błąd wyglądał następująco:

Jeśli znasz Terraform, zapewne zauważyłeś, że argument name nie jest w ogóle potrzebny, ponieważ nazwa zasobu została już określona wcześniej – nad nawiasem klamrowym otwierającym blok. Ten sam problem występuje również w sekcji dotyczącej zasobu VPC.
Możemy naprawić ten błąd, usuwając atrybut name
z obu bloków – zarówno vpc
, jak i subnet
. Ostateczna wersja kodu
powinna wyglądać tak jak poniżej:
resource "aws_vpc" "test_vpc" {
cidr_block = "10.2.0.0/16"
}
resource "aws_subnet" "test_subnet" {
cidr_block = "10.2.0.0/24"
vpc_id = aws_vpc.test_vpc.id
map_public_ip_on_launch = false
}
Teraz uruchommy ponownie komendę plan
i sprawdźmy, czy wszystko działa poprawnie. W moim przypadku wygląda na to, że
wszystko jest w porządku – komenda terraform plan
zakończyła się sukcesem i mogę zobaczyć wszystkie zasoby, które
zostaną utworzone przez nasz kod.
To całkowicie normalne, że plan
przechodzi bez błędów, ale apply
może się nie powieść – więc nie cieszmy się
przedwcześnie, dopóki nie uruchomimy apply
. Oto polecenie:
> terraform apply
Nie powiedziałbym, że się tego spodziewałem – ale niestety, apply
się nie powiódł i poniżej możesz zobaczyć błąd:

Po przeanalizowaniu kodu zauważyłem, gdzie leży problem – w bloku zasobu security group
nie został podany vpc_id
.
Aby to naprawić, dodaj poniższą linię pod opisem grupy zabezpieczeń:
vpc_id = aws_vpc.test_vpc.id
Uruchom ponownie terraform plan
. Komenda ta pokaże, co Terraform zamierza zmienić. Powinno to być niemal identyczne z
poprzednim planem, jednak ponieważ już uruchomiliśmy apply
, niektóre zasoby zostały już utworzone. Jeśli wszystko
pójdzie dobrze podczas planu, możesz ponownie uruchomić komendę apply
.
Tym razem mój terraform apply
zakończył się sukcesem i nasza infrastruktura powinna być gotowa do działania. Możesz to
zweryfikować, sprawdzając konsolę AWS.
Jak widzisz, wystarczyło usunąć dwie linie i dodać jedną linię. Ta drobna korekta mogła zostać łatwo uniknięta, a odpowiedź ChatGPT działałaby bez problemu, gdybyśmy dokładniej wyjaśnili nasze potrzeby.
Teraz spróbujmy innego scenariusza.
Konwersja kodu Terraform na inny tool IaC
Wyobraź sobie, że wcześniej napisałeś kod infrastruktury w Terraform, a potem odkryłeś, że lepszy jest Terragrunt. Teraz musisz przepisać swój kod. Przepisanie jednego pliku z 50 liniami może być proste, ale co jeśli masz ponad 40 plików i miliony linii?
Konwersja kodu Terraform na Terragrunt za pomocą ChatGPT
Próbowałem przekonwertować zawartość naszego pliku main.tf na Terragrunt, jak poniżej:

Powyższy obrazek jest przycięty — aby spróbować samodzielnie, wystarczy wpisać pierwsze zdanie, zostawić spację, a następnie wkleić zawartość pliku main.tf, który zawiera ten sam, wcześniej edytowany kod.
Poniżej znajduje się przycięty obraz odpowiedzi ChatGPT:

To zdecydowanie nie zadziała, gdy spróbujemy, i to z wielu powodów, ale najbardziej oczywistym jest to, że nasze bloki zasobów Terraform zostały przekształcone w moduły Terragrunt, mimo że nie chcieliśmy tworzyć modułów. Żeby to poprawić, trzeba znać Terragrunt, a szczerze mówiąc w tym przypadku lepiej jest napisać to od nowa lub opisać istniejącą infrastrukturę Terraform, a ChatGPT wygeneruje kod Terragrunt od podstaw.
Konwersja kodu Terraform na Pulumi za pomocą ChatGPT
Co jeśli mamy już kod Terraform i chcemy wygenerować odpowiadający mu kod Pulumi?
Powtórzyłem ten sam krok, co wcześniej, z tą różnicą, że tym razem zamiast prosić ChatGPT o konwersję szablonu Terraform na Terragrunt, wskazałem Pulumi. ChatGPT odpowiedział poniższym kodem:
import * as aws from "@pulumi/aws";
const region = "eu-central-1";
const testVpc = new aws.ec2.Vpc("test_vpc", {
cidrBlock: "10.2.0.0/16",
});
const testSubnet = new aws.ec2.Subnet("test_subnet", {
cidrBlock: "10.2.0.0/24",
vpcId: testVpc.id,
mapPublicIpOnLaunch: false,
});
const testSecurityGroup = new aws.ec2.SecurityGroup("test_security_group", {
name: "test_security_group",
description: "Allow SSH and HTTP/HTTPS traffic",
vpcId: testVpc.id,
ingress: [
{
fromPort: 22,
toPort: 22,
protocol: "tcp",
cidrBlocks: ["10.2.0.0/16"],
},
{
fromPort: 80,
toPort: 80,
protocol: "tcp",
cidrBlocks: ["10.2.0.0/16"],
},
{
fromPort: 443,
toPort: 443,
protocol: "tcp",
cidrBlocks: ["10.2.0.0/16"],
},
],
});
const exampleInstance = new aws.ec2.Instance("example_instance", {
ami: "ami-06c39ed6b42908a36",
instanceType: "t2.micro",
subnetId: testSubnet.id,
vpcSecurityGroupIds: [testSecurityGroup.id],
});
Jeśli pracowałeś wcześniej z Pulumi do provisioningu usług w chmurze, powinieneś wiedzieć, że w Pulumi IaC jest pisane za pomocą języków programowania (Typescript, Python, Go, C#, Java), a nawet YAML. Jeśli przyjrzysz się dokładnie, zauważysz, że domyślny szablon wygenerowany przez ChatGPT używa Typescripta. Oczywiście, możemy to zmienić, prosząc o wygenerowanie wersji w Go.
Przetestujmy ten kod. W przeciwieństwie do Terraform, który wymaga stworzenia jednego pliku, aby powtórzyć to samo w
Pulumi, potrzebne jest kilka dodatkowych kroków. Ponieważ to nie jest poradnik Pulumi, pominę wstępną konfigurację i
pomogę nam przetestować powyższy kod. Kiedy uruchamiam odpowiednik polecenia terraform plan
(czyli pulumi up
), widzę
poniższe:

Wybrałem „yes”, aby sprawdzić, czy kod działa poprawnie i w tym przypadku jestem naprawdę pod wrażeniem. Jeśli testujesz to tak jak ja, pamiętaj, aby zniszczyć zasoby utworzone wcześniej przez Terraform. Ponieważ kod jest taki sam, ale używamy innego narzędzia, nadal mogą pojawić się błędy, ponieważ nazwy zasobów są takie same, a gdy Pulumi próbuje je utworzyć, otrzyma informację, że zasoby o takich nazwach już istnieją.

Wszystkie zasoby zostały utworzone bez błędów i nie wymagały żadnych ręcznych zmian.
Spróbujmy ostatniego scenariusza.
Konwersja szablonu IaC na innego dostawcę
Do tej pory pracowaliśmy z różnymi narzędziami IaC, ale zawsze w ramach dostawcy chmury AWS. A co, jeśli chcemy przepisać nasz kod tak, aby można go było użyć do provisioningu zasobów na Azure lub GCP, nadal korzystając z Terraform? Użyję tego samego kodu Terraform, którego używaliśmy wcześniej. Zadałem ChatGPT następujące pytanie:

Jedyne co różni powyższy przypadek od poprzedniego, to pierwsza, najwyższa linia. Poniżej znajduje się ten sam kod Terraform. Odpowiedź ChatGPT to poniższy kod:
provider "azurerm" {
version = "2.32.0"
features {}
}
resource "azurerm_resource_group" "test_rg" {
name = "test_rg"
location = "West Europe"
}
resource "azurerm_virtual_network" "test_vnet" {
name = "test_vnet"
address_space = ["10.2.0.0/16"]
location = azurerm_resource_group.test_rg.location
resource_group_name = azurerm_resource_group.test_rg.name
}
resource "azurerm_subnet" "test_subnet" {
name = "test_subnet"
resource_group_name = azurerm_resource_group.test_rg.name
virtual_network_name = azurerm_virtual_network.test_vnet.name
address_prefix = "10.2.0.0/24"
}
resource "azurerm_network_security_group" "test_nsg" {
name = "test_nsg"
location = azurerm_resource_group.test_rg.location
resource_group_name = azurerm_resource_group.test_rg.name
security_rule {
name = "allow_ssh"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = ""
destination_port_range = "22"
source_address_prefix = "10.2.0.0/16"
destination_address_prefix = ""
}
security_rule {
name = "allow_http"
priority = 101
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = ""
destination_port_range = "80"
source_address_prefix = "10.2.0.0/16"
destination_address_prefix = ""
}
security_rule {
name = "allow_https"
priority = 102
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = ""
destination_port_range = "443"
source_address_prefix = "10.2.0.0/16"
destination_address_prefix = ""
}
}
resource "azurerm_network_interface" "test_nic" {
name = "test_nic"
location = azurerm_resource_group.test_rg.location
resource_group_name = azurerm_resource_group.test_rg.name
network_security_group_id = azurerm_network_security_group.test_nsg.id
subnet_id = azurerm_subnet.test_subnet.id
Nie będę tego testować, ale patrząc na powyższy kod, muszę powiedzieć, że jest całkiem imponujący. Widzę trzy reguły bezpieczeństwa, które odpowiadają tym z Terraform, region został zmieniony na West Europe, czyli nie Niemcy jak w regionie AWS (eu-central-1), choć istnieje też region Azure w Niemczech. Próbowano też dodać prefiks test do nazw usług, mimo że mają one różne nazwy w porównaniu z AWS, ale ChatGPT wiedział, że słowo test powinno być użyte jako prefiks.
Czy powinieneś używać ChatGPT do swojego projektu IaC?
Pracowałem tylko na kilku przykładach i choć spędziłem trochę czasu na pisaniu prostych tekstów wyjaśniających moje potrzeby ChatGPT oraz ręcznej edycji wygenerowanego szablonu Terraform, to i tak zaoszczędziłem znacznie więcej czasu niż gdybym miał pisać wszystko sam.
Myślę, że możesz kopiować z poprzednich projektów i ponownie używać fragmenty kodu, które odpowiadają Twoim potrzebom, ale różne scenariusze pokazują, że istnieją o wiele bardziej skomplikowane przypadki użycia, w których ChatGPT może Ci pomóc. W moim przypadku nigdy wcześniej nie pracowałem z Pulumi, a mimo to udało mi się uruchomić provisioning zasobów za pomocą Pulumi w mniej niż 5 minut.