DevOps

Porovnání Terraform konfigurací před deployem

6. února 2026
12 min čtení
terraform diffinfrastructure as codeIaCDevOpscloudkonfigurace

Terraform se stal standardem pro Infrastructure as Code (IaC). Před každým nasazením změn do cloudové infrastruktury je kritické porovnat aktuální a plánovaný stav. Jediná chyba v konfiguraci může smazat databázi, otevřít bezpečnostní díru nebo způsobit výpadek služby. Tento článek vás provede technikami a nástroji pro bezpečné porovnávání Terraform konfigurací.

Co je Terraform a proč potřebujete diff?

Terraform je open-source nástroj od HashiCorp pro definování infrastruktury jako kódu. Místo manuálního klikání v AWS konzoli nebo Azure portálu definujete infrastrukturu v HCL (HashiCorp Configuration Language) souborech.

Typická Terraform konfigurace:

# main.tf
provider "aws" {
  region = "eu-central-1"
}

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"

  tags = {
    Name        = "production-web"
    Environment = "production"
  }
}

resource "aws_security_group" "web_sg" {
  name        = "web-security-group"
  description = "Allow HTTP and HTTPS traffic"

  ingress {
    from_port   = 443
    to_port     = 443
    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"]
  }
}

Proč je porovnání konfigurací kritické?

1. Prevence neplánovaných změn: Terraform pracuje deklarativně – popisujete požadovaný stav, ne kroky k jeho dosažení. Malá změna v konfiguraci může mít nečekané důsledky.

2. Detekce driftu: Infrastruktura se může změnit mimo Terraform (manuální zásah, jiný nástroj). Porovnání odhalí rozdíly mezi konfigurací a skutečností.

3. Code review pro infrastrukturu: Stejně jako reviewujete změny v aplikačním kódu, musíte reviewovat změny v IaC.

4. Compliance a audit: Regulované prostředí vyžaduje dokumentaci všech změn infrastruktury.

Terraform plan: Základ pro porovnání

Příkaz terraform plan je základní nástroj pro porovnání aktuálního a plánovaného stavu.

Základní použití:

# Inicializace projektu
terraform init

# Zobrazení plánu změn
terraform plan

# Uložení plánu do souboru
terraform plan -out=tfplan

# Aplikace uloženého plánu
terraform apply tfplan

Výstup terraform plan:

Terraform will perform the following actions:

  # aws_instance.web_server will be updated in-place
  ~ resource "aws_instance" "web_server" {
        id            = "i-0abc123def456"
      ~ instance_type = "t3.small" -> "t3.medium"
        tags          = {
            "Name"        = "production-web"
            "Environment" = "production"
        }
    }

  # aws_security_group.web_sg will be created
  + resource "aws_security_group" "web_sg" {
      + arn                    = (known after apply)
      + description            = "Allow HTTP and HTTPS traffic"
      + egress                 = [
          + {
              + cidr_blocks      = ["0.0.0.0/0"]
              + from_port        = 0
              + protocol         = "-1"
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = ["0.0.0.0/0"]
              + from_port        = 443
              + protocol         = "tcp"
              + to_port          = 443
            },
        ]
      + name                   = "web-security-group"
    }

Plan: 1 to add, 1 to change, 0 to destroy.

Symboly v terraform plan:

Symbol Význam Riziko
+ Nový resource bude vytvořen Nízké
- Resource bude zničen Vysoké
~ Resource bude upraven in-place Střední
-/+ Resource bude zničen a znovu vytvořen Vysoké

Pokročilé techniky terraform plan

1. Detailní výstup změn:

# Podrobný výstup
terraform plan -detailed-exitcode

# Exit codes:
# 0 = Žádné změny
# 1 = Chyba
# 2 = Jsou změny k aplikaci

2. Targeting specifických resources:

# Plan pouze pro konkrétní resource
terraform plan -target=aws_instance.web_server

# Plan pro celý modul
terraform plan -target=module.networking

3. Porovnání s jiným state souborem:

# Použití alternativního state
terraform plan -state=production.tfstate

4. JSON výstup pro automatizaci:

# JSON formát pro strojové zpracování
terraform plan -json > plan.json

# Parsování pomocí jq
terraform plan -json | jq '.resource_changes[] | select(.change.actions | contains(["delete"]))'

Porovnání Terraform souborů před změnou

Kromě terraform plan je užitečné porovnat samotné konfigurační soubory – především při code review.

Metoda 1: Git diff

# Zobrazení změn v .tf souborech
git diff HEAD~1 -- "*.tf"

# Diff mezi větvemi
git diff main...feature-branch -- "*.tf"

# Diff se zvýrazněním syntaxe (vyžaduje delta nebo diff-so-fancy)
git diff main...feature-branch -- "*.tf" | delta

Metoda 2: Online nástroj PorovnejText.cz

