📦 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 - Terraform-State - Terraform-Zustandsdateien - SSH-Host-Cache - Cache für SSH-Verbindungen - Generierte Manifeste - YAML/JSON-Dateien für Kubernetes oder andere Systeme - Zertifikate - TLS-Zertifikate, CA-Bundles - Backup-Dateien - Datenbank-Dumps, Konfigurationssicherungen - Log-Snapshots - Spezifische Log-Auszüge
Artifacts-Struktur¶
graph TB
WS[Workspace] --> ArtRoot[artifacts/]
ArtRoot --> BlocksDir[blocks/]
BlocksDir --> B1[block-1/]
BlocksDir --> B2[block-2/]
BlocksDir --> B3[block-3/]
B1 --> Inv1[inventory.yml]
B1 --> Kube1[kubeconfig.yml]
B1 --> Cache1[hosts_cache.json]
B1 --> Custom1[custom-data.yml]
B2 --> Inv2[inventory.yml]
B2 --> TFState[terraform.tfstate]
B2 --> Certs[certs/]
B3 --> Kube3[kubeconfig.yml]
B3 --> Manifests[generated/]
Manifests --> M1[deployment.yml]
Manifests --> M2[service.yml]
Certs --> CA[ca.crt]
Certs --> TLS[tls.crt]
style ArtRoot fill:#e1f5ff
style BlocksDir fill:#f0ffe1
style B1 fill:#fff4e1
style B2 fill:#fff4e1
style B3 fill:#fff4e1 Standard-Verzeichnisstruktur¶
my-workspace/
├── artifacts/ # Artifacts-Root (konfigurierbar)
│ └── blocks/ # Block-Artifacts
│ ├── my-cluster/
│ │ ├── kubeconfig.yml
│ │ └── cluster-info.json
│ ├── infrastructure/
│ │ ├── inventory.yml
│ │ ├── hosts_cache.json
│ │ └── terraform.tfstate
│ └── my-app/
│ ├── inventory.yml # geerbt oder eigenes
│ ├── kubeconfig.yml # geerbt oder eigenes
│ └── generated/
│ ├── deployment.yml
│ └── configmap.yml
├── .logs/ # Transaction-Logs (kein Artifact)
└── blocks/ # Block-Definitionen
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
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 }}"
In Bash-Scripts¶
Nutzen Sie die Template-Syntax oder Environment-Variablen:
actions:
- name: deploy
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
# Manifest generieren und als Artifact speichern
cat > $ARTIFACTS_DIR/generated/deployment.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .block.name }}
spec:
replicas: 3
EOF
# Artifact nutzen
kubectl apply -f $ARTIFACTS_DIR/generated/deployment.yml
Artefakte generieren¶
Beispiel 1: Kubeconfig generieren¶
actions:
- name: create-cluster
playbook: playbooks/create-cluster.yml
- name: get-kubeconfig
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
# Kubeconfig von Cluster abrufen
kubectl config view --flatten > $ARTIFACTS_DIR/kubeconfig.yml
echo "Kubeconfig saved to $ARTIFACTS_DIR/kubeconfig.yml"
Andere Blocks können diesen Kubeconfig dann erben:
name: my-app
from: base-app
kubeconfig:
from: my-cluster # Erbt kubeconfig.yml von Block "my-cluster"
Beispiel 2: Inventory generieren¶
actions:
- name: provision-infrastructure
playbook: playbooks/provision.yml
- name: generate-inventory
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
# Inventory dynamisch aus Terraform-Output generieren
terraform output -json | jq -r '.hosts.value' | \
python3 scripts/generate-inventory.py > $ARTIFACTS_DIR/inventory.yml
echo "Inventory saved to $ARTIFACTS_DIR/inventory.yml"
Beispiel 3: Terraform-State persistieren¶
actions:
- name: terraform-apply
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
cd terraform/
terraform init
terraform apply -auto-approve
# State als Artifact speichern
cp terraform.tfstate $ARTIFACTS_DIR/terraform.tfstate
cp terraform.tfstate.backup $ARTIFACTS_DIR/terraform.tfstate.backup
Artefakte zwischen Blocks teilen¶
Via Vererbung¶
Der einfachste Weg ist Vererbung:
# Block: infrastructure
name: infrastructure
kind: generic
actions:
- name: generate-inventory
script:
- # ... generiert inventory.yml in Artifacts
# Block: my-app
name: my-app
kind: linuxapp
inventory:
from: infrastructure # Verwendet inventory.yml von "infrastructure"
actions:
- name: install
playbook: playbooks/install.yml # Nutzt geerbtes Inventory
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:
actions:
- name: build
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
# Build durchführen
make build
# Artifacts speichern
mkdir -p $ARTIFACTS_DIR/build
cp -r dist/* $ARTIFACTS_DIR/build/
cp build.log $ARTIFACTS_DIR/build/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:
actions:
- name: clean
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
rm -rf $ARTIFACTS_DIR/*
echo "Artifacts cleaned"
4. Artifacts dokumentieren¶
Dokumentieren Sie, welche Artifacts ein Block erstellt:
# my-block
## Generierte Artifacts:
- `kubeconfig.yml` - Kubernetes-Cluster-Zugriff
- `inventory.yml` - Ansible-Hosts-Liste
- `certs/` - TLS-Zertifikate
- `ca.crt` - Root-CA
- `tls.crt` - Server-Zertifikat
- `tls.key` - Private Key
5. Artifacts validieren¶
Validieren Sie Artifacts nach der Generierung:
actions:
- name: generate-inventory
script:
- |
ARTIFACTS_DIR="{{ .workspace.config.artifacts_root }}/blocks/{{ .block.name }}"
# Inventory generieren
python3 scripts/generate-inventory.py > $ARTIFACTS_DIR/inventory.yml
# Validieren
ansible-inventory -i $ARTIFACTS_DIR/inventory.yml --list
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
- Transactions: Änderungen an Artifacts werden geloggt
Artifact-basierte Architektur
Nutzen Sie Artifacts als Schnittstelle zwischen Blocks. Block A generiert Kubeconfig, Block B nutzt ihn. So bleiben Blocks entkoppelt und wiederverwendbar!