56 Semaphore Projekte und Inventories

56.1 Projekte anlegen und strukturieren

56.1.1 Was ist ein Projekt in Semaphore?

Ein Projekt ist die zentrale Organisationseinheit in Semaphore, die alle Ressourcen für einen zusammenhängenden Automatisierungsbereich zusammenfasst. Projekte bilden isolierte Namespaces mit eigenständigen Konfigurationen und Berechtigungen.

56.1.1.1 Projekt-Komponenten

Kernelemente eines Projekts:

56.1.1.2 Projekt-Isolation

Getrennte Bereiche:

Projekt A: Web-Application
├── Eigene Inventories (Web-Server, DB-Server)
├── Spezifische Credentials (Deploy-Keys, DB-Passwörter)
├── Dedizierte Templates (Deploy, Rollback, Backup)
└── Isolierte Job-Historie

Projekt B: Infrastructure
├── Eigene Inventories (Router, Switches, Firewalls)
├── Spezifische Credentials (SNMP-Communities, SSH-Keys)
├── Dedizierte Templates (Config-Backup, Update, Monitoring)
└── Isolierte Job-Historie

56.1.2 Strukturierungsempfehlungen

56.1.2.1 Umgebungsbezogene Trennung

Separate Projekte pro Umgebung:

Organisation: E-Commerce-Platform
├── ecommerce-development
│   ├── Dev-Server Inventories
│   ├── Development-Credentials
│   └── Test-Playbooks
├── ecommerce-staging
│   ├── Staging-Server Inventories
│   ├── Staging-Credentials
│   └── Pre-Production-Tests
└── ecommerce-production
    ├── Production-Server Inventories
    ├── Production-Credentials
    └── Production-Playbooks

Vorteile:

56.1.2.2 Teambasierte Strukturierung

Projekte nach Verantwortlichkeiten:

Organisation: TechCorp
├── frontend-team-project
│   ├── Web-Server Management
│   ├── CDN-Konfiguration
│   └── Frontend-Deployments
├── backend-team-project
│   ├── Application-Server Management
│   ├── API-Deployments
│   └── Database-Operations
└── infrastructure-team-project
    ├── Network-Configuration
    ├── Monitoring-Setup
    └── Security-Policies

56.1.2.3 Service-orientierte Strukturierung

Projekte pro Service/Anwendung:

Microservices-Umgebung:
├── user-service-ops
├── payment-service-ops
├── inventory-service-ops
├── notification-service-ops
└── shared-infrastructure

56.1.3 Projekt-Konfiguration

56.1.3.1 Grundeinstellungen

Projekt-Metadaten:

Name: "E-Commerce Backend"
Description: "Deployment und Management der Backend-Services"
Owner: backend-team
Created: 2024-08-15
Alert Email: backend-team@company.com

56.1.3.2 Access Control

Berechtigungsmatrix:

Rolle               | Template-Ausführung | Konfiguration | Credential-Zugriff
--------------------|--------------------|--------------|-----------------
Organisation Admin  | Alle               | Vollzugriff  | Admin
Project Admin       | Alle               | Vollzugriff  | Admin
Team Admin          | Alle im Team       | Team-Config  | Nutzung
Team Member         | Ausgewählte        | Lesezugriff  | Nutzung
Operator            | Ausgewählte        | Lesezugriff  | Nutzung
Viewer              | Keine              | Lesezugriff  | Keine

Hinweis: Rechte können sich zwischen Organisationsebene und Projektebene unterscheiden.

56.2 Inventories verwalten

56.2.1 Statische vs. Dynamische Inventories

56.2.1.1 Statische Inventories

Charakteristika:

56.2.1.2 Dynamische Inventories

Charakteristika:

Beispiel für Semaphore eigenes Plugin:

plugin: command
command: ./dynamic_inventory.sh

56.2.2 Statische Inventory-Beispiele

56.2.2.1 YAML-Format

# inventory.yml
all:
  children:
    webservers:
      hosts:
        web01.example.com:
          ansible_host: 192.168.1.10
          http_port: 80
        web02.example.com:
          ansible_host: 192.168.1.11
          http_port: 80
    databases:
      hosts:
        db01.example.com:
          ansible_host: 192.168.1.20
          mysql_port: 3306
        db02.example.com:
          ansible_host: 192.168.1.21
          mysql_port: 3306
    loadbalancers:
      hosts:
        lb01.example.com:
          ansible_host: 192.168.1.5
          vip: 192.168.1.100
  vars:
    ansible_user: deploy
    ansible_ssh_private_key_file: /path/to/private/key

56.2.2.2 INI-Format

# inventory.ini
[webservers]
web01.example.com ansible_host=192.168.1.10 http_port=80
web02.example.com ansible_host=192.168.1.11 http_port=80

[databases]
db01.example.com ansible_host=192.168.1.20 mysql_port=3306
db02.example.com ansible_host=192.168.1.21 mysql_port=3306