Pro rychlé vizuální porovnání dvou verzí Terraform konfigurace:

  1. Otevřete PorovnejText.cz
  2. Vložte původní verzi souboru do levého pole
  3. Vložte novou verzi do pravého pole
  4. Zvolte jazyk "HCL" nebo "Terraform"
  5. Klikněte na "Porovnat"

Výhody:

  • ✅ Okamžité barevné zvýraznění
  • ✅ Žádná instalace
  • ✅ 100% soukromí – kód zůstává v prohlížeči

Metoda 3: Terraform fmt diff

# Zobrazení formátovacích změn bez aplikace
terraform fmt -diff -check

# Rekurzivně pro všechny moduly
terraform fmt -diff -check -recursive

Terraform state diff

Terraform state obsahuje mapování mezi konfigurací a skutečnou infrastrukturou.

Porovnání state souborů:

# Export state do JSON
terraform state pull > current_state.json

# Porovnání dvou state souborů
diff <(jq -S . old_state.json) <(jq -S . current_state.json)

# Pomocí terraform show
terraform show -json tfplan > plan_output.json

Detekce state driftu:

# Refresh state bez aplikace změn
terraform plan -refresh-only

# Výstup ukáže rozdíly mezi state a skutečnou infrastrukturou

Terraform diff v CI/CD pipeline

Automatizace porovnání Terraform konfigurací je klíčová pro bezpečný deployment.

GitHub Actions workflow:

# .github/workflows/terraform.yml
name: Terraform Plan

on:
  pull_request:
    paths:
      - '**/*.tf'
      - '**/*.tfvars'

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.7.0

      - name: Terraform Init
        run: terraform init

      - name: Terraform Format Check
        run: terraform fmt -check -recursive

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color -out=tfplan
        continue-on-error: true

      - name: Post Plan to PR
        uses: actions/github-script@v7
        with:
          script: |
            const output = `#### Terraform Plan 📖

            \`\`\`
            ${{ steps.plan.outputs.stdout }}
            \`\`\`
            `;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

      - name: Fail if plan failed
        if: steps.plan.outcome == 'failure'
        run: exit 1

GitLab CI pipeline:

# .gitlab-ci.yml
stages:
  - validate
  - plan
  - apply

variables:
  TF_ROOT: ${CI_PROJECT_DIR}/terraform

.terraform:
  image: hashicorp/terraform:1.7.0
  before_script:
    - cd ${TF_ROOT}
    - terraform init

validate:
  extends: .terraform
  stage: validate
  script:
    - terraform fmt -check -recursive
    - terraform validate

plan:
  extends: .terraform
  stage: plan
  script:
    - terraform plan -out=tfplan
  artifacts:
    paths:
      - ${TF_ROOT}/tfplan
    expire_in: 1 week
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

apply:
  extends: .terraform
  stage: apply
  script:
    - terraform apply -auto-approve tfplan
  dependencies:
    - plan
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual

Nástroje pro Terraform diff

1. Terraform Cloud/Enterprise

HashiCorp Terraform Cloud nabízí:

  • Vizuální diff v UI
  • Speculative plans pro PR
  • Policy as Code (Sentinel)
  • Audit logging

2. Atlantis

Open-source pull request automation:

# atlantis.yaml
version: 3
projects:
  - name: production
    dir: environments/production
    workflow: production
    autoplan:
      when_modified:
        - "*.tf"
        - "*.tfvars"
      enabled: true

workflows:
  production:
    plan:
      steps:
        - init
        - plan
    apply:
      steps:
        - apply

3. Infracost

Nástroj pro odhad nákladů na infrastrukturu:

# Instalace
brew install infracost

# Generování cost diffu
infracost diff --path . --compare-to infracost-base.json

# Výstup v PR komentáři
infracost comment github --path infracost.json --repo owner/repo --pull-request 123

4. Checkov

Statická analýza bezpečnosti:

# Instalace
pip install checkov

# Skenování Terraform kódu
checkov -d . --framework terraform

# Diff mezi dvěma verzemi
checkov -d . --baseline baseline.json

5. tflint

Linter pro Terraform:

# Instalace
brew install tflint

# Inicializace pravidel
tflint --init

# Kontrola konfigurace
tflint --recursive

Best practices pro Terraform diff

1. Vždy používejte remote state

# backend.tf
terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "production/terraform.tfstate"
    region         = "eu-central-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

Proč:

  • Sdílený state mezi členy týmu
  • State locking zabraňuje konfliktům
  • Verzování v S3 pro rollback

2. Používejte workspaces nebo adresáře pro prostředí

# Struktura s adresáři
environments/
├── development/
│   ├── main.tf
│   └── terraform.tfvars
├── staging/
│   ├── main.tf
│   └── terraform.tfvars
└── production/
    ├── main.tf
    └── terraform.tfvars

# Nebo workspaces
terraform workspace new production
terraform workspace select production
terraform plan

3. Modulární struktura

# modules/vpc/main.tf
variable "cidr_block" {
  type        = string
  description = "CIDR block for VPC"
}

