Zum Inhalt

Artefakte

Was sind Artefakte?

Artefakte (Artifacts) sind Dateien, die während der Ausführung von Actions generiert, benötigt oder persistiert werden. Sie liegen pro Block unter artifacts/blocks/<block>/ und bleiben zwischen Action-Läufen erhalten; kein gemeinsamer Artefakt-Speicher zwischen verschiedenen Blocks.

Typische Artefakte sind:

  • Ansible-Inventories - Dynamisch generierte oder kopierte Host-Listen
  • Kubeconfigs - Kubernetes-Cluster-Zugriffskonfigurationen
  • Secrets - Verschlüsselte sensitive Dateien (Passwörter, Zertifikate, Keys)
  • SSH-Keys - SSH-Schlüsselpaare für Remote-Zugriff
  • Generierte Manifeste - YAML/JSON-Dateien für Kubernetes oder andere Systeme
  • Zertifikate - TLS-Zertifikate, CA-Bundles
  • Backup-Dateien - Datenbank-Dumps, Konfigurationssicherungen

Artifacts-Struktur

Pfad Beschreibung Sensibel
inventory.yml Ansible Inventory (Workspace-Root) Nein
artifacts/ Artifacts-Root -
artifacts/secrets/ Workspace-weite Secrets ⚠️ Ja
artifacts/secrets/id_rsa SSH Private Key ⚠️ Ja
artifacts/secrets/id_rsa.pub SSH Public Key Nein
artifacts/secrets/kubeconfig.yml Kubernetes Config ⚠️ Ja
artifacts/secrets/<block>/ Block-spezifische Secrets ⚠️ Ja
artifacts/blocks/ Block-Artefakte Nein
artifacts/blocks/<block>/generated/ Generierte Manifeste Nein

artifacts/blocks/<block>/hosts_cache.json wurde früher als SSH-Host-Cache genutzt; aktuelle Polycrate-Versionen legen diese Datei nicht mehr an (Bestands-Workspaces können sie noch enthalten).

Standard-Verzeichnisstruktur

my-workspace/
├── inventory.yml               # 📋 Ansible Inventory (Workspace-Root, YAML)
├── artifacts/                  # Artifacts-Root (konfigurierbar)
│   ├── secrets/                # 🔐 Verschlüsselte Secrets
│   │   ├── id_rsa              # Workspace SSH-Key (verschlüsselt)
│   │   ├── id_rsa.pub          # Workspace SSH-Pubkey
│   │   ├── kubeconfig.yml      # Kubernetes Kubeconfig (verschlüsselt)
│   │   └── my-app/             # Block-spezifische Secrets
│   │       ├── database.pwd    # Datenbank-Passwort
│   │       └── api-key.txt     # API-Key
│   └── blocks/                 # Block-Artifacts
│       ├── my-cluster/
│       │   └── cluster-info.json
│       ├── infrastructure/
│       │   └── (block-spezifische Artefakte)
│       └── my-app/
│           └── generated/
│               ├── deployment.yml
│               └── configmap.yml
├── secrets.poly.age            # 🔐 Verschlüsselte secrets.poly
└── blocks/                     # Block-Definitionen

Secrets-Verschlüsselung

Dateien in artifacts/secrets/ werden automatisch verschlüsselt, wenn Sie polycrate workspace encrypt ausführen. Siehe Workspace-Verschlüsselung für Details.

Artifacts-Root konfigurieren

Die Artifacts-Root Directory kann in workspace.poly konfiguriert werden. Der YAML-Schlüssel lautet artifactsroot (ein Wort, ohne Unterstrich), nicht artifacts_root.

name: my-workspace

config:
  artifactsroot: artifacts  # Standard
  # oder ein anderer Pfad:
  # artifactsroot: .artifacts
  # artifactsroot: /tmp/polycrate-artifacts

Alternativ per globalem CLI-Flag (setzt workspace.config.artifactsroot):

polycrate --artifacts-root /custom/path run my-block install

Block Artifacts Directory

