This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Infrastructure as a Code

Infrastruktura jako kod

Założenia projektów Infrastructure as a Code

Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:

  • zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
  • automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.

Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.

1 - Opentofu

IaC za pomocą Opentofu

Opentofu to narzędzie typu Infrastructure as Code (IaC), które umożliwia definiowanie, provisionowanie i zarządzanie infrastrukturą za pomocą plików konfiguracyjnych. Dzięki temu narzędziu możesz w sposób deklaratywny opisywać zasoby, takie jak serwery, sieci czy usługi w chmurze, a następnie automatycznie je tworzyć, modyfikować i usuwać, zapewniając spójność środowisk.

Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.


Założenia projektów Infrastructure as a Code

Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji. Jednym z najczęściej wykorzystywanych narzędzi do implementacji IaC jest Terraform / OpenTofu. Bliźniacze rozwiązania umożliwiają automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.

Wdrażając podejście IaC z użyciem Terraform, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.

Poniżej znajduje się lista projektów Infrastructure as a Code.

project version description
iac-gitlab IAC do zarządzania środowiskiem GitLab.
iac-mikrotik IAC do zarządzania routerami Mikrotik.
iac-proxmox IAC do zarządzania środowiskiem Proxmox.
iac-vault IAC do zarządzania środowiskiem Vault.

Architektura projektu OpenTofu w pl.rachuna-net

# Przykładowy opis struktury projektu
pl.rachuna-net/infrastructure/opentofu
├── gitlab-profile                      # Documentation
├── iac-gitlab
├── iac-mikrotik                          
├── iac-proxmox
├── iac-vault                          
├── modules                             # Opentofu modules
│   ├── gitlab-group
│   ├── gitlab-project
│   ├── proxmox-container
│   ├── proxmox-vm
│   ├── routeros-bonding
│   ├── routeros-bridge
│   ├── routeros-dhcp-server
│   ├── routeros-dns
│   ├── routeros-ethernet
│   ├── routeros-system
│   ├── routeros-vlan
│   └── vault-pki
├── proxmox
└── router.rachuna-net.pl

1.1 - iac-gitlab

IAC do zarządzania środowiskiem GitLab.

Repozytorum: iac-gitlab

Repozytorium zawierające infrastrukturę jako kod (IaC) do zarządzania środowiskiem GitLab przy użyciu OpenTofu. Umożliwia automatyzację tworzenia, konfiguracji i utrzymania zasobów GitLab.

Architektura rozwiązania

flowchart TB
 subgraph s1["opentofu module"]
        n2["gitlab-group"]
        n1("gitlab-project")
  end
    A["iac-gitlab"] --> n1
    A --> n2
    n2@{ shape: rounded}

Przykładowy układ plików

Jak można zauważyć katalogi i pliki odzwierciedlają ułożenie repozytoriów w rzeczywistości.

.
├── data
│   ├── allowed_avatar_group_types.json
│   ├── allowed_avatar_project_types.json
│   ├── allowed_project_types.json
│   ├── group_badges.json
│   └── labels.json
├── _data.tf
├── images
│   ├── group
│   │   └── *.png
│   └── project
│       └── *.png
├── _locals.tf
├── pl.rachuna-net
│   ├── apps
│   │   ├── docs.tf
│   │   └── _locals.tf
│   ├── apps.tf
│   ├── cicd
│   │   ├── gitlab-ci.tf
│   │   └── _locals.tf
│   ├── cicd.tf
│   ├── containers
│   │   ├── buildah.tf
│   │   ├── gohugo.tf
│   │   ├── _locals.tf
│   │   ├── opentofu.tf
│   │   ├── python.tf
│   │   ├── semantic-release.tf
│   │   └── trivy.tf
│   ├── containers.tf
│   ├── infrastructure
│   │   ├── _locals.tf
│   │   ├── opentofu
│   │   │   ├── iac-gitlab.tf
│   │   │   ├── _locals.tf
│   │   │   ├── modules
│   │   │   │   ├── gitlab-group.tf
│   │   │   │   ├── gitlab-project.tf
│   │   │   │   └── _locals.tf
│   │   │   └── modules.tf
│   │   └── opentofu.tf
│   ├── infrastructure.tf
│   └── _locals.tf
├── pl.rachuna-net.tf
└── _providers.tf

1.1.1 - Grupy repozytoriów

Tworzenie grupy repozytoriów w GitLab za pomocą OpenTofu

Niniejsza sekcja dokumentacji opisuje proces tworzenia grupy repozytoriów w GitLab przy użyciu OpenTofu. Prezentowane podejście umożliwia automatyczne zarządzanie strukturą repozytoriów, co wspiera podejście Infrastructure as Code (IaC).

Repozytorium GitLab zawierające definicję
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/iac-gitlab

Repozytorium modułu opentofu - gitlab-group
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/modules/gitlab-group

Korzyści wynikające z użycia OpenTofu

OpenTofu pozwala na:

  • Automatyzację tworzenia i zarządzania grupami repozytoriów,
  • Wersjonowanie konfiguracji, co ułatwia kontrolę zmian,
  • Powtarzalność konfiguracji, eliminując błędy manualne.

Definiowanie grupy w OpenTofu

Aby utworzyć grupę repozytoriów w GitLab, należy dodać odpowiednią definicję do pliku konfiguracyjnego OpenTofu.

Przykładowy plik konfiguracyjny OpenTofu

Definicja grupy

📄 Ścieżka pliku: pl.rachuna-net/containers.tf

module "_containers" {
  source = "git@gitlab.com:pl.rachuna-net/infrastructure/opentofu/modules/gitlab-group.git?ref=v1.0.0"

  name           = "containers"
  description    = "Repozytoria z obrazami kontenerowymi."
  parent_group   = local.parent_name
  visibility     = "public"
  default_branch = "main"
  avatar         = "containers"

}

module "containers" {
  source = "./containers/"
}

Definicja parametrów dla dzieci

📄 Ścieżka pliku: pl.rachuna-net/containers/_locals.tf

locals {
  parent_name  = "pl.rachuna-net/containers"
  project_type = "container"
}

1.1.2 - Repozytorium kodu

Tworzenie repozytorium w GitLab za pomocą OpenTofu

Niniejsza sekcja dokumentacji opisuje proces tworzenia repozytoriów w GitLab przy użyciu OpenTofu. Prezentowane podejście umożliwia automatyczne zarządzanie repozytoriami, co wspiera podejście Infrastructure as Code (IaC).

Repozytorium GitLab zawierające definicję
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/iac-gitlab

Repozytorium modułu opentofu - gitlab-group
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/modules/gitlab-project

Korzyści wynikające z użycia OpenTofu

OpenTofu pozwala na:

  • Automatyzację tworzenia i zarządzania grupami repozytoriów,
  • Wersjonowanie konfiguracji, co ułatwia kontrolę zmian,
  • Powtarzalność konfiguracji, eliminując błędy manualne.

Definiowanie grupy w OpenTofu

Aby utworzyć repozytorium w GitLab, należy dodać odpowiednią definicję do pliku konfiguracyjnego OpenTofu.

📄 Ścieżka pliku: pl.rachuna-net/containers/opentofu

module "opentofu" {
  source = "git@gitlab.com:pl.rachuna-net/infrastructure/opentofu/modules/gitlab-project.git?ref=v1.0.0"

  name               = "opentofu"
  archived           = false
  description        = "Obraz Dockerowy z narzędziem opentofu."
  visibility         = "public"
  tags               = ["docker", "opentofu"]
  avatar             = "opentofu"
  parent_group       = local.parent_name
  project_type       = "container"
  build_git_strategy = "clone"
  gitlab_ci_path     = "containers/docker.yml@pl.rachuna-net/cicd/gitlab-ci"

  # sonarqube
  is_enabled_sonarqube       = true
  sonarqube_cloud_project_id = "pl.rachuna-net_opentofu"

  # mirror to github
  mirror_url = format(
    "https://%s:%s@github.com/%s/%s.git",
    data.vault_kv_secret_v2.github.data["owner"],
    data.vault_kv_secret_v2.github.data["token"],
    data.vault_kv_secret_v2.github.data["owner"],
    "pl.rachuna-net.containers.opentofu"
  )

  variables = {
    PUBLISH_VAULT_SECRET_PATH = {
      description = "Ścieżka do sekrety Vault, gdzie będą publikowane zmienne środowiskowe",
      value       = "pl.rachuna-net/containers/opentofu:CONTAINER_IMAGE_OPENTOFU"
    }
    PUBLISH_VAULT_VALUE_VARIABLE = {
      description = "Nazwa zmiennej środowiskowej, która będzie publikowana w Vault",
      value       = "CONTAINER_IMAGE_VERSION"
    }
  }
}

1.2 - iac-vault

IAC do zarządzania HashiCorp Vault przy użyciu OpenTofu.

Repozytorium: iac-vault

Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą zarządzanie środowiskiem HashiCorp Vault za pomocą OpenTofu. Projekt automatyzuje tworzenie, konfigurację oraz utrzymanie komponentów Vault, w tym trzystopniowego PKI, przestrzeni KV oraz polityk dostępu.


Architektura rozwiązania

