/tf-flux

Primary LanguageHCL

Terraform + Flux

Репо містить приклад розгортання кластера для роботи kubot (https://github.com/Andygol/kubot.git)

Гілки

Гілка main містить код для розгортання кластера у GCP.

Для розгортання кластера локально з використанням kind, скористайтесь гілкою kind (https://github.com/Andygol/tf-flux/tree/kind)

Для явного вказання версії Kubernetes в Kind дивіться den-vasyliev/tf-kind-cluster#1 для внесення змін в модуль kind-cluster.

Порядок розгортання

  • Створіть файл terraform.tfvars (перейменуйте terraform.tfvars.example), вкажіть ваші значення для змінних

    github_owner = "username"
    github_token = "ghp_0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    repository_name = "flux-gitops"
    google_project  = "GCP project id"
  • tf init – ініціалізація, завантаження модулів

  • tf validate – перевірка конфігурації

  • tf apply – застосування конфігурації, розгортання кластера

Розгортання відбувається в автоматичному режимі за допомогою tf apply -auto-approve.

Під час розгортання виконується клонування репо flux-gitops, додавання до нього патчів та заворітнє надсилання патчів для подальшого їх застосування за допомогою FluxCD.

В кінці розгортання буде отримано контекст кластера, що дозволить безпосередньо перейти до отримання відомостей про його стан за допомогою kubectl та інших інструментів.

  • flux get all – перевірка наявності nodes
  • k cluster-info – відомості про кластер
  • flux check --pre – перевірка передумов для flux
  • k get ns – перевірка наявності потрібних namespace
  • flux logs -f – безперервний вивід логів

Кроки, виконання яких було додані до процесу розгортання

  • додавання в репо flux-gitops маніфест namespace для розгортання застосунку flux-gitops/clusters/kubot/ns.yaml; спостерігаємо за логами, щоб переконатись що маніфест було використано для створення namespace

    apiVersion: v1
    kind: Namespace
    metadata:
      name: kubot
  • Додавання маніфест GitRepository kubot-git-repository.yaml – flux create source git kubot --url=https://github.com/Andygol/kubot.git --branch=main --namespace=kubot --export 

    apiVersion: source.toolkit.fluxcd.io/v1
    kind: GitRepository
    metadata:
      name: kubot
      namespace: kubot
    spec:
      interval: 1m0s
      ref:
        branch: main
      url: https://github.com/Andygol/kubot.git
  • Додавання маніфесту HelmRelease kubot-helm-release.yaml – flux create helmrelease kubot --namespace kubot --source GitRepository/kubot --chart ./helm --interval 1m --export

    apiVersion: helm.toolkit.fluxcd.io/v2beta2
    kind: HelmRelease
    metadata:
      name: kubot
      namespace: kubot
    spec:
      chart:
        spec:
          chart: ./helm
          reconcileStrategy: ChartVersion
          sourceRef:
            kind: GitRepository
            name: kubot
      interval: 1m0s

Розвʼязання можливих проблем

  • У разі помилки застосування kubot-helm-release.yaml перевіримо версію API kubectl logs -n flux-system deployment/helm-controller | jq -r 'select(.source != null) | .source'

  • За потреби, змінимо версію v2beta2 --> v2beta1 в маніфесті kubot-helm-release.yaml

  • k get po -n kubot – перевірка створення поду 🫛

  • k describe pods -n kubot – інформація про под 🫛

  • … 🫛 под не запускається через відсутність токена для застосунку

  • tf destroy – розбираємо збірку, припиняємо роботу кластера

  • … далі буде

Що відбувається під капотом

Terraform використовуючи опис ресурсів розгортає кластер, а Flux (знаходиться в залежностях ресурсів Terraform) ініціалізує репозиторій для GitOps.

Flux відстежує зміни в репозиторії GitOps та зміни в чарті Helm в репо нашого застосунку та застосовує їх.

Під час внесення змін в код застосунку за допомогою GitHub Actions в репо застосунку збирається новий образ контейнера та оновлюється версія чарту Helm.

За наявності таких змін Flux доставляє нову версію застосунку в кластер.

flowchart LR
pr("Changes fas:fa-code-pull-request") 
chk_sec("Checking for 
secrets fas:fa-user-secret")

subgraph ar["Application Code Repo"]
    subgraph ga["Github Actions"]
        build_img("Build Image fa:fa-hard-drive")
        update_helm("Update Helm Chart fas:fa-arrows-rotate")
    end
    subgraph app["Application"]
        code("Application Code fa:fa-code")
        hc("Helm Chart fa:fa-file-invoice")
    end
end

subgraph reg["Image Registry far:fa-server"]
    img("Image fas:fa-database")
end

subgraph cli["CLIs fas:fa-toolbox"]
    tf("terrafom fas:fa-screwdriver-wrench") 
    flux("flux fas:fa-trowel-bricks")
end

subgraph tffx["Terraform & Flux"]
    subgraph iac["Infrastructure as Code fa:fa-code"]
    direction LR
        iacode("Code of the Infrastructure") -.->
        iacga("GitHub Actions")
    end
    go("GitOps Repo fa:fa-code")
end

subgraph cluster["Cluster fas:fa-circle-nodes"]
    fx("flux-controller fas:fa-gears")
    other1("…fas:fa-gears")
    other2("…fas:fa-gears")
end


pr --> go & iacode 
pr --> chk_sec --> |"Checks passed"| app 
chk_sec -.-> |"Checks failed"| pr

code --> ga
iac -.-> cli
iac --> tf --> fx 
tf --> other1 & other2 
flux --> fx
img -.-> fx & hc 
hc -->fx 
fx <--> go 

update_helm --> hc
build_img --> img & update_helm 

other1 & other2 -.- fx
tf -.-> cluster

В разі внесення змін в опис ресурсів контейнера за допомогою Infracost (через GitHub Actions цього репо) виконується розрахунок можливих змін витрат на інфраструктуру. Якщо ці зміни відповідають нашим вимогам – виконуємо їх злиття в основну гілку та застосовуємо їх для оновлення інфраструктури.1

Footnotes

  1. Для подальшої автоматизації можливо додати відповідні GitHub Actions, які будуть автоматично перевіряти та застосовувати зміні в цьому репо до розгорнутої інфраструктури, див https://developer.hashicorp.com/terraform/tutorials/automation/github-actions.