Für jeden Block wird automatisch eine Block Artifacts Directory erstellt:

artifacts/blocks/<BLOCK_NAME>/

Diese Directory:

  • Wird automatisch angelegt beim ersten Laden des Blocks
  • Ist persistent zwischen Action-Ausführungen
  • Wird in den Container gemountet
  • Ist Teil des Snapshots

Block-Artefakte-Variablen in Ansible/Jinja

In Playbooks und Jinja-Templates stehen folgende Snapshot-Variablen zur Verfügung:

Variable Beschreibung Beispiel
block.artifacts.path Generischer Pfad artifacts/blocks/my-app
block.artifacts.localpath Lokaler Pfad (Host) /abs/pfad/artifacts/blocks/my-app
block.artifacts.containerpath Pfad im Ansible-Container /polycrate/artifacts/blocks/my-app
block.artifacts.secrets.path Pfad zum Secrets-Ordner artifacts/blocks/my-app/secrets
block.artifacts.secrets.localpath Lokaler Pfad zum Secrets-Ordner /abs/pfad/artifacts/blocks/my-app/secrets
block.artifacts.secrets.containerpath Container-Pfad zum Secrets-Ordner /polycrate/artifacts/blocks/my-app/secrets

block.artifacts.path (ab LoadArtifacts)

Für Pfade in Playbooks (Schreiben, lookup('file', …)) block.artifacts.path verwenden: Die CLI setzt diesen Wert auf den passenden Pfad für lokalen oder Container-Lauf (--local vs. Container).

Block Secrets Path (ab 0.30.4)

Für expliziten Zugriff auf den Block-Secrets-Ordner block.artifacts.secrets.path bzw. block.artifacts.secrets.localpath (Host) nutzen:

- name: SSH-Key aus Block-Secrets kopieren
  copy:
    src: "{{ block.artifacts.secrets.localpath }}/id_rsa"
    dest: /tmp/deploy-key
    mode: '0600'

Secrets Directory

Die Secrets Directory (artifacts/secrets/) ist ein spezieller Bereich für sensitive Dateien, die bei der Workspace-Verschlüsselung automatisch verschlüsselt werden.

Struktur

artifacts/secrets/
├── id_rsa              # Workspace SSH-Key
├── id_rsa.pub          # Workspace SSH-Pubkey
├── kubeconfig.yml      # Workspace Kubeconfig
└── <block-name>/       # Block-spezifische Secrets
    ├── database.pwd    # Passwort-Datei
    ├── api-key.txt     # API-Key
    └── cert.pem        # Zertifikat

Workspace-Secrets vs Block-Secrets

Typ Pfad Zugriff in Ansible
Workspace-Secrets artifacts/secrets/ {{ workspace.secrets['filename'] }}
Block-Secrets artifacts/secrets/<block>/ {{ block.secrets['filename'] }}

Beispiel: Secrets in Ansible nutzen

# deploy.yml
- name: Deploy mit Secrets
  hosts: all
  tasks:
    # Workspace-Secret nutzen
    - name: Kubeconfig aus Workspace-Secrets
      shell: kubectl --kubeconfig={{ workspace.secrets['kubeconfig.yml'] }} get pods

    # Block-Secret nutzen
    - name: Datenbank-Passwort aus Block-Secrets
      shell: mysql -p$(cat {{ block.secrets['database.pwd'] }}) -h localhost

Verschlüsselung

Alle Dateien in artifacts/secrets/ werden automatisch verschlüsselt, wenn Sie den Workspace verschlüsseln:

# Workspace verschlüsseln (inkl. Secrets)
polycrate workspace encrypt

# Status anzeigen
polycrate workspace status

# Entschlüsseln für Bearbeitung
polycrate workspace decrypt

Nach der Verschlüsselung:

  • secrets.polysecrets.poly.age
  • artifacts/secrets/id_rsaartifacts/secrets/id_rsa.age
  • artifacts/secrets/kubeconfig.ymlartifacts/secrets/kubeconfig.yml.age

