Terraform – Infrastructure as Code

TL;DR: Terraform to narzędzie Infrastructure as Code (IaC) od HashiCorp, które pozwala zarządzać infrastrukturą za pomocą kodu. Zamiast klikać w AWS Console, piszesz deklaratywny kod który opisuje infrastrukturę i Terraform ją tworzy. W tym artykule nauczysz się podstaw Terraform, stworzysz pierwszą infrastrukturę i zrozumiesz dlaczego IaC to przyszłość ops.

Dlaczego Infrastructure as Code to przyszłość

Wyobraź sobie sytuację: musisz utworzyć identyczne środowisko testowe, staging i produkcyjne. Tradycyjnie oznacza to godziny klikania w panelach administracyjnych, ręczne tworzenie instancji EC2, konfigurowanie security groups, load balancerów… A co jeśli pomylisz się w jednym kroku? Co jeśli za miesiąc musisz powtórzyć ten proces?

Infrastructure as Code (IaC) rozwiązuje te problemy poprzez opisanie całej infrastruktury w plikach tekstowych, które można wersjonować, testować i wielokrotnie używać. Terraform od HashiCorp to obecnie jedno z najlepszych narzędzi IaC na rynku.

Co się nauczysz:

  • Czym jest Infrastructure as Code i dlaczego warto z tego korzystać
  • Jak zainstalować i skonfigurować Terraform
  • Jak napisać pierwszy plik konfiguracyjny Terraform
  • Jak utworzyć infrastrukturę w AWS za pomocą Terraform
  • Podstawowe komendy Terraform i workflow
  • Najlepsze praktyki przy pracy z Terraform

Wymagania wstępne:

  • Podstawowa znajomość cloud computing (AWS, Azure lub GCP)
  • Umiejętność pracy z linią komend
  • Konto AWS (free tier wystarczy)
  • Podstawowa znajomość JSON/YAML (mile widziana)

Czym jest Terraform i Infrastructure as Code

Infrastructure as Code (IaC) – podejście do zarządzania infrastrukturą, gdzie konfiguracja systemów jest opisana w plikach kodu źródłowego zamiast ręcznych procesów konfiguracyjnych.

Terraform to narzędzie open-source stworzone przez HashiCorp w 2014 roku, które implementuje koncepcję Infrastructure as Code. Najważniejsze cechy Terraform:

**Deklaratywność:** Opisujesz JAK ma wyglądać Twoja infrastruktura, a nie KROKI jej tworzenia. Terraform sam ustala co i w jakiej kolejności utworzyć.

**Multi-cloud:** Działa z AWS, Azure, Google Cloud, ale też z setkami innych providerów – od DNSów po monitoring.

**State management:** Terraform pamięta aktualny stan infrastruktury i potrafi wykryć różnice między kodem a rzeczywistością.

Terraform to jak przepis na ciasto. Zamiast pamiętać „najpierw podgrzej piekarnik, potem wymieszaj jajka…”, piszesz składniki i efekt końcowy. Terraform (jak dobry kucharz) sam ustala kolejność kroków.

Instalacja i pierwsze kroki z Terraform

### Instalacja Terraform

Terraform to pojedynczy plik wykonywalny. Na macOS najprościej przez Homebrew:

# macOS
brew install terraform

# Linux (Ubuntu/Debian)
wget https://releases.hashicorp.com/terraform/0.11.1/terraform_0.11.1_linux_amd64.zip
unzip terraform_0.11.1_linux_amd64.zip
sudo mv terraform /usr/local/bin/

Sprawdź instalację:

terraform version
# Terraform v0.11.1
W 2017 roku aktualna wersja Terraform to 0.11.x. Wersja 0.12 z wieloma usprawnieniami pojawi się w 2019 roku.

### Konfiguracja AWS

Terraform potrzebuje uprawnień do tworzenia zasobów w AWS. Utwórz użytkownika IAM z odpowiednimi uprawnieniami:

# Ustaw credentials przez AWS CLI
aws configure

# Lub przez zmienne środowiskowe
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-west-2"

Pierwszy projekt Terraform – EC2 Instance

Stwórzmy pierwszy projekt Terraform, który utworzy prostą instancję EC2 w AWS.

### Struktura projektu

mkdir terraform-first-project
cd terraform-first-project
touch main.tf

### Plik main.tf

# Provider configuration
provider "aws" {
  region = "us-west-2"
}

# Data source to get latest Amazon Linux AMI
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
  }
}

# Security group for our instance
resource "aws_security_group" "web_sg" {
  name_prefix = "terraform-example-"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags {
    Name = "terraform-example-sg"
  }
}