resource "aws_vpc" "main" {
  cidr_block = var.cidr_block

  tags = {
    Name = "${var.environment}-vpc"
  }
}

# environments/production/main.tf
module "vpc" {
  source     = "../../modules/vpc"
  cidr_block = "10.0.0.0/16"
}

4. Verzování modulů

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.1.2"  # Pinovaná verze

  name = "production-vpc"
  cidr = "10.0.0.0/16"
}

5. Pre-commit hooks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.83.6
    hooks:
      - id: terraform_fmt
      - id: terraform_validate
      - id: terraform_tflint
      - id: terraform_docs
      - id: terraform_checkov

Řešení běžných problémů

Problém 1: Neočekávané destroy

Situace: Plan ukazuje -/+ (destroy and recreate) místo ~ (update).

Příčiny:

  • Změna immutable atributu (např. ami u EC2)
  • Změna názvu resource
  • Změna providera

Řešení:

# Přesunutí resource do jiného stavu
terraform state mv aws_instance.old aws_instance.new

# Ignorování změn v lifecycle
lifecycle {
  ignore_changes = [ami]
}

Problém 2: State drift

Situace: Někdo změnil infrastrukturu mimo Terraform.

Řešení:

# Detekce driftu
terraform plan -refresh-only

# Import existující infrastruktury
terraform import aws_instance.web i-abc123

# Synchronizace state
terraform apply -refresh-only

Problém 3: Konfliktní změny v týmu

Situace: Dva lidé mění stejnou infrastrukturu současně.

Řešení:

# State locking pomocí DynamoDB
terraform {
  backend "s3" {
    # ...
    dynamodb_table = "terraform-locks"
  }
}

# Manuální unlock při problémech
terraform force-unlock LOCK_ID

Problém 4: Příliš velký plan

Situace: Plan je nepřehledný kvůli množství změn.

Řešení:

# Targeting specifických resources
terraform plan -target=module.networking

# Filtrování výstupu
terraform plan -json | jq '.resource_changes[] | select(.change.actions != ["no-op"])'

# Použití terragrunt pro lepší organizaci
terragrunt run-all plan

Bezpečnostní aspekty

1. Citlivé hodnoty v planu

# Označení citlivých proměnných
variable "database_password" {
  type      = string
  sensitive = true
}

# Sensitive output
output "connection_string" {
  value     = "postgres://user:${var.database_password}@host/db"
  sensitive = true
}

2. Policy as Code

# Sentinel policy (Terraform Enterprise)
import "tfplan"

main = rule {
  all tfplan.resources.aws_security_group as _, instances {
    all instances as _, r {
      r.applied.ingress[0].cidr_blocks not contains "0.0.0.0/0"
    }
  }
}

3. RBAC pro state

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::terraform-state/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/team": "platform"
        }
      }
    }
  ]
}

Checklist před terraform apply

Před každým apply zkontrolujte:

  1. Plan review:

    • Přečetli jste celý plan?
    • Rozumíte všem změnám?
    • Nejsou tam nečekané destroy?
  2. Bezpečnost:

    • Jsou security groups správně nastavené?
    • Nejsou exponované citlivé porty?
    • Je zapnuté šifrování?
  3. Náklady:

    • Zkontrolovali jste instance typy?
    • Je nastaven auto-scaling?
    • Odpovídá to rozpočtu?
  4. Backup a recovery:

    • Existuje backup před změnou?
    • Je možný rollback?
    • Je zdokumentovaný recovery plán?
  5. Timing:

    • Je vhodný čas pro změnu?
    • Jsou dostupní kolegové pro případnou pomoc?
    • Je naplánované maintenance window?

Závěr

Porovnávání Terraform konfigurací před deployem je základní praxí pro bezpečný Infrastructure as Code workflow. Klíčové body:

Vždy používejte terraform plan:

  • Před každým apply
  • S uložením do souboru pro audit
  • S JSON výstupem pro automatizaci

Automatizujte v CI/CD:

  • Plan v pull requestu
  • Automatické kontroly formátování a validace
  • Cost estimation a security scanning

Dodržujte best practices:

  • Remote state s lockingem
  • Modulární struktura
  • Verzování modulů
  • Pre-commit hooks

Nezapomínejte na bezpečnost:

  • Sensitive values
  • Policy as Code
  • RBAC pro state přístup

Investice do kvalitního diff workflow se vrátí v podobě stabilnější infrastruktury, méně výpadků a lepší spolupráce v týmu.


Potřebujete rychle porovnat Terraform konfigurace? Použijte PorovnejText.cz – okamžité porovnání kódu s barevným zvýrazněním přímo ve vašem prohlížeči. Vše běží lokálně, žádná data se neodesílají na server.

Vyzkoušejte PorovnejText.cz zdarma

Nejrychlejší český nástroj pro porovnání textů. Vše probíhá ve vašem prohlížeči, žádná registrace není potřeba.

Porovnat texty nyní →