Repozytorium iac-vault pełni rolę głównego punktu orkiestracji konfiguracji Vault. Bazuje na dedykowanym module vault-pki, który odpowiada za budowę hierarchii certyfikatów.

flowchart TB
 subgraph s1["opentofu module"]
        n2["vault-pki"]
  end
    A["iac-vault"] --> n3["auth"] & n4["pki"] & n5["secrets"] & n6["polices"]
    n4 --> n2

    n2@{ shape: rounded}

Struktura repozytorium:

.
├── auth                     # mechanizmy autoryzacji (userpass, AppRole)
├── main.tf                  # główny plik wykonawczy OpenTofu
├── pki                      # konfiguracja PKI oparta o moduł vault-pki
├── policies                 # polityki ACL Vault
├── providers.tf             # definicje providerów
├── secrets                  # konfiguracja backendów KV
└── variables.tf             # zmienne globalne

Główny plik main.tf integruje moduły:

  • pki
  • secrets
  • policies
  • auth

Parametry globalne, takie jak var.pki_urls_base (adres publikacji certyfikatów i CRL) oraz var.kv_mount_path, definiowane są w pliku variables.tf.


Public Key Infrastructure (PKI)

Warstwa PKI korzysta z modułu:

👉 vault-pki

Moduł automatyzuje budowę trójwarstwowej hierarchii certyfikatów:

Root CA

  • pki-root – tworzy główny urząd certyfikacji.

Intermediate CA

Dwa niezależne urzędy pośrednie, wykorzystywane zgodnie z podziałem ról:

  • pki-infrastructure – certyfikaty dla infrastruktury (np. routery, systemy HA, bazy danych)
  • pki-apps – certyfikaty dla aplikacji i usług

Certyfikaty końcowe (leaf)

Moduł pozwala generować certyfikaty końcowe oraz zapisywać je jako sekrety Vault.

Integracja z sekcjami secrets

Wygenerowane certyfikaty mogą być opcjonalnie przechowywane w backendach KV (np. kv-certificates), co umożliwia ich łatwe pobieranie przez inne procesy (np. Ansible, CI/CD).


Polityki dostępu (ACL Policies)

Polityki zdefiniowane są w katalogu policies/ i odpowiadają za granularną kontrolę dostępu do zasobów Vault.

Struktura zawiera m.in.:

Polityki ogólne

  • full-admin.hcl – pełne uprawnienia administracyjne.

Polityki dla storage KV

  • kv-devops
  • kv-gitlab
  • kv-certificates

Każda z nich definiuje:

  • uprawnienia odczytu (policy_read.hcl)
  • uprawnienia zapisu (policy_write.hcl)
  • uprawnienia administracyjne (policy_admin.hcl)

Polityki dla PKI

  • pki-root
  • pki-infrastructure
  • pki-apps

Zawierają:

  • pozwolenia na odczyt CA,
  • generowanie CRL,
  • wydawanie certyfikatów,
  • administrowanie backendem PKI.

Polityki są automatycznie rejestrowane w policies/main.tf.


Auth

Mechanizmy uwierzytelniania znajdują się w katalogu auth/.

Obejmują:

userpass

  • zarządzanie użytkownikami Vault,
  • definiowanie ról,
  • konfigurację dostępu (np. użytkownik mrachuna).

AppRole

  • integracja z CI/CD (np. GitLab CI),
  • generowanie ról i secret_id dla pipeline’ów.

Mechanizmy auth są aktywowane i konfigurowane w auth/main.tf.


Podsumowanie

Repozytorium iac-vault zapewnia kompletny, modułowy i skalowalny zestaw IaC do zarządzania HashiCorp Vault w środowisku produkcyjnym. Łączy:

  • trzystopniowy PKI,
  • kontrolę dostępu,
  • storage KV,
  • mechanizmy auth,
  • dobre praktyki organizacji zasobów w Vault.

Całość jest w pełni automatyzowalna dzięki OpenTofu i integruje się z pipeline’ami GitLab CI oraz procesami konfiguracji (np. Ansible).

1.2.1 - Secret storage

Tworzenie storage dla secretów

KV (Key-Value) w HashiCorp Vault to jeden z najprostszych i najczęściej używanych backendów sekretów. Służy do przechowywania dowolnych danych w formie klucz–wartość, takich jak:

  • hasła,
  • tokeny API,
  • klucze prywatne,
  • konfiguracje usług,
  • certyfikaty,
  • dane konfiguracyjne aplikacji.

Sekcja secrets definiuje backendy KV v2 przeznaczone do przechowywania poufnych danych, takich jak:

  • konfiguracje projektów,
  • tokeny,
  • hasła,
  • certyfikaty końcowe.

Przykładowa konfiguracja backendu:

resource "vault_mount" "kv_gitlab" {
  path        = "kv-gitlab"
  type        = "kv-v2"
  description = "Storage for GitLab related secrets"
  options = {
    version = "2"
    type    = "kv-v2"
  }
}

resource "vault_kv_secret_backend_v2" "kv_gitlab_config" {
  mount        = vault_mount.kv_gitlab.path
  max_versions = 10
  cas_required = false
}

1.2.2 - PKI

Tworzenie PKI w organizacji

PKI (Public Key Infrastructure) to infrastruktura klucza publicznego – zestaw technologii, zasad i komponentów, które umożliwiają bezpieczną komunikację, uwierzytelnianie i szyfrowanie w systemach informatycznych.


Utworzenie drzewa certyfikatów Root CA i Intermediate CA

stateDiagram
  direction TB
  classDef Sky stroke-width:1px,stroke-dasharray:none,stroke:#374D7C,fill:#E2EBFF,color:#374D7C;
  classDef Peach stroke-width:1px,stroke-dasharray:none,stroke:#FBB35A,fill:#FFEFDB,color:#8F632D;
  [*] --> s1
  s1 --> s2
  s1 --> s5
  s1:Root CA
s1:*.rachuna-net.pl

  s2:Infrastructure Intermediate CA
s2:Certyfikaty Infrastruktury

  [*]
  s5:Apps Intermediate CA
s5:Certyfikaty Aplikacji

  class s5 Peach
module "vault_pki" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.0.0"

  root_domain      = "rachuna-net.pl"
  root_common_name = "rachuna-net.pl ROOT CA"
  pki_urls_base    = "https://ct01101.rachuna-net.pl:8200/"

  intermediates = {
    infrastructure = {
      path        = "pki-infrastructure"
      common_name = "rachuna-net.pl Infrastructure Intermediate CA"
      role_name   = "infrastructure-default"
    }
    apps = {
      path        = "pki-apps"
      common_name = "rachuna-net.pl Apps Intermediate CA"
      role_name   = "apps-default"
    }
  }

}

Przykładowe rozwiązanie reprezentuje certyfikat główny ROOT CA oraz certyfikaty pośredniczące nfrastructure Intermediate CA dedykowany dla infrastruktury oraz Apps Intermediate CA


Wygenerowanie certyfikatu końcowego

  1. Generowanie certyfikaty końcowe (leaf) dla konkretnych usług:

    • gitlab.rachuna-net.pl
    • consul.rachuna-net.pl
    • vault.rachuna-net.pl
    • docs.rachuna-net.pl
module "vault_pki" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.0.0"

  root_domain   = "rachuna-net.pl"
  pki_urls_base = "https://ct01101.rachuna-net.pl:8200/"

  intermediates = {
    infrastructure = {
      path        = "pki-infrastructure"
      common_name = "Infrastructure Intermediate CA"
      role_name   = "infrastructure-default"
    }
    apps = {
      path        = "pki-apps"
      common_name = "Apps Intermediate CA"
      role_name   = "apps-default"
    }
  }

  leaf_requests = {
    "infra-gitlab" = {
      backend_key = "infrastructure"
      common_name = "gitlab.rachuna-net.pl"
      alt_names = [
        "registry.rachuna-net.pl"
      ]
    }
    "infra-consul" = {
      backend_key = "infrastructure"
      common_name = "consul.rachuna-net.pl"
      alt_names = [
        "ct01101.rachuna-net.pl",
        "ct01102.rachuna-net.pl",
        "ct01103.rachuna-net.pl",
      ]
    }
    "infra-vault" = {
      backend_key = "infrastructure"
      common_name = "vault.rachuna-net.pl"
      alt_names = [
        "ct01101.rachuna-net.pl",
        "ct01102.rachuna-net.pl",
        "ct01103.rachuna-net.pl",
      ]
    }
    "apps-docs" = {
      backend_key = "apps"
      common_name = "docs.rachuna-net.pl"
    }
  }
}