[loadbalancers]
lb01.example.com ansible_host=192.168.1.5 vip=192.168.1.100

[webservers:vars]
http_port=80
max_connections=1000

[databases:vars]
mysql_port=3306
backup_hour=2

56.2.2.3 Erweiterte Gruppierung

# Nested Groups
all:
  children:
    production:
      children:
        prod_web:
          hosts:
            prod-web-01.company.com:
            prod-web-02.company.com:
        prod_db:
          hosts:
            prod-db-01.company.com:
    staging:
      children:
        stage_web:
          hosts:
            stage-web-01.company.com:
        stage_db:
          hosts:
            stage-db-01.company.com:
    
    # Funktionale Gruppierung
    frontend:
      hosts:
        prod-web-01.company.com:
        stage-web-01.company.com:
    backend:
      hosts:
        prod-db-01.company.com:
        stage-db-01.company.com:

56.2.3 Dynamische Inventories

56.2.3.1 AWS EC2 Plugin

Konfiguration:

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
  - eu-central-1
filters:
  - tag:Environment
  - instance-state-name: running
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: instance_type
    prefix: type
hostnames:
  - tag:Name
  - dns-name
compose:
  ansible_host: public_ip_address
  ec2_region: placement.region

Automatische Gruppierung:

Resultierende Gruppen:
├── env_production (basierend auf Environment-Tag)
├── env_staging
├── type_t3_medium (basierend auf Instance-Type)
├── type_t3_large
└── aws_ec2 (alle EC2-Instanzen)

56.2.3.2 Azure Resource Manager Plugin

Konfiguration:

# azure_rm.yml
plugin: azure.azcollection.azure_rm
auth_source: auto
include_vm_resource_groups:
  - rg-production
  - rg-staging
keyed_groups:
  - key: tags.environment | default('unknown')
    prefix: env
  - key: location
    prefix: location
conditional_groups:
  webservers: "'web' in tags.role"
  databases: "'db' in tags.role"

56.2.3.3 Google Cloud Platform Plugin

Konfiguration:

# gcp_compute.yml
plugin: google.cloud.gcp_compute
projects:
  - my-gcp-project
auth_kind: serviceaccount
service_account_file: /path/to/service-account.json
zones:
  - us-central1-a
  - europe-west1-b
keyed_groups:
  - key: labels.environment
    prefix: env
  - key: machineType
    prefix: type
filters:
  - status = RUNNING

56.2.4 Vorteile dynamischer Inventories

56.2.4.1 Skalierbarkeit

Automatische Anpassung:

56.2.4.2 Metadaten-Integration

Rich Information:

# Beispiel AWS EC2 Host-Variablen
ec2_ami_id: ami-0123456789abcdef0
ec2_architecture: x86_64
ec2_availability_zone: us-east-1a
ec2_instance_id: i-0123456789abcdef0
ec2_instance_type: t3.medium
ec2_region: us-east-1
ec2_security_groups:
  - web-tier-sg
  - ssh-access-sg
ec2_tags:
  Environment: production
  Team: backend
  Application: web-api

56.2.4.3 Konsistenz

Single Source of Truth:

56.3 Integration externer Systeme

56.3.1 Git-Repositories als Playbook-Quelle

56.3.1.1 Repository-Konfiguration

Git-Integration-Parameter:

Repository URL: https://github.com/company/ansible-playbooks.git
Branch: main
Deployment Key: semaphore-deploy-key
Auto-Update: Enabled
Webhook Support: Enabled
Authentication: SSH Keys oder Token-basiert

56.3.1.2 Repository-Struktur

Empfohlene Verzeichnisstruktur:

ansible-playbooks/
├── playbooks/
│   ├── webserver-deploy.yml
│   ├── database-backup.yml
│   └── system-update.yml
├── roles/
│   ├── nginx/
│   ├── mysql/
│   └── common/
├── inventories/
│   ├── production/
│   ├── staging/
│   └── development/
├── group_vars/
│   ├── webservers.yml
│   └── databases.yml
├── host_vars/
│   └── specific-server.yml
└── requirements.yml

56.3.1.3 Branching-Strategien

Environment- und Feature-Branches:

Git Repository:
├── main (production-ready)
├── staging (pre-production testing)
├── development (feature development)
├── feature/* (Feature-Branches für Tests)

Semaphore Projekte:
├── prod-project → main branch
├── staging-project → staging branch
├── dev-project → development branch
└── feature-project → feature branch

56.3.2 Synchronisation und Updates

56.3.2.1 Automatische Synchronisation

Webhook-Integration:

{
  "webhook_url": "https://semaphore.company.com/api/project/1/repository/sync",
  "events": ["push", "pull_request"],
  "branches": ["main", "staging"],
  "secret": "webhook-secret-token"
}

Scheduled Sync:

Sync-Intervall: 15 Minuten
Trigger: Cron-Expression "*/15 * * * *"
Aktion: Git pull + Dependency-Update