Git-Sicherheit

Committen Sie niemals unverschlüsselte Secrets. Fügen Sie artifacts/secrets/ zu .gitignore hinzu oder verschlüsseln Sie den Workspace vor dem Commit.

Ausführliche Dokumentation zur Workspace-Verschlüsselung

Standard-Artefakte

1. Ansible-Inventory

Das Ansible-Inventory liegt als inventory.yml direkt im Workspace-Root. Es muss im YAML-Format vorliegen — INI-Format wird nicht unterstützt. Polycrate setzt ANSIBLE_INVENTORY automatisch auf diesen Pfad.

# inventory.yml  (Workspace-Root)
all:
  hosts:
    web1:
      ansible_host: 192.168.1.10
      ansible_user: deploy
      ansible_port: 22
    web2:
      ansible_host: 192.168.1.11
      ansible_user: deploy
  vars:
    ansible_python_interpreter: /usr/bin/python3
  children:
    webservers:
      hosts:
        web1: {}
        web2: {}

2. Kubeconfig

Die Kubeconfig muss unter artifacts/secrets/kubeconfig.yml abgelegt werden. Dieser Pfad liegt innerhalb der Secrets-Directory und wird dadurch automatisch von der Workspace-Verschlüsselung erfasst.

# artifacts/secrets/kubeconfig.yml
apiVersion: v1
kind: Config
clusters:
  - name: prod-cluster
    cluster:
      server: https://k8s.example.com:6443
      certificate-authority-data: LS0tLS...
contexts:
  - name: prod
    context:
      cluster: prod-cluster
      user: admin
      namespace: production
current-context: prod
users:
  - name: admin
    user:
      client-certificate-data: LS0tLS...
      client-key-data: LS0tLS...

Pflichtpfad

Die Kubeconfig muss unter artifacts/secrets/kubeconfig.yml gespeichert werden – sowohl bei manueller Verwendung als auch beim offiziellen ayedo k8s-Block. Nur so greift die Workspace-Verschlüsselung korrekt.

3. SSH-Host-Cache (historisch)

Frühere Polycrate-Versionen konnten unter artifacts/blocks/<block>/hosts_cache.json SSH-Verbindungsdaten zwischenspeichern. Aktuelle Releases legen diese Datei nicht mehr an. In älteren Workspaces kann die Datei noch existieren; sie wird nicht mehr aktiv verwaltet.

Artefakte in Actions nutzen

In Ansible-Playbooks

Artifacts sind automatisch verfügbar über Snapshot-Variablen:

---
- name: Deploy Application
  hosts: localhost
  connection: local

  tasks:
    - name: Lade generiertes Manifest
      set_fact:
        manifest: "{{ lookup('file', block.artifacts.path + '/generated/deployment.yml') }}"

    - name: Apply Manifest
      kubernetes.core.k8s:
        state: present
        definition: "{{ manifest }}"

Best Practice: Ansible-Playbooks

Alle Actions sollten mit Ansible-Playbooks implementiert werden:

actions:
  - name: status
    playbook: status.yml

  - name: deploy
    playbook: deploy.yml

Im Playbook haben Sie Zugriff auf alle Workspace- und Block-Variablen via Jinja2-Templating.

Artefakte generieren

Beispiel 1: Kubeconfig generieren

Komplexe Artefakt-Generierung sollte in einem Ansible-Playbook erfolgen:

# block.poly
actions:
  - name: create-cluster
    playbook: create-cluster.yml

  - name: get-kubeconfig
    playbook: get-kubeconfig.yml
# get-kubeconfig.yml
- name: Kubeconfig abrufen und speichern
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Kubeconfig exportieren
      shell: kubectl config view --flatten
      register: kubeconfig_output

    - name: Kubeconfig als Artifact speichern
      copy:
        content: "{{ kubeconfig_output.stdout }}"
        dest: "{{ block.artifacts.path }}/kubeconfig.yml"
        mode: '0600'

    - name: Bestätigung
      debug:
        msg: "Kubeconfig saved to {{ block.artifacts.path }}/kubeconfig.yml"