Kluczowe parametry:

  • root_domain = "rachuna-net.pl" Root CA będzie wystawiony dla tej domeny, np. Rachuna-Net Root CA.

  • pki_urls_base = "https://ct01101.rachuna-net.pl:8200/" Baza do ustawienia:

    • issuing_certificates
    • crl_distribution_points
    • ocsp_servers czyli gdzie klienci mają się zgłaszać po CRL / certyfikaty.
  • intermediates – definicja CA pośrednich (mapa):

    • klucz (infrastructure, apps) to alias używany dalej w module,
    • path – mount w Vault, np. pki-infrastructure,
    • common_name – CN tego CA,
    • role_name – domyślna rola w tym backendzie (do wystawiania leafów).
  • leaf_requestslista certyfikatów końcowych do wygenerowania:

    • klucz mapy (infra-gitlab, infra-consul…) to tylko nazwa logiczna w module,
    • backend_key – mówi, z którego intermediate CA korzystać (infrastructure / apps),
    • common_name – CN certyfikatu (zazwyczaj FQDN usługi),
    • alt_names – Subject Alternative Names (SAN) – dodatkowe nazwy DNS w certyfikacie.

Pobieranie certyfikatu

Zależy, jak moduł jest napisany, ale typowo:

  • Zapisane są certyfikaty w kv (np. kv-certificates/leaf/grafana),
{
  "alt_names": [],
  "backend_key": "apps",
  "ca_chain": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
  "certificate": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
  "common_name": "test.rachuna-net.pl",
  "issuing_ca": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
  "private_key": "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----",
  "serial_number": "42:b5:19:73:cd:f9:70:0c:30:81:93:fb:b5:56:a1:7e:f9:25:6a:23"
}
  • bezpośrednio do pobrania z pki
RESP=$(curl \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  --request POST \
  --data '{"common_name": "grafana.rachuna-net.pl"}' \
  https://ct01005.rachuna-net.pl:8200/v1/pki-apps/issue/apps-default)

echo "$RESP" | jq -r '.data.certificate'  > grafana.crt
echo "$RESP" | jq -r '.data.private_key'  > grafana.key
echo "$RESP" | jq -r '.data.issuing_ca'   > grafana.chain.crt

Proponowany podział PKI?

Z poziomu dev/DevOps masz bardzo prosty mentalny model:

  • Root CA – trzymasz w Vault, ale używasz tylko do podpisywania intermediates.

  • Intermediate CA – logiczny podział według typu systemów:

    • infrastructure: Proxmox, Consul, Vault, GitLab, routery, load balancery.
    • apps: aplikacje biznesowe, frontend, API.
    • (opcjonalnie) dmz, internal, storage, kubernetes itd.
  • Leaf certyfikaty – dla konkretnych hostów/usług.

I wszystko opisujesz w dwóch mapach: intermediates i leaf_requests.


Przykłady rozbudowania PKI

Kilka konkretnych trików:

  1. Osobny intermediate dla Kubernetes:

    intermediates = {
      # ...
      kubernetes = {
        path        = "pki-k8s"
        common_name = "Kubernetes Intermediate CA"
        role_name   = "k8s-default"
      }
    }
    
  2. Cert dla Ingress Controller:

    leaf_requests = {
      "k8s-ingress" = {
        backend_key = "kubernetes"
        common_name = "ingress.rachuna-net.pl"
        alt_names = [
          "*.apps.rachuna-net.pl",
        ]
      }
    }
    

Użycie ACME

Ten blok możesz podmienić w sekcji „Utworzenie drzewa certyfikatów Root CA i Intermediate CA” (stary przykład z ref=v1.0.0 → nowy z ref=v1.1.0 + ACME):

module "vault_pki" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.1.0"

  root_domain      = "rachuna-net.pl"
  root_common_name = "rachuna-net.pl ROOT CA"
  pki_urls_base    = "https://ct01005.rachuna-net.pl:8200"

  intermediates = {
    infrastructure = {
      path        = "pki-infrastructure"
      common_name = "rachuna-net.pl Infrastructure Intermediate CA"
      role_name   = "infrastructure-default"

      # klasyczne parametry PKI
      ttl     = "26280h"
      max_ttl = "26280h"

      # konfiguracja ACME dla infrastruktury
      acme = {
        acme_enabled                = true
        acme_cluster_path           = "https://ct01005.rachuna-net.pl"
        allow_wildcard_certificates = true
        max_ttl                     = "168h"
      }

      # (opcjonalnie) aliasy/parametry dla zachowania wstecznej kompatybilności modułu
      acme_enabled      = true
      acme_cluster_path = "https://ct01005.rachuna-net.pl"
    }

    apps = {
      path        = "pki-apps"
      common_name = "rachuna-net.pl Apps Intermediate CA"
      role_name   = "apps-default"

      # zezwalamy na wildcardy z tego backendu
      allow_wildcard_certificates = true

      # klasyczne parametry PKI
      ttl     = "26h"
      max_ttl = "26h"

      # konfiguracja ACME dla aplikacji
      acme = {
        acme_enabled      = true
        acme_cluster_path = "https://ct01005.rachuna-net.pl"
        max_ttl           = "25h"
      }
    }
  }
}

1.2.3 - Uwierzytelnianie (Auth)

Uwierzytelnianie (Auth)

Uwierzytelnianie (Auth)

Moduł Auth odpowiada za konfigurację metod uwierzytelniania w HashiCorp Vault oraz przypisywanie użytkownikom i procesom automatycznym odpowiednich polityk dostępu (policies). W projekcie wykorzystywane są dwie główne metody:

  • Userpass – dla użytkowników technicznych i administratorów,
  • AppRole – dla automatyzacji (CI/CD, GitLab Runner, systemy integracyjne).

1. Polityki (Policies)

Polityki definiują zakres dostępu do ścieżek w Vault. Każda polityka opisuje:

  • na jakich ścieżkach (path)
  • jakie operacje (capabilities) są dozwolone.

1.1. Minimalny przykład polityki

Plik polityki w formacie HCL:

# policies/app-read.hcl
path "kv-apps/data/apps/example-service" {
  capabilities = ["read"]
}

Rejestracja polityki w Vault:

resource "vault_policy" "app_read" {
  name   = "app-read"
  policy = file("${path.module}/policies/app-read.hcl")
}

1.2. Zasady organizacyjne dla polityk

W projekcie polityki są utrzymywane w sposób modułowy w katalogu:

iac-vault/policies/

Struktura:

  • pki-* – polityki dla PKI,
  • kv-* – polityki dla KV,
  • .full-admin – pełne uprawnienia administracyjne.

Każda nowa polityka powinna zostać dodana jako osobny moduł, aby zachować:

  • spójność zarządzania,
  • możliwość kontroli wersji,
  • łatwe przypisywanie do metod uwierzytelniania.

2. Userpass – użytkownicy z przypisanymi politykami

Metoda userpass umożliwia logowanie do Vault za pomocą:

  • loginu,
  • hasła,
  • przypisanych polityk.

2.1. Włączenie metody userpass

resource "vault_auth_backend" "userpass" {
  type = "userpass"
}

2.2. Tworzenie użytkownika i przypisywanie polityk

resource "vault_generic_endpoint" "user_jan" {
  depends_on = [vault_auth_backend.userpass]

  path = "auth/userpass/users/jan"

  data_json = jsonencode({
    password = "silne-haslo"
    policies = [
      ".full-admin",
      "kv-apps.policy_admin"
    ]
  })
}

2.3. Znaczenie pól

Pole Opis
path Ścieżka użytkownika w metodzie userpass
password Hasło użytkownika
policies Lista polityk przypisanych do użytkownika

✅ Ten mechanizm stosowany jest głównie dla:

  • administratorów,
  • operatorów,
  • użytkowników technicznych.

3. AppRole – tokeny dla automatyzacji (CI/CD, GitLab)

Metoda AppRole przeznaczona jest dla:

  • pipeline’ów GitLab,
  • narzędzi automatyzujących,
  • systemów backendowych.

Logowanie odbywa się przy użyciu:

  • role_id,
  • secret_id.

3.1. Włączenie metody AppRole

resource "vault_auth_backend" "approle" {
  type = "approle"
}

3.2. Definicja roli AppRole

resource "vault_approle_auth_backend_role" "ci_role" {
  backend        = vault_auth_backend.approle.path
  role_name      = "ci-role"

  token_policies = [
    "kv-apps.policy_write",
    "pki-apps.policy_read"
  ]

  token_ttl      = "24h"
  token_max_ttl  = "24h"
}

3.3. Generowanie secret_id

resource "vault_approle_auth_backend_role_secret_id" "ci_role" {
  backend   = vault_auth_backend.approle.path
  role_name = vault_approle_auth_backend_role.ci_role.role_name
}

3.4. Znaczenie parametrów

Parametr Opis
role_name Nazwa roli używana w automatyzacji
token_policies Polityki przypisane do tokenu
token_ttl Czas życia tokenu
token_max_ttl Maksymalny czas życia tokenu
secret_id Jednorazowy sekret do logowania

1.3 - iac-proxmox

IAC do zarządzania clustrem Proxmox przy użyciu OpenTofu.

Repozytorium: iac-proxmox

Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą automatyczne, deklaratywne zarządzanie infrastrukturą kontenerową i wirtualną w środowisku Proxmox VE.

Projekt umożliwia:

  • tworzenie kontenerów LXC i maszyn wirtualnych w sposób powtarzalny,
  • zarządzanie template systemów operacyjnych,
  • pełną kontrolę konfiguracji przez Git,
  • integrację z Vault w zakresie sekretów,
  • eliminację ręcznej konfiguracji przez interfejs graficzny.

