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.
Kernelemente eines Projekts:
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
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:
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
Projekte pro Service/Anwendung:
Microservices-Umgebung:
├── user-service-ops
├── payment-service-ops
├── inventory-service-ops
├── notification-service-ops
└── shared-infrastructure
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
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.
Charakteristika:
Charakteristika:
Beispiel für Semaphore eigenes Plugin:
plugin: command
command: ./dynamic_inventory.sh# 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# 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# 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: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.regionAutomatische 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)
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"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 = RUNNINGAutomatische Anpassung:
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-apiSingle Source of Truth:
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
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
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
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
Repository-Updates:
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
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"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
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"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"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 * * *"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)
Konfiguration in Templates:
# Template: Deploy Application
Environment Variables:
ANSIBLE_HOST_KEY_CHECKING: "False"
ANSIBLE_STDOUT_CALLBACK: "json"
DEPLOYMENT_ENV: "production"
LOG_LEVEL: "INFO"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/binSichere 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 }}"Credential-Ersetzung zur Laufzeit:
Template-Variable: api_key="{{ api_credential }}"
Credential-Name: external_api_key
Laufzeit-Ersetzung: api_key="abc123def456..."