# EC2 Instance
resource "aws_instance" "web_server" {
  ami           = "${data.aws_ami.amazon_linux.id}"
  instance_type = "t2.micro"
  
  vpc_security_group_ids = ["${aws_security_group.web_sg.id}"]
  
  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "

Hello from Terraform!

" > /var/www/html/index.html EOF tags { Name = "terraform-example-server" } } # Output the public IP output "public_ip" { value = "${aws_instance.web_server.public_ip}" }
Pro tip: Składnia ${data.aws_ami.amazon_linux.id} to interpolacja – sposób na odwoływanie się do wartości innych zasobów w Terraform.

### Podstawowe komendy Terraform

# 1. Inicjalizacja - pobiera potrzebne providery
terraform init

# 2. Plan - pokazuje co będzie utworzone/zmienione
terraform plan

# 3. Apply - wykonuje zmiany
terraform apply

# 4. Sprawdzenie stanu
terraform show

# 5. Usunięcie infrastruktury
terraform destroy

Terraform workflow krok po kroku

### 1. Terraform Init

$ terraform init

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (1.6.0)...

Terraform has been successfully initialized!

Ta komenda:
– Pobiera pluginy providerów (w naszym przypadku AWS)
– Tworzy ukryty folder .terraform
– Przygotowuje backend do przechowywania state

### 2. Terraform Plan

$ terraform plan

Refreshing Terraform state in-memory prior to plan...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

+ aws_instance.web_server
    ami:                         "ami-0def3275"
    instance_type:               "t2.micro"
    vpc_security_group_ids.#:    "1"
    
+ aws_security_group.web_sg
    name_prefix:                 "terraform-example-"
    ingress.#:                   "2"

Plan: 2 to add, 0 to change, 0 to destroy.
Plan nie wykonuje zmian – tylko pokazuje co zostanie zrobione. To bezpieczny sposób na sprawdzenie efektów przed wykonaniem.

### 3. Terraform Apply

$ terraform apply

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.web_sg: Creating...
aws_security_group.web_sg: Creation complete after 2s (ID: sg-12345678)
aws_instance.web_server: Creating...
aws_instance.web_server: Still creating... (10s elapsed)
aws_instance.web_server: Creation complete after 31s (ID: i-87654321)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

public_ip = 52.12.34.56

Po kilku minutach możesz otworzyć http://52.12.34.56 i zobaczyć stronę „Hello from Terraform!”

State management – serce Terraform

Terraform przechowuje informacje o utworzonej infrastrukturze w pliku terraform.tfstate. Ten plik zawiera:

– Jakie zasoby zostały utworzone
– Ich aktualne identyfikatory (ID)
– Powiązania między zasobami
– Metadane i właściwości

Uwaga: Plik state zawiera wrażliwe dane! Nigdy nie commituj go do repozytorium Git. Używaj remote state (S3, Terraform Cloud) w prawdziwych projektach.

Sprawdź zawartość state:

# Wyświetl stan w czytelnej formie
terraform show

# Lista zasobów w state
terraform state list

# Szczegóły konkretnego zasobu
terraform state show aws_instance.web_server

Organizacja kodu Terraform

W większych projektach warto podzielić kod na pliki:

terraform-project/
├── main.tf          # Główne zasoby
├── variables.tf     # Definicje zmiennych
├── outputs.tf       # Definicje outputów
├── provider.tf      # Konfiguracja providerów
└── terraform.tfvars # Wartości zmiennych

### Przykład z zmiennymi

**variables.tf:**

variable "region" {
  description = "AWS region"
  default     = "us-west-2"
}

variable "instance_type" {
  description = "EC2 instance type"
  default     = "t2.micro"
}

variable "server_name" {
  description = "Name tag for the server"
  type        = "string"
}

**terraform.tfvars:**

region = "us-east-1"
instance_type = "t2.small"
server_name = "production-web-server"

**main.tf (z użyciem zmiennych):**

provider "aws" {
  region = "${var.region}"
}

resource "aws_instance" "web_server" {
  ami           = "${data.aws_ami.amazon_linux.id}"
  instance_type = "${var.instance_type}"
  
  tags {
    Name = "${var.server_name}"
  }
}

Najlepsze praktyki Terraform

### 1. Używaj remote state

Dla zespołów krytyczne jest przechowywanie state w centralnym miejscu:

terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "prod/terraform.tfstate"
    region = "us-west-2"
  }
}

### 2. Organizuj zasoby w modules

modules/
├── vpc/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
├── web-server/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
└── database/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

### 3. Zawsze planuj przed apply