Dlaczego LXC zamiast klasycznych maszyn wirtualnych?

Kontenery LXC są w tym projekcie podstawowym mechanizmem uruchamiania usług, ponieważ:

  • uruchamiają się w kilka sekund,

  • zużywają znacznie mniej zasobów niż VM,

  • nie wymagają osobnego jądra systemu,

  • idealnie sprawdzają się dla:

    • mikroserwisów,
    • reverse proxy,
    • workerów CI,
    • systemów backendowych.

Maszyny wirtualne są stosowane wyłącznie tam, gdzie:

  • wymagane jest osobne jądro,
  • potrzebna jest pełna izolacja sprzętowa.

5. Struktura projektu iac-proxmox

Uproszczona struktura repozytorium:

iac-proxmox/
├── containers_templates/   # Szablony LXC
├── machines/               # Definicje kontenerów LXC i VM (ctXXXXX.tf)
├── _locals.tf              # Wspólne zmienne (storage, node, pool)
└── main.tf

Integracja z Vault

Projekt iac-proxmox jest w pełni zintegrowany z Vault, który przechowuje m.in.:

  • hasła root,
  • dane użytkowników technicznych,
  • klucze SSH,
  • adresy IP.

Dzięki temu:

  • ❌ dane dostępowe nie trafiają do repozytorium,
  • ✅ możliwa jest rotacja sekretów,
  • ✅ dostęp do infrastruktury jest audytowalny.

1.3.1 - Pobieranie template LXC

Pobieranie template LXC

Instrukcja pobrania szablonu LXC oraz jego wykorzystania do utworzenia kontenera w projekcie iac-proxmox przy użyciu modułu proxmox-container.


1. Cel i kontekst

Szablony LXC (templates) w środowisku Proxmox VE są wykorzystywane do szybkiego i powtarzalnego tworzenia kontenerów systemowych. W projekcie iac-proxmox za pobieranie oraz utrzymanie tych szablonów odpowiada dedykowany katalog:

./containers_templates/

Zasoby zdefiniowane w tym katalogu:

  • automatycznie pobierają obrazy kontenerów,
  • zapisują je w magazynie danych Proxmoxa,
  • udostępniają je do dalszego użycia przez moduł proxmox-container.

2. Pobranie szablonu LXC

Poniższy zasób odpowiada za pobranie oficjalnego szablonu Ubuntu 24.04 LTS bezpośrednio z repozytorium Proxmoxa:

resource "proxmox_virtual_environment_download_file" "ubuntu24-10" {
  content_type       = "vztmpl"
  datastore_id       = local.storage_name
  node_name          = local.default_node
  file_name          = "ubuntu-24.04.tar.zst"
  url                = "http://download.proxmox.com/images/system/ubuntu-24.04-standard_24.04-2_amd64.tar.zst"
  checksum           = "4030982618eeae70854e8f9711adbd09"
  checksum_algorithm = "md5"
}

3. Omówienie parametrów zasobu

Parametr Opis
content_type Typ pobieranego pliku — vztmpl oznacza szablon LXC
datastore_id Magazyn danych w Proxmoxie (np. local, local-lvm, ceph)
node_name Nazwa noda Proxmoxa, na którym ma zostać zapisany template
file_name Nazwa pliku po zapisaniu w repozytorium template
url Bezpośredni adres oficjalnego szablonu
checksum Suma kontrolna pliku
checksum_algorithm Algorytm weryfikacji integralności (md5, sha256)

✅ Dzięki zastosowaniu checksum OpenTofu weryfikuje, czy pobrany plik nie został uszkodzony.


4. Zmienne lokalne wykorzystywane w zasobie

Zmienna local.storage_name oraz local.default_node są zwykle zdefiniowane w pliku:

locals.tf

Przykładowa definicja:

locals {
  storage_name = "local"
  default_node = "proxmox-1"
}

✅ Takie podejście zapewnia:

  • centralne zarządzanie konfiguracją,
  • łatwą migrację między środowiskami,
  • brak twardo zakodowanych nazw w zasobach.

5. Zależność od modułu proxmox-container

Po pobraniu szablonu, może on zostać wykorzystany w module:

modules/proxmox-container

Przykład użycia template w definicji kontenera:

template = "local:vztmpl/ubuntu-24.04.tar.zst"

Moduł proxmox-container wykorzystuje ten template do:

  • utworzenia systemu plików kontenera,
  • konfiguracji sieci,
  • ustawienia użytkowników,
  • przypisania zasobów CPU i RAM.

1.3.2 - Kontener LXC

Kontener LXC

LXC (Linux Containers) to technologia lekkiej wirtualizacji na poziomie systemu operacyjnego, umożliwiająca uruchamianie wielu odseparowanych środowisk Linux na jednym jądrze systemowym.

W przeciwieństwie do klasycznych maszyn wirtualnych:

  • nie emuluje pełnego sprzętu,
  • nie wymaga osobnego jądra systemu,
  • zużywa znacznie mniej zasobów,
  • uruchamia się niemal natychmiastowo.

W środowisku Proxmox VE kontenery LXC są wykorzystywane do:

  • uruchamiania mikroserwisów,
  • hostowania aplikacji backendowych,
  • serwerów proxy, API, workerów CI,
  • środowisk testowych i stagingowych.

✅ LXC to rozwiązanie:

  • szybsze niż VM,
  • tańsze zasobowo,
  • idealne do infrastruktury jako kod (IaC).

1. Rola kontenerów LXC w iac-proxmox

W projekcie iac-proxmox kontenery LXC są:

  • w pełni zarządzane przez OpenTofu,
  • tworzone automatycznie z gotowych template,
  • konfigurowane przez moduł:
modules/proxmox-container

Każdy kontener posiada:

  • jednoznaczny CT ID,
  • przypisany node, storage, pool,
  • zdefiniowane zasoby CPU, RAM i dysk,
  • użytkownika technicznego,
  • klucz SSH.

2. Struktura katalogów dla kontenerów

Definicje kontenerów znajdują się w katalogu:

./machines/

Każdy kontener posiada osobny plik:

ctXXXXX.tf

Przykład:

ct01011.tf

✅ Zapewnia to:

  • czytelność,
  • pełną niezależność kontenerów,
  • łatwą kontrolę zmian w Git.

3. Tworzenie kontenera LXC

module "ct01011" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-container.git?ref=v1.0.0"

  hostname      = "ct01011.rachuna-net.pl"
  description   = "example-service"
  node_name     = "pve-s1"
  ct_id         = 1011
  pool_id       = "web-proxy"
  start_on_boot = true
  tags          = ["example", "ubuntu"]

  cpu_cores = 2
  memory = { dedicated = 2048, swap = 1024 }
  disk   = { storage_name = "local-lvm", disk_size = 32 }

  operating_system = {
    template_file = "local:vztmpl/ubuntu-24.04.tar.zst"
    type          = "ubuntu"
  }

  user_account = {
    username       = "techuser"
    password       = "change-me"
    public_ssh_key = "ssh-ed25519 AAAA..."
  }
}

4. Omówienie kluczowych parametrów

4.1. Identyfikacja i lokalizacja

Parametr Opis
hostname Pełna nazwa DNS kontenera
description Opis techniczny usługi
node_name Węzeł Proxmoxa
ct_id Unikalne ID kontenera
pool_id Pool logiczny
start_on_boot Autostart po restarcie
tags Tagi administracyjne

4.2. Zasoby sprzętowe

cpu_cores = 2

memory = {
  dedicated = 2048
  swap      = 1024
}

disk = {
  storage_name = "local-lvm"
  disk_size    = 32
}

✅ Pozwala to precyzyjnie sterować:

  • obciążeniem hosta,
  • wydajnością usług,
  • dynamicznym skalowaniem.

4.3. System operacyjny

operating_system = {
  template_file = "local:vztmpl/ubuntu-24.04.tar.zst"
  type          = "ubuntu"
}

✅ Template musi być:

  • wcześniej pobrany przez containers_templates,
  • dostępny na storage Proxmoxa.

4.4. Konto użytkownika

user_account = {
  username       = "techuser"
  password       = "change-me"
  public_ssh_key = "ssh-ed25519 AAAA..."
}

✅ Tworzone automatycznie:

  • konto techniczne,
  • dostęp SSH,
  • możliwość wyłączenia logowania root.

5. Integracja z Vault

Jeżeli dane dostępowe pochodzą z Vault, zamiast jawnych wartości:

user_account = {
  username       = data.vault_kv_secret_v2.ct.data["username"]
  password       = data.vault_kv_secret_v2.ct.data["password"]
  public_ssh_key = data.vault_kv_secret_v2.ct.data["ssh_key"]
}

✅ Pozwala to:

  • usunąć hasła z repozytorium,
  • rotować dane dostępowe,
  • centralnie kontrolować dostęp.

1.3.3 - Virtual Machine

Maszyny wirtualne

