deployowanie aplikacji ai za pomoca terraform (windows)

⏱ ~20 minut czytania 📊 Poziom: Średniozaawansowany 📅 Styczeń 2026

Klikanie w AWS Console jest świetne na początek, ale gdy tworzysz aplikację AI z prawdziwego zdarzenia, potrzebujesz powtarzalności. Terraform to narzędzie Infrastructure as Code (IaC), które zamienia ręczne konfiguracje w kod — wersjonowany, recenzowany i wdrażany jednym poleceniem.

🎯 Czego się nauczysz:

  • Podstaw Terraform i HCL (HashiCorp Configuration Language)
  • Konfigurację providera AWS na Windowsie
  • Zarządzanie wieloma środowiskami przez Workspaces
  • Automatyzację deploymentu skryptami PowerShell
  • Izolację stanu (state) per środowisko
  • Dobre praktyki nazewnictwa i tagowania zasobów

TL;DR — Szybkie podsumowanie

Aspekt Manual (Console) Terraform
Powtarzalność ❌ Ręczna konfiguracja ✅ Kod = dokumentacja
Wersjonowanie ❌ Brak historii ✅ Git tracking
Środowiska ❌ Ręczna izolacja ✅ Workspaces (dev/test/prod)
Rollback ❌ Trudny terraform destroy
Czas deploymentu ~30 minut ~5 minut (po konfiguracji)

🤔 Dlaczego Terraform dla aplikacji AI?

Gdy budujesz cyfrowego bliźniaka (Digital Twin) — chatbota wykorzystującego modele Bedrock — infrastruktura składa się z wielu moving parts:

  • Lambda — backend Pythonowy obsługujący API
  • API Gateway — endpointy HTTP dla frontendu
  • S3 — bucket na frontend (static hosting) i pamięć konwersacji
  • CloudFront — CDN dla frontendu
  • IAM — uprawnienia do Bedrock i S3

Ręczne klikanie w konsoli przy trzech środowiskach (dev/test/prod) to prosta droga do błędów. Terraform pozwala zdefiniować to raz i deployować wielokrotnie.

🛠️ Przygotowanie środowiska Windows

Instalacja Terraform

Na Windows najwygodniej użyć winget lub pobrać binarkę:

PowerShell
# Instalacja przez winget (Windows 10/11)
winget install Hashicorp.Terraform

# Weryfikacja
terraform --version
# Terraform v1.10.0 on windows_amd64
Tip: Alternatywnie pobierz zip z developer.hashicorp.com, wypakuj do C:\tools\terraform i dodaj do PATH.

Struktura projektu

twin/ ├── backend/ # Kod Lambda (Python) ├── frontend/ # Next.js aplikacja ├── terraform/ # Konfiguracja IaC (tu pracujemy) │ ├── versions.tf │ ├── variables.tf │ ├── main.tf │ ├── outputs.tf │ └── terraform.tfvars └── scripts/ ├── deploy.ps1 # Główny skrypt deploymentu (Windows) └── destroy.ps1 # Czyszczenie zasobów

⚙️ Konfiguracja Terraform

1. Provider i wersje (versions.tf)

terraform {
  required_version = ">= 1.0"
  
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"  # Bedrock najlepiej działa tu
}

# Drugi provider dla certyfikatów (musi być w us-east-1)
provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

2. Zmienne (variables.tf)

Parametryzacja to klucz do wielu środowisk:

variable "project_name" {
  description = "Prefiks dla wszystkich zasobów"
  type        = string
  default     = "twin"
  
  validation {
    condition     = can(regex("^[a-z0-9-]+$", var.project_name))
    error_message = "Tylko małe litery, cyfry i myślniki."
  }
}

variable "environment" {
  description = "Środowisko: dev, test, prod"
  type        = string
  
  validation {
    condition     = contains(["dev", "test", "prod"], var.environment)
    error_message = "Dozwolone wartości: dev, test, prod."
  }
}