Pułapka: Nigdy nie uruchamiaj terraform apply bez wcześniejszego terraform plan. Możesz przypadkowo usunąć produkcyjną infrastrukturę!

### 4. Taguj wszystkie zasoby

resource "aws_instance" "web_server" {
  ami           = "${data.aws_ami.amazon_linux.id}"
  instance_type = "t2.micro"
  
  tags {
    Name        = "web-server"
    Environment = "production"
    Project     = "website"
    Owner       = "devops-team"
    ManagedBy   = "terraform"
  }
}

Rozwiązywanie problemów

### Typowe błędy początkujących

Błąd: Zapomnienie o terraform init po dodaniu nowego providera.
Rozwiązanie: Zawsze uruchom terraform init po zmianach w providerach.
Błąd: Modyfikacja infrastruktury ręcznie (przez AWS Console) po utworzeniu przez Terraform.
Rozwiązanie: Wszystkie zmiany rób przez Terraform. Użyj terraform refresh aby zsynchronizować state.

### Przydatne komendy debugowania

# Sprawdź składnię
terraform validate

# Sformatuj kod
terraform fmt

# Odśwież state bez zmian
terraform refresh

# Wyświetl graf zależności
terraform graph | dot -Tpng > graph.png
Czy Terraform zastąpi Ansible/Chef/Puppet?

Nie – to narzędzia do różnych zadań. Terraform tworzy infrastrukturę (serwery, sieci, bazy danych), podczas gdy Ansible/Chef/Puppet konfigurują aplikacje na już istniejących serwerach. Często używa się ich razem.

Jak long running jest Terraform apply?

Zależy od złożoności. Pojedyncza instancja EC2: 1-2 minuty. VPC z wieloma zasobami: 5-15 minut. Duże środowisko z RDS, ELB, Auto Scaling: 20-45 minut.

Co się stanie jeśli wykonam terraform destroy przez przypadek?

Terraform usunie WSZYSTKIE zasoby opisane w konfiguracji. Dlatego zawsze używaj remote state z versioning i nigdy nie uruchamiaj destroy bez plan. W enterprise środowiskach używa się policy as code (Sentinel) aby zablokować niebezpieczne operacje.

Czy mogę używać Terraform z istniejącą infrastrukturą?

Tak, przez terraform import możesz „zaimportować” istniejące zasoby do Terraform state. Następnie musisz napisać odpowiadającą im konfigurację. To proces manualny i czasochłonny, ale możliwy.

Jak współpracować z zespołem nad Terraform?

Używaj remote state (S3 + DynamoDB dla locking), trzymaj kod w Git, używaj Terraform workspace dla różnych środowisk (dev/staging/prod), implementuj CI/CD pipeline z terraform plan w pull requestach.

Jakie są koszty użycia Terraform?

Sam Terraform jest darmowy (open source). Płacisz tylko za utworzone zasoby w chmurze (EC2, RDS, etc.) według standardowych cenników providerów. HashiCorp oferuje płatne Terraform Cloud/Enterprise z dodatkowymi funkcjami dla enterprise.

Czy Terraform może zarządzać wieloma cloud providerami jednocześnie?

Tak! To jedna z głównych zalet Terraform. Możesz w jednej konfiguracji mieć AWS, Azure, Google Cloud, CloudFlare, DataDog i setki innych providerów. Terraform sam ustali kolejność tworzenia zasobów między providerami.

Przydatne zasoby:

🚀 Zadanie dla Ciebie

Stwórz kompletne środowisko web aplikacji:

  • VPC z publiczną i prywatną podsiecią
  • Application Load Balancer
  • 2 instancje EC2 w prywatnej podsieci z Nginx
  • RDS MySQL w prywatnej podsieci
  • NAT Gateway dla dostępu do internetu z prywatnych podsieci
  • Security Groups z odpowiednimi regułami

Użyj zmiennych dla konfiguracji i outputów dla ważnych wartości (ALB DNS, RDS endpoint). Pamiętaj o tagowaniu wszystkich zasobów!

Wynik opublikuj na GitHub i podziel się linkiem w komentarzach. Chętnie przejrzę Twój kod i dam feedback!

Terraform to potężne narzędzie które zmienia sposób myślenia o infrastrukturze. Od ręcznego klikania przechodzisz do kodu, który można testować, wersjonować i wielokrotnie używać. To początek prawdziwego DevOps!

Masz pytania dotyczące Terraform lub Infrastructure as Code? A może już używasz IaC w swoich projektach? Podziel się swoimi doświadczeniami w komentarzach!

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Przewijanie do góry