Skip to content
GitLabGitHub

Utworzenie procesu CI dla opentofu

W tym artykule opiszę jak zbudowałem własny centralne repozytorium dla opentofu

  • Wdrażamy wersjonowanie repozytorium za pomocą semantic-release

  1. .
    ├── configs
    │   ├── stages.yml
    │   └── workflow.yml
    ├── docs
    │   └── logo
    ├── jobs
    │   ├── analyze_conventional_commits
    │   │   ├── job.yml
    │   │   └── README.md
    │   ├── code_review
    │   │   ├── job.yml
    │   │   └── README.md
    │   ├── versioning
    │   │   ├── job.yml
    │   │   └── README.md
    │   └── yamllint
    │       ├── job.yml
    │       └── README.md
    ├── pipelines
    │   └── opentofu-module
    │       └── README.md
    └── scripts
        ├── helper_gitlab-ci.yml
        └── helper_readme.yml
  2. Utworzenie centralnego router procesów CI/CD

    Section titled “Utworzenie centralnego router procesów CI/CD”

    Główny plik .gitlab-ci.yml pełni rolę centralnego routera procesów CI/CD, którego zadaniem nie jest bezpośrednia definicja logiki buildów czy wdrożeń, lecz koordynacja i orkiestracja całego procesu pipeline w sposób spójny, skalowalny i możliwy do rozszerzania.

    Kluczowe założenia architektoniczne

    • Pipeline jest komponowany dynamicznie z wielu mniejszych, wyspecjalizowanych plików YAML.
    • Każdy projekt korzystający z tego repozytorium dziedziczy wspólny zestaw obowiązkowych jobów, niezależnie od typu projektu.
    • Logika specyficzna dla danego typu projektu jest delegowana do dedykowanych pipeline’ów procesowych, wybieranych na podstawie zmiennych środowiskowych.
    ---
    default:
      tags:
        - gitlab-rnp
    
    include:
      - local: "configs/stages.yml"
      - local: "configs/workflow.yml"
    
      # helpers
      - local: "scripts/*.yml"
    
      # jobs
      - local: "jobs/*/job.yml"
    
      # process
      - local: "pipelines/${PROJECT_TYPE}/.gitlab-ci.yml"
        rules:
          - if: $DISABLE_EXECUTE_PIPELINE == "true"
            when: never
          - if: $PROJECT_TYPE
  3. configs/stages.yml:

    ---
    stages:
        ### Standard w ramach dyscypliny
        - prepare           # przygotowanie środowiska, instalacja zależności, inicjalizacja.
        - dependency        # pobieranie zależności (biliotek, funkcji, komponentów)
        - validate          # weryfikacja poprawności konfiguracji, linting, planowanie zmian (Terraform, Ansible), pre-commit checks.
        - unit-test         # testy jednostkowe dla kodu (Go, .NET, Node.js itp.).
        - sast              # analiza statyczna kodu (Static Application Security Testing).
        - dast              # analiza dynamiczna aplikacji (Dynamic Application Security Testing).
        - build             # budowanie artefaktów (Packer, kontenery, kod źródłowy).
        - publish           # publikacja artefaktów, obrazów kontenerowych, paczek NuGet, npm itp.
        - release           # Wydawanie wersji
        - deploy            # wdrażanie aplikacji, infrastruktury, konfiguracji.
        - integration-test  # testy integracyjne, e2e, testy akceptacyjne.
        - cleanup           # usuwanie tymczasowych zasobów, sprzątanie środowiska.

    configs/workflow.yml:

    ---
    workflow:
      rules:
        - if: '$CI_COMMIT_TAG'
          when: never
        - if: $CI_PIPELINE_SOURCE == "push" && $CI_OPEN_MERGE_REQUESTS
          when: never
        - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/
          when: never
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
        - if: $CI_PIPELINE_SOURCE == "web"
        - if: $CI_PIPELINE_SOURCE == "push"
        - if: $CI_COMMIT_BRANCH
  4. pipelines/opentofu-module/.gitlab-ci.yml:

    ---
    variables:
      OPENTOFU_IMAGE: registry.gitlab.com/pl.rachuna-net/artifacts/containers/opentofu:0.0.1
      DOCS_MD_FILE_PATH: pipelines/opentofu-module/README.md
    
    🕵 opentofu fmt:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
      script:
        - tofu fmt -recursive -check
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    ✅ tflint:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
      script:
        - tflint
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    ✅ terraform-docs:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
      script:
        - |
          cp README.md README.md.bak
          if [ -f .terraform-docs.yml ]; then
            terraform-docs -c .terraform-docs.yml .
          else
            terraform-docs md . > README.md
          fi
          diff README.md README.md.bak
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success

    pipelines/opentofu/.gitlab-ci.yml:

    ---
    variables:
      OPENTOFU_IMAGE: registry.rachuna-net.pl/pl.rachuna-net/containers/opentofu:1.0.0
      DOCS_MD_FILE_PATH: pipelines/opentofu/README.md
    
    include:
      - local: "pipelines/opentofu/tofu-init.sh.yml"
    
    🕵 opentofu fmt:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
      script:
        - tofu fmt -recursive -check
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    ✅ opentofu validate:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
        - !reference [.tofu-init.sh.yml]
      script:
        - tofu validate
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    ✅ tflint:
      image: $OPENTOFU_IMAGE
      stage: validate
      before_script:
        - !reference [.helper_gitlab-ci.sh]
        - !reference [.tofu-init.sh.yml]
      script:
        - tflint
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    🧪 opentofu plan:
      image: $OPENTOFU_IMAGE
      stage: unit-test
      before_script:
        - !reference [.helper_gitlab-ci.sh]
        - !reference [.tofu-init.sh.yml]
      script:
        - tofu plan
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - when: on_success
    
    💥 opentofu apply:
      image: $OPENTOFU_IMAGE
      stage: deploy
      needs:
        - job: 📍 Publish Version
      before_script:
        - !reference [.helper_gitlab-ci.sh]
        - !reference [.tofu-init.sh.yml]
      script:
        - tofu apply -auto-approve
      after_script:
        - !reference [.helper_readme.sh]
      rules:
        - if: $CI_COMMIT_TAG
          when: never
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
          when: on_success
        - if: $CI_OPEN_MERGE_REQUESTS
          when: manual
  5. Wydanie wersji gitlab-ci v1.0.0

    pipeline