Die Workspace-Kubeconfig für Kubernetes-Aktionen liegt dagegen fest unter artifacts/secrets/kubeconfig.yml (siehe Abschnitt Kubeconfig). Ein anderer Block-Eintrag kann in der workspace.poly per kubeconfig.from: auf den Kubeconfig-Kontext eines anderen Blocks verweisen – das ist Konfigurationsverdrahtung, kein gemeinsames Artefakt-Verzeichnis:

# workspace.poly
blocks:
  - name: my-cluster
    from: registry.my-org.com/blocks/k8s/cluster:1.0.0

  - name: my-app
    from: registry.my-org.com/blocks/k8s/my-app:1.0.0
    kubeconfig:
      from: my-cluster  # Nutzt kubeconfig.yml von Block "my-cluster"

Beispiel 2: Inventory aus Cloud-API generieren

# generate-inventory.yml
- name: Inventory aus Cloud-API generieren
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Cloud-Instanzen abrufen
      amazon.aws.ec2_instance_info:
        region: "{{ block.config.region }}"
        filters:
          "tag:Environment": "{{ block.config.environment }}"
      register: ec2_instances

    - name: Inventory generieren
      template:
        src: inventory.yml.j2
        dest: "{{ block.artifacts.path }}/inventory.yml"
      vars:
        hosts: "{{ ec2_instances.instances }}"

Beispiel 3: Generierte Konfiguration persistieren

# generate-config.yml
- name: Konfiguration generieren und persistieren
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Konfiguration generieren
      template:
        src: config.yml.j2
        dest: "{{ block.artifacts.path }}/config.yml"
      vars:
        namespace: "{{ block.config.namespace }}"
        replicas: "{{ block.config.replicas }}"

    - name: Cache-Datei erstellen
      copy:
        content: "{{ block.config | to_nice_json }}"
        dest: "{{ block.artifacts.path }}/config_cache.json"

Kein Artefakt-Teilen zwischen Blocks

Artefakte sind pro Block unter artifacts/blocks/<block-name>/ abgelegt. Es gibt kein gemeinsames Artefakt-Repository: Ein Block kann nicht direkt die Artefaktdateien eines anderen Blocks lesen oder „übernehmen“, und Workflows führen auch keine automatische Weitergabe von Artefaktdateien zwischen Steps oder Blocks herbei.

Was in der workspace.poly möglich ist (z. B. kubeconfig.from:, inventory.from:), sind Verweise auf andere Block-Instanzen für die Workspace-Konfiguration (welcher Kontext, welches Inventory gilt) – nicht das gleichzeitige Nutzen eines gemeinsamen Artefakt-Ordners. Daten, die ein Block für den nächsten braucht, müssen über Workspace-weite Pfade (z. B. inventory.yml, artifacts/secrets/) oder durch erneutes Erzeugen im Ziel-Block bereitgestellt werden.

Best Practices

1. Artifacts für reproduzierbare Builds

Speichern Sie alle generierten Dateien als Artifacts (in einem Playbook):

# build.yml
- name: Build und Artifacts speichern
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Build durchführen
      command: make build

    - name: Artifacts-Verzeichnis erstellen
      file:
        path: "{{ block.artifacts.path }}/build"
        state: directory

    - name: Build-Artifacts kopieren
      copy:
        src: "{{ item }}"
        dest: "{{ block.artifacts.path }}/build/"
      loop:
        - dist/
        - build.log

2. Git und Artefakte

Unter artifacts/ liegen reproduzierbare Ausgaben (Manifeste, generierte Inventories, Block-Artefakte). Diese sind Teil des Workspace-Repositorys und sollen in der Regel versioniert werden, damit GitOps- und Review-Prozesse nachvollziehbar bleiben.

Flüchtige oder große Zwischenstände (npm-, pip-Caches, temporäre Downloads) gehören nicht unter artifacts/ im Workspace: Legen Sie solche Pfade im Container nach /tmp oder außerhalb von workspace.path an, oder räumen Sie sie in einer Action auf.