variable "bedrock_model_id" {
  description = "ID modelu AWS Bedrock"
  type        = string
  default     = "amazon.nova-micro-v1:0"  # Tani model dla dev
}

3. Główna konfiguracja (main.tf)

locals {
  name_prefix = "${var.project_name}-${var.environment}"
  
  common_tags = {
    Project     = var.project_name
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

# S3 dla pamięci konwersacji (prywatny)
resource "aws_s3_bucket" "memory" {
  bucket = "${local.name_prefix}-memory-${data.aws_caller_identity.current.account_id}"
  tags   = local.common_tags
}

# Lambda function
resource "aws_lambda_function" "api" {
  filename         = "${path.module}/../backend/lambda-deployment.zip"
  function_name    = "${local.name_prefix}-api"
  role             = aws_iam_role.lambda_role.arn
  handler          = "lambda_handler.handler"
  runtime          = "python3.12"
  timeout          = var.lambda_timeout
  
  environment {
    variables = {
      S3_BUCKET        = aws_s3_bucket.memory.id
      BEDROCK_MODEL_ID = var.bedrock_model_id
    }
  }
}

4. Wyjścia (outputs.tf)

output "api_gateway_url" {
  description = "URL API Gateway"
  value       = aws_apigatewayv2_api.main.api_endpoint
}

output "cloudfront_url" {
  description = "URL CloudFront"
  value       = "https://${aws_cloudfront_distribution.main.domain_name}"
}

🗂️ Workspaces — klucz do izolacji środowisk

Terraform Workspaces pozwalają utrzymać osobny stan (state) dla każdego środowiska bez duplikowania kodu.

🚀 Skrypt deploymentu dla Windows (PowerShell)

Ręczne wpisywanie komend jest podatne na błędy. Stwórzmy scripts/deploy.ps1:

param(
    [string]$Environment = "dev",   # dev | test | prod
    [string]$ProjectName = "twin"
)
$ErrorActionPreference = "Stop"

Write-Host "🚀 Deploying $ProjectName to $Environment..." -ForegroundColor Green

# 1. Budowanie pakietu Lambda
Set-Location (Split-Path $PSScriptRoot -Parent)
Write-Host "📦 Building Lambda package..." -ForegroundColor Yellow

Set-Location backend
uv run deploy.py  # Tworzy lambda-deployment.zip
Set-Location ..

# 2. Terraform - inicjalizacja i apply
Set-Location terraform
terraform init -input=false

# Sprawdź czy workspace istnieje
if (-not (terraform workspace list | Select-String $Environment)) {
    terraform workspace new $Environment
} else {
    terraform workspace select $Environment
}

# Apply z auto-approve
terraform apply -var="project_name=$ProjectName" -var="environment=$Environment" -auto-approve

# Pobierz outputy
$ApiUrl = terraform output -raw api_gateway_url
$FrontendBucket = terraform output -raw s3_frontend_bucket

Set-Location ..\frontend

# 3. Budowanie frontendu
Write-Host "📝 Building frontend..." -ForegroundColor Yellow
"NEXT_PUBLIC_API_URL=$ApiUrl" | Out-File .env.production -Encoding utf8

npm install
npm run build

# 4. Deploy do S3
aws s3 sync .\out "s3://$FrontendBucket/" --delete

Write-Host "`n✅ Deployment complete!" -ForegroundColor Green
Użycie: .\scripts\deploy.ps1 -Environment dev lub .\scripts\deploy.ps1 -Environment prod

Konfiguracja per środowisko

Utwórz terraform/prod.tfvars dla produkcji:

project_name             = "twin"
environment              = "prod"
bedrock_model_id         = "amazon.nova-lite-v1:0"  # Lepszy model
lambda_timeout           = 60
api_throttle_burst_limit = 20
use_custom_domain        = true
root_domain              = "twojadomena.pl"

Dla dev wystarczy terraform.tfvars:

project_name     = "twin"
environment      = "dev"
bedrock_model_id = "amazon.nova-micro-v1:0"  # Tańszy
use_custom_domain = false

🧹 Czyszczenie zasobów (destroy)

Aby uniknąć kosztów za zapomniane zasoby, stwórz scripts/destroy.ps1:

param(
    [Parameter(Mandatory=$true)]
    [string]$Environment,
    [string]$ProjectName = "twin"
)

Write-Host "🗑️ Destroying $ProjectName-$Environment..." -ForegroundColor Red

Set-Location (Join-Path (Split-Path $PSScriptRoot -Parent) "terraform")

# Pobierz nazwy bucketów przed destroy
$AccountId = aws sts get-caller-identity --query Account --output text
$FrontendBucket = "$ProjectName-$Environment-frontend-$AccountId"
$MemoryBucket = "$ProjectName-$Environment-memory-$AccountId"

# Opróżnij S3 (Terraform nie usunie niepustych bucketów)
aws s3 rm "s3://$FrontendBucket" --recursive 2>$null
aws s3 rm "s3://$MemoryBucket" --recursive 2>$null

# Destroy
terraform workspace select $Environment
terraform destroy -auto-approve

Write-Host "✅ Environment $Environment destroyed" -ForegroundColor Green

Dobre praktyki

Praktyka Implementacja
Taguj wszystko Dzięki local.common_tags masz pełną widoczność kosztów per środowisko w AWS Cost Explorer
Nazewnictwo z prefixem Używaj ${local.name_prefix} (np. twin-dev-api) aby uniknąć konfliktów nazw
State backend Dla zespołów przenieś stan do S3 zamiast trzymać lokalnie
.gitignore *.tfstate
.terraform/
*.tfvars (oprócz przykładów)

🐛 Troubleshooting Windows

Problem: terraform nie jest rozpoznawane jako polecenie
Rozwiązanie: Dodaj ścieżkę do Terraform do zmiennych środowiskowych PATH (System Properties → Environment Variables).
Problem: “Error: Invalid function argument” przy ścieżkach
Rozwiązanie: W HCL używaj forward slashes (/) lub podwójnych backslashów (\\).
Problem: PowerShell blokuje skrypty (Execution Policy)
Rozwiązanie: Uruchom PowerShell jako Administrator i wykonaj:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

📋 Podsumowanie komend

Akcja Komenda PowerShell
Inicjalizacja terraform init
Nowy workspace terraform workspace new dev
Deploy terraform apply -auto-approve
Podgląd zmian terraform plan
Destroy terraform destroy -auto-approve
Outputy terraform output
Formatowanie terraform fmt

🎯 Kiedy używać Terraform?

✅ Użyj Terraform gdy:

  • Masz więcej niż jedno środowisko (dev/prod)
  • Zespół współdzieli infrastrukturę
  • Potrzebujesz audytowalności zmian (Git history)
  • Chcesz szybkiego rollbacku (terraform destroy)
  • Automatyzujesz przez CI/CD (GitHub Actions)

❌ Nie potrzebujesz Terraform gdy:

  • Szybki prototyp na jeden wieczór
  • Jeden developer, jedno środowisko
  • Uczysz się AWS i chcesz zrozumieć usługi (najpierw Console, potem IaC)

📚 Bibliografia

  1. HashiCorp. (2025). Terraform Documentation. terraform.io/docs
  2. AWS. (2025). AWS Provider for Terraform. registry.terraform.io/providers/hashicorp/aws
  3. AWS. (2025). AWS Lambda Developer Guide. docs.aws.amazon.com/lambda
  4. Terraform Best Practices. (2025). terraform-best-practices.com
  5. PowerShell Documentation. (2025). Microsoft Learn. learn.microsoft.com/powershell
Wniosek: Terraform na Windowsie działa równie dobrze jak na Linuxie — kluczem jest dobrze skonfigurowany PowerShell i konsekwentne używanie Workspaces do izolacji środowisk. Dzięki temu zamiast klikania w konsoli AWS, możesz deployować swojego AI Twin’a jednym poleceniem: .\scripts\deploy.ps1 -Environment prod.