Wirtualna maszyna (VM, Virtual Machine) to programowe odwzorowanie fizycznego komputera, które działa w ramach istniejącego systemu lub bezpośrednio na hyperwizorze. Posiada własny system operacyjny, przydzielone zasoby (CPU, pamięć RAM, dysk, sieć) i jest odizolowana od innych maszyn działających na tym samym hoście. Dzięki wirtualizacji możliwe jest uruchamianie wielu niezależnych środowisk na jednej fizycznej infrastrukturze, co zwiększa efektywność wykorzystania zasobów, ułatwia zarządzanie oraz podnosi bezpieczeństwo i elastyczność środowisk IT.


1. Struktura katalogów dla kontenerów

Definicje vm znajdują się w katalogu:

./machines/

Każdy vm posiada osobny plik:

vmXXXXX.tf

Przykład:

vm01011.tf

✅ Zapewnia to:

  • czytelność,
  • pełną niezależność kontenerów,
  • łatwą kontrolę zmian w Git.

2. Tworzenie VM

module "vm01017" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-vm.git?ref=v1.0.0"

  hostname      = "vm01017.rachuna-net.pl"
  description   = "Kubernetes master w4"
  node_name     = "pve-s1"
  vm_id         = 1017
  pool_id       = "kubernetes"
  protection    = true
  tags          = ["kubernetes", "master", "ubuntu"]
  is_dmz        = false
  mac_address   = "BC:24:11:50:5F:83"
  datastore_id  = "storage.rachuna-net.pl"

  template = {
    node_name = "pve-s1"
    vm_id     = 901
    full      = true
  }

  cpu = {
    cores   = 4
    sockets = 2
  }

  memory = {
    dedicated = 8192
  }

  user_account = {
    username       = data.vault_kv_secret_v2.auth_techuser.data["username"]
    password       = data.vault_kv_secret_v2.auth_techuser.data["password"]
    public_ssh_key = data.vault_kv_secret_v2.auth_techuser.data["public_ssh_key"]
  }

  vault = {
    mount = "kv-gitlab"
    path  = "pl.rachuna-net/infrastructure/opentofu/iac-proxmox/machine/vm01017"
  }
}
  • source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-vm.git?ref=v1.0.0" - Źródło modułu.
  • hostname – pełna nazwa FQDN VM.
  • description – krótki opis roli serwera (widzoczny w Proxmox).
  • node_name – węzeł Proxmox, na którym VM ma być tworzona (pve-s1, pve-s2, pve-s3, …).
  • vm_id – unikalny ID VM w klastrze (sprawdź, czy numer nie jest zajęty).
  • pool_id – pula Proxmox (np. kubernetes), ustaw zgodnie z przeznaczeniem.
  • protection – zwykle true dla ochrony przed przypadkowym usunięciem.
  • tags – lista tagów (rola, system, np. ["kubernetes", "master", "ubuntu"]).
  • is_dmztrue/false zależnie od strefy sieci.
  • mac_address – statyczny MAC (zapewnij unikalność w sieci).
  • datastore_id – magazyn na dyski (obecnie storage.rachuna-net.pl jak w istniejących VM).

2.1. Sekcje template, cpu, memory

  • template – wskaż template VM (aktualnie wykorzystywany jest vm_id = 901 na pve-s1 z kopią pełną: full = true).
  • cpu – ustaw liczbę rdzeni (cores) i gniazd (sockets).
  • memorydedicated w MB (np. 8192).

2.2. Dostępy i sekrety

  • user_account pobiera dane użytkownika technicznego z Vault: data.vault_kv_secret_v2.auth_techuser.data[...] – upewnij się, że wpis istnieje (definicja w machines/_data.tf).
  • vault – ustaw ścieżkę na sekrety specyficzne dla VM, zgodnie z konwencją pl.rachuna-net/infrastructure/opentofu/iac-proxmox/machine/vmNNNNN (zaktualizuj numer).

3. Integracja z Vault

Jeżeli dane dostępowe pochodzą z Vault, zamiast jawnych wartości:

user_account = {
  username       = data.vault_kv_secret_v2.ct.data["username"]
  password       = data.vault_kv_secret_v2.ct.data["password"]
  public_ssh_key = data.vault_kv_secret_v2.ct.data["ssh_key"]
}

✅ Pozwala to:

  • usunąć hasła z repozytorium,
  • rotować dane dostępowe,
  • centralnie kontrolować dostęp.

1.4 - iac-mikrotik

IAC do zarządzania routerami MikroTik przy użyciu OpenTofu.

Repozytorium: iac-mikrotik

Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą automatyczne, deklaratywne zarządzanie konfiguracją routerów MikroTik działających na systemie RouterOS przy użyciu OpenTofu.

Projekt umożliwia:

  • pełne zarządzanie warstwą L2/L3 w sposób deklaratywny,
  • automatyzację konfiguracji interfejsów, VLAN, bridge oraz bondingu (LACP),
  • centralne zarządzanie serwerami DHCP i DNS,
  • utrzymanie statycznych rekordów DNS dla infrastruktury krytycznej,
  • eliminację ręcznej konfiguracji przez interfejs graficzny RouterOS,
  • wersjonowanie, audyt oraz szybki rollback zmian przez Git.

Cel projektu iac-mikrotik

Celem projektu jest zbudowanie spójnego, audytowalnego i w pełni zautomatyzowanego modelu zarządzania konfiguracją sieciową, obejmującego:

  • routing,
  • switching,
  • adresację IP,
  • segmentację VLAN,
  • serwery DHCP,
  • centralny resolver DNS.

Projekt stanowi fundament całej warstwy sieciowej dla środowisk:

  • Proxmox,
  • usług serwerowych,
  • środowisk developerskich,
  • sieci Wi-Fi,
  • stref DMZ i management.

Zakres dokumentacji

Dokumentacja obejmuje pełen cykl życia konfiguracji RouterOS:

  • Interfaces – Ethernet, Bonding (LACP), Bridge, VLAN (każdy typ jako osobny moduł i katalog konfiguracyjny),

  • Serwery DHCP – sieci, pule adresowe, serwery DHCP, statyczne rezerwacje, integracja z DNS,

  • Serwer DNS – centralny resolver, cache, parametry upstream, bezpieczeństwo,

  • Rekordy DNS – statyczne wpisy:

    • A, AAAA,
    • CNAME,
    • TXT,
    • MX,
    • NS, utrzymywane centralnie w mapie dns_records.

Struktura katalogów w repozytorium

Uproszczona struktura projektu:

router.rachuna-net.pl/
├── interfaces/         # ethernet, bonding, bridge, vlan (*.tf)
├── dhcp-servers/       # każdy serwer DHCP w osobnym pliku
├── dns-server/         # main.tf z konfiguracją resolvera
└── dns-records/        # mapa statycznych rekordów DNS

Zasady organizacyjne:

  • ✅ jeden plik = jeden element logiczny,
  • ✅ brak plików „kombajnów”,
  • ✅ pełna czytelność konfiguracji,
  • ✅ jednoznaczne mapowanie kod → element infrastruktury.

Moduły OpenTofu wykorzystywane w projekcie

Warstwa interfejsów:

  • routeros-ethernet
  • routeros-bonding
  • routeros-bridge
  • routeros-vlan

Warstwa usług IP:

  • routeros-dhcp-server – sieci, pule, serwery DHCP oraz statyczne leases,
  • routeros-dns – resolver, cache, serwery upstream oraz statyczne dns_records.

Każdy moduł odpowiada za jedną, ściśle określoną funkcję logiczną, co umożliwia:

  • precyzyjny audyt zmian,
  • łatwą rozbudowę,
  • bezpieczny rollback.

Kolejność wdrażania konfiguracji

Zalecana kolejność wdrożeń w iac-mikrotik:

  1. Interfaces Ethernet → Bonding → Bridge → VLAN
  2. Serwery DHCP Na gotowych interfejsach L3
  3. Serwer DNS Resolver + cache
  4. Rekordy DNS Statyczne wpisy dla infrastruktury krytycznej

Taka kolejność eliminuje błędy zależności między warstwami.


Wspólne zasady projektowe

  • Zero konfiguracji w GUI – całość wyłącznie przez IaC,
  • Jeden moduł = jedna funkcja logiczna,
  • DHCP zawsze wskazuje lokalny DNS,
  • Krytyczne hosty zawsze posiadają statyczne rekordy DNS,
  • Każda zmiana przechodzi przez Git (review, audyt, rollback),
  • ❌ Brak ręcznych modyfikacji w RouterOS,
  • ❌ Brak przechowywania konfiguracji poza repozytorium.

1.4.1 - Konfiguracja Interfaces

Konfiguracja Interfaces

Dokumentacja opisuje zarządzanie interfejsami sieciowymi w routerach MikroTik z wykorzystaniem RouterOS oraz OpenTofu w podejściu Infrastructure as Code (IaC).

Celem tej sekcji jest ujednolicenie oraz pełna automatyzacja konfiguracji interfejsów sieciowych w infrastrukturze RouterOS. Dokumentacja obejmuje:

  • porty Ethernet,
  • interfejsy Bonding (LACP),
  • mosty logiczne Bridge,
  • sieci wirtualne VLAN.

Każdy typ interfejsu:

  • jest zarządzany przez dedykowany moduł OpenTofu,
  • posiada własny katalog konfiguracyjny,
  • może być wersjonowany i audytowany w systemie kontroli wersji.

1. Struktura katalogów