Secrets: Unverschlüsselte Geheimnisse nicht committen – siehe Workspace-Verschlüsselung.

3. Artifacts-Cleanup

Implementieren Sie Cleanup-Actions als Playbook:

# clean.yml
- name: Artifacts aufräumen
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Artifacts-Verzeichnis leeren
      file:
        path: "{{ block.artifacts.path }}"
        state: absent

    - name: Artifacts-Verzeichnis neu erstellen
      file:
        path: "{{ block.artifacts.path }}"
        state: directory

    - name: Bestätigung
      debug:
        msg: "Artifacts cleaned: {{ block.artifacts.path }}"

4. Artifacts dokumentieren

Dokumentieren Sie, welche Artifacts ein Block erstellt (im Block-README):

# my-block

## Generierte Artifacts

| Datei | Beschreibung |
|-------|-------------|
| `kubeconfig.yml` | Kubernetes-Cluster-Zugriff |
| `inventory.yml` | Ansible-Hosts-Liste |
| `certs/ca.crt` | Root-CA |
| `certs/tls.crt` | Server-Zertifikat |
| `certs/tls.key` | Private Key (verschlüsselt) |

5. Artifacts validieren

Validieren Sie Artifacts nach der Generierung:

# generate-inventory.yml
- name: Inventory generieren und validieren
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Inventory generieren
      command: python3 scripts/generate-inventory.py
      register: inventory_output

    - name: Inventory speichern
      copy:
        content: "{{ inventory_output.stdout }}"
        dest: "{{ block.artifacts.path }}/inventory.yml"

    - name: Inventory validieren
      command: ansible-inventory -i {{ block.artifacts.path }}/inventory.yml --list
      register: validation

    - name: Validierung erfolgreich
      debug:
        msg: "Inventory validated: {{ (validation.stdout | from_json).all.hosts | length }} hosts"

Artifacts im Lifecycle

sequenceDiagram
    participant User
    participant CLI
    participant Block
    participant Artifacts

    User->>CLI: polycrate run block provision
    CLI->>Artifacts: Lade existierende Artifacts
    Artifacts-->>CLI: inventory.yml, kubeconfig.yml
    CLI->>Block: Führe Action aus
    Block->>Artifacts: Generiere neue Artifacts
    Artifacts-->>Block: Gespeichert
    Block-->>CLI: Action erfolgreich
    CLI->>Artifacts: Workspace-Reload: Lade neue Artifacts
    Artifacts-->>CLI: Aktualisierte Artifacts
    CLI-->>User: Fertig

    User->>CLI: polycrate run app deploy
    CLI->>Artifacts: Lade Artifacts (inkl. neu generierte)
    Artifacts-->>CLI: inventory.yml, kubeconfig.yml
    CLI->>Block: Führe Action mit Artifacts aus
  1. Vor Action: Bestehende Artifacts werden geladen
  2. Während Action: Neue Artifacts werden generiert/modifiziert
  3. Nach Action: Workspace wird neu geladen (neue Artifacts verfügbar)
  4. Nächste Action: Verwendet aktualisierte Artifacts

Zusammenhang mit anderen Konzepten

  • Snapshot: Artifacts sind Teil des Snapshots
  • Vererbung: Block-Artefakte und Konfigurationen können vererbt werden
  • Workflows: Workflows führen Actions in festgelegter Reihenfolge aus (kein automatisches Artefakt-Teilen zwischen Blocks)
  • Container: Artifacts werden in den Container gemountet

Workspace-weite Schnittstellen

Sollen mehrere Instanzen dieselbe Datenlage nutzen (z. B. inventory.yml im Workspace-Root oder artifacts/secrets/kubeconfig.yml), legen Sie diese workspace-weit ab und dokumentieren Sie die Konventionen in der README – nicht über ein gemeinsames Artefakt-Verzeichnis eines anderen Blocks.