56.3.2.2 Update-Verhalten

Repository-Updates:

  1. Git-Repository wird geklont/aktualisiert
  2. Ansible-Dependencies werden installiert (requirements.yml)
  3. Syntax-Validierung der Playbooks
  4. Templates werden aktualisiert (falls konfiguriert)
  5. Benachrichtigung bei Fehlern

56.3.3 Versionskontrolle im Projektkontext

56.3.3.1 Git-basierte Versionierung

Commit-Tracking:

Template: "Deploy Web Application"
├── Playbook: playbooks/webserver-deploy.yml
├── Git Commit: a1b2c3d4e5f6789
├── Branch: main
├── Last Sync: 2024-08-15 14:30:00
└── Sync Status: Success

56.3.3.2 Tag-basierte Releases

Release-Management:

# Git-Tags für Releases
git tag -a v1.2.0 -m "Production Release 1.2.0"
git push origin v1.2.0

# Semaphore Template-Konfiguration
Playbook Branch/Tag: v1.2.0
Description: "Stable release for production deployment"

56.3.3.3 Rollback-Szenarien

Version-Rollback:

Fehlerhaftes Deployment:
1. Template auf vorherige Git-Version setzen
2. Rollback-Playbook ausführen
3. Repository auf bekannt-funktionierenden Commit zurücksetzen
4. Validierung der Wiederherstellung

56.4 Variablen-Management

56.4.1 Arten von Variablen

56.4.1.1 Globale Variablen

Scope: Organisationsweit verfügbar, in der Semaphore-Datenbank gespeichert Verwendung: Übergreifende Konfigurationen

# Globale Variablen
company_domain: "company.com"
backup_retention_days: 30
monitoring_server: "monitor.company.com"
log_level: "INFO"

56.4.1.2 Projektvariablen

Scope: Projektspezifisch (Datenbankeinträge in Semaphore) Verwendung: Projekt-relevante Konfigurationen

# Projekt: E-Commerce Backend
application_name: "ecommerce-backend"
deployment_environment: "production"
database_cluster: "prod-db-cluster"
api_version: "v2.1"
load_balancer_url: "https://api.ecommerce.company.com"

56.4.1.3 Inventory-Variablen

Scope: Host- oder gruppenspezifisch Verwendung: System-spezifische Konfigurationen (werden über Git-Sync in Semaphore geladen)

# Group Variables - webservers
nginx_worker_processes: 4
nginx_worker_connections: 1024
ssl_certificate_path: "/etc/ssl/certs/company.crt"
ssl_private_key_path: "/etc/ssl/private/company.key"

# Host Variables - web01.company.com
server_role: "primary"
nginx_worker_processes: 8  # Override group variable
backup_schedule: "0 2 * * *"

56.4.2 Variablen-Hierarchie

Prioritätsreihenfolge (niedrigste zu höchste Priorität):

1. Inventory file (group_vars/all)
2. Playbook group_vars/all
3. Inventory group_vars/*
4. Playbook group_vars/*
5. Inventory file (host_vars/*)
6. Playbook host_vars/*
7. Inventory file (host vars)
8. Inventory script (host vars)
9. Playbook vars
10. Template extra variables (in Semaphore definiert)
11. Command line variables (-e)

56.4.3 Umgebungsvariablen

56.4.3.1 Template-spezifische Umgebungsvariablen

Konfiguration in Templates:

# Template: Deploy Application
Environment Variables:
  ANSIBLE_HOST_KEY_CHECKING: "False"
  ANSIBLE_STDOUT_CALLBACK: "json"
  DEPLOYMENT_ENV: "production"
  LOG_LEVEL: "INFO"

56.4.3.2 System-Umgebungsvariablen

Semaphore-Service-Variablen:

# Environment für Semaphore-Service
export SEMAPHORE_DB_DIALECT=postgres
export SEMAPHORE_TMP_PATH=/tmp/semaphore
export ANSIBLE_CONFIG=/etc/ansible/ansible.cfg
export PATH=$PATH:/usr/local/bin

56.4.4 Secrets und Credentials im Variablenkontext

56.4.4.1 Credential-Integration in Variablen

Sichere Variablen-Nutzung:

# Template-Konfiguration
Extra Variables:
  db_host: "{{ database_hostname }}"
  db_port: "{{ database_port }}"
  # Credentials werden automatisch eingefügt
  db_user: "{{ credential.database_user }}"
  db_password: "{{ credential.database_password }}"

56.4.4.2 Variable Substitution

Credential-Ersetzung zur Laufzeit:

Template-Variable: api_key="{{ api_credential }}"
Credential-Name: external_api_key
Laufzeit-Ersetzung: api_key="abc123def456..."