📦 Artefakte¶
Was sind Artefakte?¶
Artefakte (Artifacts) sind Dateien, die während der Ausführung von Actions generiert, benötigt oder persistiert werden. Sie dienen als Schnittstelle zwischen verschiedenen Actions und Blocks und ermöglichen das Speichern von Zustandsinformationen, Konfigurationsdateien und generierten Ressourcen.
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 |
|---|---|---|
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>/inventory.yml | Ansible Inventory | Nein |
artifacts/blocks/<block>/hosts_cache.json | SSH Host Cache | Nein |
artifacts/blocks/<block>/generated/ | Generierte Manifeste | Nein |
Standard-Verzeichnisstruktur¶
my-workspace/
├── artifacts/ # Artifacts-Root (konfigurierbar)
│ ├── secrets/ # 🔐 Verschlüsselte Secrets
│ │ ├── id_rsa # Workspace SSH-Key (verschlüsselt)
│ │ ├── id_rsa.pub # Workspace SSH-Pubkey
│ │ ├── kubeconfig.yml # Workspace 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/
│ │ ├── inventory.yml
│ │ └── hosts_cache.json
│ └── 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:
name: my-workspace
config:
artifacts_root: artifacts # Standard
# oder ein anderer Pfad:
# artifacts_root: .artifacts
# artifacts_root: /tmp/polycrate-artifacts
Alternativ per CLI-Flag:
Block Artifacts Directory¶
Für jeden Block wird automatisch eine Block Artifacts Directory erstellt:
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
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¶
# playbooks/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.poly→secrets.poly.ageartifacts/secrets/id_rsa→artifacts/secrets/id_rsa.ageartifacts/secrets/kubeconfig.yml→artifacts/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¶
Polycrate sucht automatisch nach inventory.yml in der Block Artifacts Directory:
# artifacts/blocks/my-app/inventory.yml
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: {}
Suchpfade (in dieser Reihenfolge): 1. artifacts/blocks/<BLOCK>/inventory.yml 2. Geerbtes Inventory (wenn inventory.from gesetzt) 3. Workspace-Root inventory.yml
2. Kubeconfig¶
Polycrate sucht automatisch nach kubeconfig.yml in der Block Artifacts Directory:
# artifacts/blocks/my-app/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...
Suchpfade: 1. artifacts/blocks/<BLOCK>/kubeconfig.yml 2. Geerbter Kubeconfig (wenn kubeconfig.from gesetzt) 3. Workspace-Root kubeconfig.yml 4. System-Default (~/.kube/config)
3. SSH-Host-Cache¶
Polycrate cached SSH-Verbindungsdaten für Performance:
// artifacts/blocks/my-app/hosts_cache.json
{
"web1": {
"ansible_host": "192.168.1.10",
"ansible_port": 22,
"ansible_user": "deploy",
"last_seen": "2025-01-30T10:30:00Z",
"fingerprint": "SHA256:abc123..."
}
}
Dieser Cache wird automatisch verwaltet und beschleunigt SSH-Operationen.
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', workspace.config.artifacts_root + '/blocks/' + block.name + '/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: playbooks/status.yml
- name: deploy
playbook: playbooks/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: playbooks/create-cluster.yml
- name: get-kubeconfig
playbook: playbooks/get-kubeconfig.yml
# playbooks/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.local_path }}/kubeconfig.yml"
mode: '0600'
- name: Bestätigung
debug:
msg: "Kubeconfig saved to {{ block.artifacts.local_path }}/kubeconfig.yml"
Andere Blocks können diese Kubeconfig dann in der workspace.poly referenzieren:
# 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¶
# playbooks/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.local_path }}/inventory.yml"
vars:
hosts: "{{ ec2_instances.instances }}"
Beispiel 3: Generierte Konfiguration persistieren¶
# playbooks/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.local_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.local_path }}/config_cache.json"
Artefakte zwischen Blocks teilen¶
Via Referenzierung¶
Blocks können Artifacts von anderen Blocks referenzieren (in workspace.poly):
# workspace.poly
blocks:
- name: infrastructure
from: registry.my-org.com/blocks/infra/base:1.0.0
# Generiert inventory.yml in artifacts/blocks/infrastructure/
- name: my-app
from: registry.my-org.com/blocks/k8s/my-app:1.0.0
inventory:
from: infrastructure # Nutzt inventory.yml von "infrastructure"
Via Workflows¶
Workflows können Artifacts zwischen Blocks orchestrieren:
# In workspace.poly
name: my-workspace
blocks:
- name: infrastructure
# ...
- name: my-app
# ...
workflows:
- name: deploy-stack
steps:
- name: provision-infra
block: infrastructure
action: provision
- name: generate-inventory
block: infrastructure
action: generate-inventory
- name: deploy-app
block: my-app
action: install # Nutzt Inventory von vorherigem Step
Nach generate-inventory lädt Polycrate den Workspace neu und das neue Inventory steht my-app zur Verfügung.
Best Practices¶
1. Artifacts für reproduzierbare Builds¶
Speichern Sie alle generierten Dateien als Artifacts (in einem Playbook):
# playbooks/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.local_path }}/build"
state: directory
- name: Build-Artifacts kopieren
copy:
src: "{{ item }}"
dest: "{{ block.artifacts.local_path }}/build/"
loop:
- dist/
- build.log
2. Artifacts in .gitignore¶
Artifacts sollten nicht in Git committed werden:
Ausnahmen: Manche Artifacts (wie manuell erstellte Inventories) können committed werden.
3. Artifacts-Cleanup¶
Implementieren Sie Cleanup-Actions als Playbook:
# playbooks/clean.yml
- name: Artifacts aufräumen
hosts: localhost
gather_facts: false
tasks:
- name: Artifacts-Verzeichnis leeren
file:
path: "{{ block.artifacts.local_path }}"
state: absent
- name: Artifacts-Verzeichnis neu erstellen
file:
path: "{{ block.artifacts.local_path }}"
state: directory
- name: Bestätigung
debug:
msg: "Artifacts cleaned: {{ block.artifacts.local_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:
# playbooks/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.local_path }}/inventory.yml"
- name: Inventory validieren
command: ansible-inventory -i {{ block.artifacts.local_path }}/inventory.yml --list
register: validation
- name: Validierung erfolgreich
debug:
msg: "Inventory validated: {{ (validation.stdout | from_json).all.hosts | length }} hosts"
if [ $? -ne 0 ]; then
echo "ERROR: Invalid inventory generated!"
exit 1
fi
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 - Vor Action: Bestehende Artifacts werden geladen
- Während Action: Neue Artifacts werden generiert/modifiziert
- Nach Action: Workspace wird neu geladen (neue Artifacts verfügbar)
- Nächste Action: Verwendet aktualisierte Artifacts
Zusammenhang mit anderen Konzepten¶
- Snapshot: Artifacts sind Teil des Snapshots
- Vererbung: Artifacts können vererbt werden (
inventory.from,kubeconfig.from) - Workflows: Workflows orchestrieren Artifact-Generation zwischen Blocks
- Container: Artifacts werden in den Container gemountet
Artifact-basierte Architektur
Nutzen Sie Artifacts als Schnittstelle zwischen Blocks. Block A generiert Kubeconfig, Block B nutzt ihn. So bleiben Blocks entkoppelt und wiederverwendbar!