Konfiguracja interfejsów znajduje się w:

router.rachuna-net.pl/interfaces/
├── ethernet/
├── bonding/
├── bridge/
└── vlan/

Zasada organizacyjna:

✅ jeden plik = jedna logiczna konfiguracja ✅ brak konfiguracji w GUI ✅ pełna powtarzalność konfiguracji


2. Konfiguracja Ethernet

Pliki znajdują się w:

router.rachuna-net.pl/interfaces/ethernet/*.tf

Przykładowa konfiguracja

module "ethernet_ether1" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-ethernet.git?ref=v1.0.0"

  name         = "ether1"
  mtu          = 1500
  arp          = "enabled"
  poe_out      = "off"
  disabled     = false
  dhcp_client  = false
  addresses    = ["192.0.2.1/24"]  # lub puste, jeśli tylko do bridge/bonding
}

Znaczenie parametrów

Parametr Opis
name Nazwa fizycznego portu
mtu Rozmiar ramki
arp Obsługa ARP
poe_out Zasilanie PoE
disabled Włączenie/wyłączenie portu
dhcp_client Czy uruchomić klienta DHCP
addresses Adresy IP przypisane do portu

3. Bonding – agregacja łączy (LACP)

Pliki znajdują się w:

interfaces/bonding/*.tf

Przykład (tryb LACP – 802.3ad):

module "bonding_storage" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-bonding.git?ref=v1.0.0"

  name      = "bond-storage"
  mode      = "802.3ad"
  slaves    = ["ether2", "ether3"]
  lacp_rate = "1sec"
  arp       = "enabled"
  comment   = "storage uplink"
}

Znaczenie parametrów

Parametr Opis
name Nazwa interfejsu logicznego
mode Tryb pracy (np. 802.3ad)
slaves Lista portów fizycznych
lacp_rate Częstotliwość LACP
arp Obsługa ARP
comment Opis administracyjny

4. Bridge

Pliki znajdują się w:

interfaces/bridge/*.tf

Przykład:

module "bridge_clients" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-bridge.git?ref=v1.0.0"

  name     = "br-clients"
  comment  = "bridge klientów"
  ageing   = 300
  protocol_mode = "rstp"
  ports = [
    { interface = "ether4", pvid = 10 },
    { interface = "ether5", pvid = 10 }
  ]
}

Znaczenie parametrów

Parametr Opis
name Nazwa bridge
comment Opis
ageing Czas życia wpisów MAC
protocol_mode Tryb STP
ports Lista portów wraz z PVID

4. VLAN – sieci logiczne

Pliki znajdują się w:

interfaces/vlan/*.tf

Przykład:

module "vlan_vms_internal" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-vlan.git?ref=v1.0.0"

  name        = "vlan-vms-int"
  interface   = "bond-storage"   # trunk/bond/ether/bridge
  vlan_id     = 20
  arp         = "enabled"
  mtu         = 1500
  loop_protect = false
  comment     = "VLAN VMs internal"
}

Znaczenie parametrów

Parametr Opis
name Nazwa interfejsu VLAN
interface Interfejs nadrzędny
vlan_id Identyfikator VLAN
arp Obsługa ARP
mtu MTU
loop_protect Ochrona przed pętlą
comment Opis sieci

5. Kolejność wdrażania konfiguracji

Zalecana kolejność:

  1. Ethernet
  2. Bonding
  3. Bridge
  4. VLAN

Zapobiega to błędom zależności i brakującym interfejsom

1.4.2 - Serwery DHCP

Konfiguracja Serwerów DHCP

DHCP (Dynamic Host Configuration Protocol) to protokół sieciowy działający w warstwie L3 modelu OSI, którego celem jest automatyczne przydzielanie parametrów sieciowych hostom, takich jak:

  • adres IP,
  • maska podsieci,
  • adres bramy (gateway),
  • serwery DNS,
  • domena wyszukiwania,
  • czas dzierżawy adresu (lease time).

Architektura serwera DHCP w projekcie iac-mikrotik

Konfiguracja DHCP składa się z kilku warstw logicznych:

  1. Interfejs L3, na którym działa DHCP (np. BRIDGE-PROXMOX lub interfejs VLAN)

  2. Sieć DHCP (dhcp_network) definiuje:

    • adresację,
    • bramę,
    • serwery DNS,
    • domenę.
  3. Pula adresowa (address_pools) zakresy IP do automatycznego przydziału.

  4. Serwer DHCP (dhcp-server) instancja działająca na wybranym interfejsie.

  5. Leases (dhcp_leases) statyczne rezerwacje IP na podstawie MAC.


Struktura plików

Konfiguracja DHCP znajduje się w katalogu:

router.rachuna-net.pl/dhcp-servers/*.tf

Każdy serwer DHCP powinien być definiowany w osobnym pliku.

Zalety:

  • wersjonowanie każdej podsieci,
  • audyt zmian,
  • możliwość rollback,
  • czysta i modularna struktura projektu.

Przykład konfiguracji serwera DHCP

Poniżej pełen przykład wdrożenia serwera DHCP dla sieci Proxmox:

module "dhcp-proxmox" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-dhcp-server.git?ref=v1.0.0"

  name         = "DHCP-PROXMOX"
  comment      = "DHCP server for PROXMOX"
  address_pool = "PROXMOX-POOLS"
  interface    = "BRIDGE-PROXMOX"
  lease_time   = "12h"

  dhcp_network = {
    address    = "10.3.0.0/24"
    gateway    = "10.3.0.1"
    dns_server = ["10.3.0.1"]
    domain     = "rachuna-net.pl"
    comment    = "proxmox network"
  }

  address_pools = {
    "PROXMOX-POOLS" = {
      ranges  = ["10.3.0.11-10.3.0.14"]
      comment = "proxmox pool"
    }
  }

  dhcp_leases = {
    "10.3.0.11" = {
      hostname    = "pve-s1.rachuna-net.pl"
      comment     = "pve-s1.rachuna-net.pl"
      mac_address = "38:05:25:33:B8:49"
      server      = "DHCP-PROXMOX"
      disabled    = false
    }
    "10.3.0.12" = {
      hostname    = "pve-s2.rachuna-net.pl"
      comment     = "pve-s2.rachuna-net.pl"
      mac_address = "D8:5E:D3:6B:3F:0C"
      server      = "DHCP-PROXMOX"
      disabled    = false
    }
    "10.3.0.13" = {
      hostname    = "pve-s3.rachuna-net.pl"
      comment     = "pve-s3.rachuna-net.pl"
      mac_address = "18:C0:4D:8C:4F:5E"
      server      = "DHCP-PROXMOX"
      disabled    = false
    }
  }
}

Omówienie parametrów technicznych

5.1. Parametry serwera DHCP

Parametr Znaczenie
name Nazwa instancji serwera DHCP
comment Opis techniczny
address_pool Nazwa puli adresowej używanej przez serwer
interface Interfejs, na którym działa DHCP (bridge lub VLAN)
lease_time Czas ważności wydawanej dzierżawy IP

5.2. Sieć DHCP

Sekcja dhcp_network jest kluczowa – definiuje parametry, które klient otrzyma w komunikacie DHCP OFFER:

Parametr Opis
address Zakres sieci (subnet)
gateway Brama (router)
dns_server Lista serwerów DNS
domain Domena dla FQDN
comment Opis

5.3. Pula adresowa (dynamiczne przydzielanie IP)

Parametr Opis
ranges Zakresy IP do automatycznego przydzielania
comment Opis techniczny puli

Każda pula posiada nazwę klucza — np.:

"PROXMOX-POOLS"

5.4. Leases (statyczne przypisania)

Zalecane w serwerowniach, hypervisorach, NAS, firewallach.

Parametr Opis
hostname Nazwa klienta
mac_address Adres MAC urządzenia
server Instancja DHCP, która będzie zarządzać lease
disabled Włączenie/wyłączenie rezerwacji

Zasady projektowe i dobre praktyki

1. Ogólne zasady

  • Każda podsieć = osobny moduł DHCP
  • DHCP musi działać tylko na interfejsach L3
  • Nigdy nie mieszaj DHCP z adresacją statyczną w tej samej puli
  • Węzły Proxmox, Routery, Nas’y – zawsze na statycznych lease

2. Bezpieczeństwo

  • DHCP powinien działać tylko w zaufanych segmentach sieci.

  • Zalecane filtrowanie:

    • DHCP snooping na switchach,
    • blokada rogue DHCP serwerów.

3. Integracja z DNS

W RouterOS serwer DHCP może dynamicznie rejestrować hosty w DNS. Pole hostname w lease jest automatycznie używane do:

  • zapisu rekordów A,
  • aktualizacji rekordów PTR.

Typowe błędy i jak ich unikać

Problem Przyczyna Rozwiązanie
Klient nie dostaje IP DHCP działa na złym interfejsie Upewnij się, że interfejs posiada IP i jest L3
IP spoza zakresu Nakładanie się pul Rozdziel pule dynamiczne i statyczne
Błędne DNS Nieprawidłowe wpisy dns_server Zastosuj lokalny DNS routera lub upstream
Lease się nie odświeża Zbyt krótki lease_time Zwiększ do 12–24h

Podsumowanie

Serwer DHCP w iac-mikrotik zapewnia:

  • deklaratywne, w pełni automatyczne zarządzanie adresacją,
  • wersjonowanie zmian w Git,
  • spójność konfiguracji RouterOS,
  • łatwe wdrażanie i modyfikowanie pul IP,
  • centralne rezerwacje dla serwerów i hostów krytycznych.

1.4.3 - Serwer DNS

Konfiguracja Serwera DNS

DNS (Domain Name System) to podstawowy mechanizm infrastruktury sieciowej odpowiedzialny za zamianę nazw domenowych na adresy IP (forward lookup) oraz adresów IP na nazwy domenowe (reverse lookup – rekordy PTR). W projekcie iac-mikrotik serwer DNS oparty jest o resolver systemu RouterOS i zarządzany deklaratywnie przy użyciu OpenTofu.


Struktura plików

Konfiguracja DNS znajduje się w katalogu:

router.rachuna-net.pl/dns-server/main.tf

Zalety takiego podejścia:

  • centralne zarządzanie resolverem,
  • wersjonowanie konfiguracji,
  • szybki rollback,
  • spójność dla całego środowiska.

Przykład konfiguracji serwera DNS

module "dns_server" {
  source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-dns.git?ref=v1.0.0"

  allow_remote_requests   = true
  cache_max_ttl           = "1d"
  max_concurrent_queries  = 1000
  servers                 = ["1.1.1.1", "8.8.8.8"]
  dynamic_servers         = []
  comment                 = "DNS resolver/router"
}

Omówienie parametrów technicznych

1. Parametry instancji serwera DNS

Parametr Znaczenie
allow_remote_requests Zezwala klientom sieciowym na korzystanie z resolvera
cache_max_ttl Maksymalny czas przechowywania odpowiedzi w cache
max_concurrent_queries Limit równoległych zapytań DNS
servers Lista serwerów DNS upstream
dynamic_servers Serwery DNS pobierane dynamicznie (np. z DHCP ISP)
comment Opis administracyjny

2. Rola cache DNS

Mechanizm cache:

  • znacząco redukuje liczbę zapytań wychodzących,
  • poprawia wydajność sieci,
  • zwiększa odporność na chwilowe awarie upstream.

W konfiguracji:

cache_max_ttl = "1d"

oznacza, że odpowiedzi mogą być przechowywane przez maksymalnie 24 godziny.


3. Serwery upstream

servers = ["1.1.1.1", "8.8.8.8"]

Oznacza to wykorzystanie:

  • **Cloudflare DNS – 1.1.1.1,
  • **Google DNS – 8.8.8.8.

Zastosowanie co najmniej dwóch niezależnych operatorów DNS zwiększa odporność na awarie.


Integracja DNS z DHCP

W projekcie iac-mikrotik DNS jest bezpośrednio powiązany z DHCP:

  • każdy lease z hostname,

  • automatycznie tworzy:

    • rekord A,
    • rekord PTR,
  • umożliwia rozwiązywanie nazw lokalnych:

pve-s1.rachuna-net.pl → 10.3.0.11
10.3.0.11 → pve-s1.rachuna-net.pl

Dzięki temu:

  • hosty są widoczne po nazwach,
  • działa poprawnie Kerberos, LDAP, TLS, monitoring, HA Proxmox.

Zasady projektowe i dobre praktyki

1. Ogólne zasady

  • Jeden centralny resolver DNS dla całej infrastruktury
  • DNS zawsze wskazywany przez DHCP
  • DNS zawsze działa na routerze brzegowym
  • Brak konfiguracji DNS bezpośrednio na hostach

2. Bezpieczeństwo

  • allow_remote_requests powinien być:

    • włączony tylko dla sieci zaufanych,
  • brak otwartego DNS do Internetu,

  • firewall powinien blokować:

    • zapytania DNS spoza infrastruktury.

3. Spójność DNS i TLS

  • Każdy host produkcyjny powinien posiadać:

    • rekord A,
    • rekord PTR,
  • Brak PTR = problemy z:

    • pocztą,
    • certyfikatami,
    • monitoringiem,
    • logami.

Typowe błędy i jak ich unikać

Problem Przyczyna Rozwiązanie
DNS nie odpowiada allow_remote_requests = false Ustaw na true
Brak internetu mimo IP Brak upstream DNS Ustaw servers
Brak PTR Brak integracji z DHCP Używaj hostname w lease
Timeouty DNS Zbyt niski max_concurrent_queries Zwiększ limit

Podsumowanie

Serwer DNS w iac-mikrotik zapewnia:

  • centralny, cache’ujący resolver,
  • dynamiczne rekordy A i PTR z DHCP,
  • wysoką wydajność dzięki cache,
  • pełną deklaratywność w IaC,
  • brak ręcznej konfiguracji RouterOS,
  • spójność nazw w całym środowisku IT.

Jeżeli chcesz, mogę dodatkowo przygotować:

  • dokumentację rekordów statycznych DNS (A, CNAME, TXT),
  • integrację DNS z Vault PKI,
  • model DNS dla Proxmox + Kubernetes + Wi-Fi + DMZ,
  • checklistę audytową DNS pod bezpieczeństwo.

1.4.4 - Rekord DNS

Konfiguracja Rekordów DNS

Oprócz działania jako resolver i cache, serwer DNS w RouterOS może również pełnić rolę lokalnego, autorytatywnego serwera rekordów statycznych dla domeny wewnętrznej. W projekcie iac-mikrotik realizowane jest to poprzez mapę dns_records w module routeros-dns.

Rekordy te są:

  • w pełni zarządzane przez IaC,
  • wersjonowane w Git,
  • niezależne od DHCP,
  • odporne na restart routera,
  • wykorzystywane przez TLS, monitoring, reverse proxy, klastry i routing.

Struktura dns_records

Rekordy DNS definiowane są jako mapa rekordów, gdzie:

  • klucz mapy = identyfikator rekordu,
  • wartość = pełna definicja wpisu DNS.

Przykład konfiguracji:

dns_records = {
  "router.rachuna-net.pl" = {
    name    = "router.rachuna-net.pl"
    address = "10.0.0.1"
    type    = "A"
    ttl     = "1w"
    comment = "Router IP address"
  }
}

Omówienie parametrów rekordu DNS

Parametr Znaczenie techniczne
name Pełna nazwa hosta (FQDN)
address Adres IP powiązany z nazwą
type Typ rekordu DNS (najczęściej A)
ttl Czas życia rekordu w cache
comment Opis administracyjny

Obsługiwane typy rekordów (praktyczne zastosowanie)

Typ Zastosowanie
A Mapowanie nazwa → IPv4
AAAA Mapowanie nazwa → IPv6
CNAME Alias do innej nazwy
TXT SPF, DKIM, weryfikacje
MX Serwery poczty
NS Delegacja stref

Przykład rekordu aliasu:

"dns.rachuna-net.pl" = {
  name    = "dns.rachuna-net.pl"
  address = "router.rachuna-net.pl"
  type    = "CNAME"
  ttl     = "1d"
  comment = "Alias for router DNS"
}

Rola rekordów statycznych vs DHCP

Źródło rekordu Przeznaczenie
DHCP (dynamiczne) Laptopy, VM, urządzenia tymczasowe
dns_records (statyczne) Routery, load balancery, proxmoxy, serwery, usługi infrastrukturalne

Zasada infrastrukturalna:

Każdy element krytyczny infrastruktury powinien posiadać rekord statyczny, a nie tylko dynamiczny z DHCP.


TTL – znaczenie w praktyce

TTL Zastosowanie
1h Sieci testowe
1d Standard produkcyjny
1w Routery, klastry, infrastruktura krytyczna

U Ciebie:

ttl = "1w"

oznacza, że:

  • cache DNS będzie przechowywał wpis nawet przez 7 dni,
  • zmiany IP wymagają ręcznego odświeżenia cache,
  • idealne dla infrastruktury stałej (router, core).

Powiązanie z TLS, monitoringiem i reverse proxy

Statyczne rekordy DNS są wykorzystywane bezpośrednio przez:

  • certyfikaty TLS (Vault PKI, ACME),
  • monitoring (Prometheus, Zabbix, Grafana),
  • reverse proxy (Nginx, Traefik),
  • klastry (Proxmox, Kubernetes).

Brak statycznego DNS powoduje:

  • niestabilność certyfikatów,
  • błędy monitoringu,
  • problemy z HA i load balancingiem.

Typowe błędy i jak ich unikać

Problem Przyczyna Rozwiązanie
Rekord nie działa Błędna nazwa w name Tylko FQDN
Brak rozwiązywania DNS nie jest ustawiony przez DHCP Sprawdź dns_server
Stara odpowiedź DNS Zbyt długi TTL Zmniejsz TTL i wyczyść cache
Konflikt nazwy Istnieje rekord dynamiczny Usuń dynamiczny lub zmień nazwę

Podsumowanie sekcji dns_records

Sekcja dns_records w iac-mikrotik zapewnia:

  • centralne, statyczne wpisy DNS,
  • pełną kontrolę nad infrastrukturą nazw,
  • powtarzalność wdrożeń,
  • brak ręcznej edycji RouterOS,
  • kompatybilność z TLS, DHCP, monitoringiem i proxy,
  • spójność nazw w całym ekosystemie IT.

1.5 - Integracja z projektem gitlab

Integracja z projektem gitlab

Terraform State to mechanizm w Terraformie, który przechowuje aktualny stan zarządzanej infrastruktury. Jest to plik (domyślnie terraform.tfstate), w którym Terraform zapisuje informacje o zasobach, ich konfiguracji oraz zależnościach. Dzięki temu Terraform może:

  1. Śledzić zmiany – porównuje aktualną infrastrukturę ze skonfigurowaną w kodzie, identyfikując różnice.
  2. Optymalizować działania – wie, które zasoby wymagają zmiany, zamiast tworzyć je od nowa.
  3. Zarządzać zależnościami – rozumie, w jakiej kolejności tworzyć, aktualizować lub usuwać zasoby.
  4. Współdzielić stan – umożliwia pracę zespołową poprzez zdalne przechowywanie stanu w backendach takich jak S3, GitLab czy Terraform Cloud.

Zarządzanie stanem jest kluczowe, dlatego warto używać zdalnego backendu zamiast przechowywać terraform.tfstate lokalnie, szczególnie w środowiskach zespołowych.


Ustawienie terraform state w ustawieniach repozytorium

  terraform init \
  -backend-config="address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}" \
  -backend-config="lock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
  -backend-config="unlock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
  -backend-config="username=gitlab-ci-token" \
  -backend-config="password=${CI_JOB_TOKEN}" \
  -backend-config="lock_method=POST" \
  -backend-config="unlock_method=DELETE" \
  -backend-config="retry_wait_min=5"

dla OpenTofu

  tofu init \
  -backend-config="address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}" \
  -backend-config="lock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
  -backend-config="unlock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
  -backend-config="username=gitlab-ci-token" \
  -backend-config="password=${CI_JOB_TOKEN}" \
  -backend-config="lock_method=POST" \
  -backend-config="unlock_method=DELETE" \
  -backend-config="retry_wait_min=5"

gdzie:

  • CI_PROJECT_ID - id projektu w gitlab
  • CI_SERVER_URL - serwer URL
  • TF_STATE_NAME - nazwa instancji state

Terraform state z procesu CI1

1.6 - Importowanie obiektów

Importowanie istniejących obiektów

tofu Import – Co to jest i do czego służy?

tofu import to polecenie w OpenTofu, które umożliwia wprowadzenie istniejących zasobów do stanu (state) OpenTofu, bez konieczności ich tworzenia od zera. Jest to przydatne, gdy mamy zasoby zarządzane ręcznie lub przez inne narzędzia i chcemy przejąć nad nimi kontrolę za pomocą OpenTofu.

Do czego służy OpenTofu import?

  • Przejmowanie kontroli nad istniejącymi zasobami – jeśli masz już zasoby w chmurze (np. VM w AWS, projekt w GitLab, użytkowników w Azure), możesz je zaimportować do OpenTofu bez ich ponownego tworzenia.
  • Unikanie usuwania i ponownego tworzenia zasobów – jeśli ręcznie utworzony zasób nie znajduje się w stanie OpenTofu, ale istnieje, można go dodać do state, zamiast niszczyć i tworzyć od nowa.
  • Migracja do OpenTofu – jeśli zarządzałeś zasobami ręcznie lub przy pomocy innego narzędzia (np. Ansible, CloudFormation), możesz je przenieść do OpenTofu.

Przykłady importowanie obiektów

importowanie grupy gitlab

import {
  to = module.pl_rachuna-net.module.infrastructure.module.opentofu.module.group_modules.gitlab_group.group
  id = "100726684"
}

albo

tofu import module.pl_rachuna-net.module.infrastructure.module.opentofu.module.group_modules.gitlab_group.group 100726684

importowanie projektu gitlab

import {
    to = module.pl_rachuna-net.module.infrastructure.module.opentofu.module.modules.module.gitlab_group.gitlab_project.project
    id = "66189322"
}

albo

tofu import module.pl_rachuna-net.module.infrastructure.module.opentofu.module.modules.module.gitlab_group.gitlab_project.project 66189322

1.7 - Nadpisanie teraform states

Wysłanie opentofu state do gitlab
#!/bin/env bash

curl --request POST \
     --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
     --header "Content-Type: application/json" \
     --data-binary "@default.json" \
     "https://gitlab.com/api/v4/projects/${PRROJECT_ID}/terraform/state/${TF_STATE_NAME}"

1.8 - OpenTofu Modules

Moduły OpenTofu

Poniżej znajduje lista stworzonych modułów OpenTofu

Lista modułów Terraform

component version description
gitlab-group Zarządzanie grupą w GitLab
gitlab-project Zarządzanie projektem w GitLab
proxmox-container Moduł umożliwia automatyczne tworzenie i zarządzanie kontenerami LXC (CT) w środowisku Proxmox VE.
proxmox-vm Moduł umożliwia automatyczne tworzenie i zarządzanie kontenerami VM w środowisku Proxmox VE.
routeros-bonding Moduł OpenTofu do zarządzania interfejsami bonding na RouterOS.
routeros-bridge Moduł OpenTofu do zarządzania bridge na RouterOS.
routeros-dhcp-server Moduł OpenTofu do zarządzania serwerami dhcp na RouterOS.
routeros-dns Moduł OpenTofu do zarządzania serwerem DNS na urządzeniach RouterOS.
routeros-ethernet Moduł OpenTofu do zarządzania portami Ethernet na urządzeniach MikroTik RouterOS.
routeros-system Moduł, który ustawia i konfiguruje system RouterOS - Mikrotik.
routeros-vlan Moduł OpenTofu do zarządzania interfejsami VLAN na urządzeniach Mikrotik RouterOS.
vault-pki Zarządzanie pki w vault

2 - Packer

VM Template dla ProxMox

Packer to narzędzie do automatycznego budowania, instalacji systemu operacyjnego, konfiguracji jego według zdefiniowanych reguł i zapisania wyniku jako gotowy obraz do użycia.

Zamiast instalować system ręcznie, Packer wykonuje cały proces automatycznie: uruchamia maszynę, instaluje system operacyjny, konfiguruje go według zdefiniowanych reguł i zapisuje wynik jako gotowy obraz. Dzięki temu każdy wygenerowany template jest identyczny i możliwy do odtworzenia w dowolnym momencie.


Projekty Packer

projekt version description
alma Template Alma dla Proxmox generowany przez Packer
alpine Template Alpine dla Proxmox generowany przez Packer
ubuntu Template Ubuntu dla Proxmox generowany przez Packer

Instalacja szablonów

Konfiguracja w Vault

pl.rachuna-net/infrastructure/packer

{
  "SSH_PASSWORD": "techuser",
  "SSH_PUBLIC_KEY": "ssh-...",
  "SSH_USERNAME": "techuser"
}

pl.rachuna-net/auth/proxmox

{
  "DEFAULT_NODE": "pve-s1",
  "PASSWORD": "...",
  "USERNAME": "root@pam"
}

Skrypt instalacyjny

#!/usr/bin/env bash
### VAULT CONNECTION ###
export VAULT_TOKEN="hvs....."
export VAULT_ADDR="https://vault.rachuna-net.pl"

direnv allow
packer init .

for file in $(find pkrvars -type f -name "*.hcl"); do
    # Create a new vm template
    packer fmt -var-file=$file .
    packer validate -var-file=$file .
    packer build -var-file=$file .
done

3 - Ansible

IaC za pomocą Ansible

Opentofu to narzędzie typu Infrastructure as Code (IaC), które umożliwia definiowanie, provisionowanie i zarządzanie infrastrukturą za pomocą plików konfiguracyjnych. Dzięki temu narzędziu możesz w sposób deklaratywny opisywać zasoby, takie jak serwery, sieci czy usługi w chmurze, a następnie automatycznie je tworzyć, modyfikować i usuwać, zapewniając spójność środowisk.

Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.

Poniżej znajduje się lista projektów Infrastructure as a Code.

project version description
iac-gitlab IAC do zarządzania środowiskiem GitLab.
iac-vault IAC do zarządzania Vault.

Architektura projektu OpenTofu w pl.rachuna-net

# Przykładowy opis struktury projektu
pl.rachuna-net/infrastructure/opentofu
├── gitlab-profile                      # Documentation
├── home.rachuna-net.pl
├── iac-gitlab                          
├── iac-vault                          
├── modules                             # Opentofu modules
│   ├── gitlab-group                    # Opentofu module for menagment groups
│   ├── gitlab-project                  # Opentofu module for menagment projects
│   ├── proxmox-container
│   ├── proxmox-download-container
│   ├── proxmox-vm
│   ├── routeros-bonding
│   ├── routeros-bridge
│   ├── routeros-dhcp-server
│   ├── routeros-dns
│   ├── routeros-ethernet
│   ├── routeros-system
│   ├── routeros-vlan
│   ├── vault-pki-cert-ca
│   └── vault-pki-cert-intermediate
├── proxmox
└── router.rachuna-net.pl