Semaphore UI: 현대적인 DevOps 자동화 플랫폼 완전 가이드
⏱️ 예상 읽기 시간: 15분
서론
DevOps 작업이 복잡해지고 팀 규모가 커질수록, 터미널에서의 수동 배포는 더 이상 실용적이지 않습니다. Semaphore UI는 이러한 문제를 해결하는 현대적인 웹 인터페이스로, Ansible, Terraform/OpenTofu, PowerShell 등 다양한 DevOps 도구들을 하나의 통합된 플랫폼에서 관리할 수 있게 해줍니다.
12.2k 스타를 받은 이 오픈소스 프로젝트는 MIT 라이선스로 제공되며, Jenkins나 AWX의 복잡함 없이도 강력한 자동화 기능을 제공합니다. 특히 직관적인 UI와 강력한 API를 통해 개발팀과 운영팀 모두가 쉽게 사용할 수 있는 것이 가장 큰 장점입니다.
이번 튜토리얼에서는 macOS에서 Docker를 사용한 설치부터 실제 Ansible playbook과 Terraform 코드 실행까지 단계별로 진행하겠습니다.
Semaphore UI 핵심 개념
🎯 주요 특징
- 멀티 도구 지원: Ansible, Terraform, OpenTofu, Terragrunt, PowerShell, Bash
- 웹 기반 관리: 브라우저에서 모든 DevOps 작업 관리
- 알림 시스템: 실패한 작업에 대한 즉시 알림
- 접근 제어: 세밀한 권한 관리 시스템
- 스케줄링: 자동화된 작업 실행
- API 우선: RESTful API로 모든 기능 제어 가능
📊 핵심 구성 요소
구성 요소 | 설명 | 역할 |
---|---|---|
Projects | 관련 리소스와 작업의 모음 | 프로젝트별 구성 관리 |
Task Templates | 재사용 가능한 작업 정의 | 표준화된 작업 실행 |
Tasks | 실제 실행되는 작업 인스턴스 | 작업 실행 및 모니터링 |
Schedules | 자동화된 작업 스케줄 | 정기적 작업 실행 |
Inventory | 대상 호스트 관리 | 배포 대상 서버 정의 |
Variable Groups | 환경 변수 및 비밀 정보 | 설정 및 보안 관리 |
🏗️ 시스템 아키텍처
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Web Browser │ │ Semaphore UI │ │ Target Hosts │
│ (Users) │◄──►│ (Web Server) │◄──►│ (Inventory) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
┌──────────────────┐
│ DevOps Tools │
│ Ansible|Terraform│
│ PowerShell|Bash │
└──────────────────┘
설치 및 초기 설정
1단계: 시스템 요구사항 확인
# Docker 설치 확인
docker --version
# Docker Compose 확인 (필요시)
docker-compose --version
# 포트 3000 사용 가능 확인
lsof -i :3000
최소 시스템 요구사항:
- Docker: 20.10 이상
- 메모리: 2GB 이상 (4GB 권장)
- 디스크: 10GB 이상
- 네트워크: 인터넷 연결 (패키지 다운로드용)
2단계: Docker로 Semaphore UI 설치
기본 설치 (SQLite 사용):
# Semaphore UI 컨테이너 실행
docker run -d \
--name semaphore \
-p 3000:3000 \
-e SEMAPHORE_DB_DIALECT=bolt \
-e SEMAPHORE_ADMIN=admin \
-e SEMAPHORE_ADMIN_PASSWORD=changeme \
-e SEMAPHORE_ADMIN_NAME="Admin User" \
-e SEMAPHORE_ADMIN_EMAIL=admin@localhost \
-v semaphore-data:/tmp/semaphore \
semaphoreui/semaphore:latest
프로덕션 설정 (MySQL 사용):
# docker-compose.yml 생성
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
mysql:
image: mysql:8.0
hostname: mysql
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_DATABASE: semaphore
MYSQL_USER: semaphore
MYSQL_PASSWORD: semaphore_password
volumes:
- mysql-data:/var/lib/mysql
restart: unless-stopped
semaphore:
image: semaphoreui/semaphore:latest
hostname: semaphore
ports:
- "3000:3000"
environment:
SEMAPHORE_DB_USER: semaphore
SEMAPHORE_DB_PASS: semaphore_password
SEMAPHORE_DB_HOST: mysql
SEMAPHORE_DB_PORT: 3306
SEMAPHORE_DB_DIALECT: mysql
SEMAPHORE_DB: semaphore
SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore/
SEMAPHORE_ADMIN_PASSWORD: changeme
SEMAPHORE_ADMIN_NAME: "Admin"
SEMAPHORE_ADMIN_EMAIL: admin@localhost
SEMAPHORE_ADMIN: admin
SEMAPHORE_ACCESS_KEY_ENCRYPTION: gs72mPntFATGJs9qK1pQ0UI5sI6J42MSh
volumes:
- semaphore-data:/tmp/semaphore
depends_on:
- mysql
restart: unless-stopped
volumes:
mysql-data:
semaphore-data:
EOF
# 서비스 시작
docker-compose up -d
3단계: 웹 인터페이스 접속
# 컨테이너 상태 확인
docker ps | grep semaphore
# 로그 확인
docker logs semaphore
# 웹 인터페이스 접속
echo "http://localhost:3000에서 Semaphore UI에 접속하세요"
echo "초기 로그인: admin / changeme"
첫 번째 프로젝트 설정
프로젝트 생성
웹 인터페이스에 접속한 후:
- 좌측 메뉴에서 “Projects” 클릭
- “New Project” 버튼 클릭
- 프로젝트 정보 입력:
Name: "Demo Infrastructure"
Description: "Ansible과 Terraform을 활용한 인프라 자동화"
Max Parallel Tasks: 5
Key Store 설정
1. SSH 키 등록:
# SSH 키 생성 (필요시)
ssh-keygen -t rsa -b 4096 -C "semaphore@localhost" -f ~/.ssh/semaphore_key
# 공개키 내용 복사
cat ~/.ssh/semaphore_key.pub
웹 UI에서:
- Key Store > New Key 클릭
- Type: SSH Key
- Name:
demo-ssh-key
- Private Key: 개인키 내용 붙여넣기
2. 환경 변수 설정:
Type: Environment
Name: demo-env-vars
Variables:
AWS_REGION: us-west-2
ENVIRONMENT: development
LOG_LEVEL: info
Inventory 설정
정적 인벤토리 생성:
# inventory.yml 내용
[webservers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
web2 ansible_host=192.168.1.11 ansible_user=ubuntu
[dbservers]
db1 ansible_host=192.168.1.20 ansible_user=ubuntu
[all:vars]
ansible_ssh_private_key_file=/tmp/semaphore/demo-ssh-key
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
웹 UI에서:
- Inventory > New Inventory 클릭
- Name:
demo-inventory
- Type: Static
- Inventory: 위 내용 입력
Ansible 플레이북 실행
Repository 연결
1. Git Repository 설정:
# 테스트용 플레이북 리포지토리 생성
mkdir -p ~/semaphore-demo/playbooks
cd ~/semaphore-demo
# 기본 플레이북 생성
cat > playbooks/site.yml << 'EOF'
---
- name: Web Server Setup
hosts: webservers
become: yes
tasks:
- name: Update apt cache
apt:
update_cache: yes
when: ansible_os_family == "Debian"
- name: Install nginx
package:
name: nginx
state: present
- name: Start and enable nginx
service:
name: nginx
state: started
enabled: yes
- name: Create custom index.html
copy:
content: |
<html>
<head><title>Deployed by Semaphore</title></head>
<body>
<h1>Hello from </h1>
<p>Deployed at: </p>
</body>
</html>
dest: /var/www/html/index.html
mode: '0644'
notify: reload nginx
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
- name: Database Server Setup
hosts: dbservers
become: yes
tasks:
- name: Install MySQL
package:
name: mysql-server
state: present
- name: Start MySQL service
service:
name: mysql
state: started
enabled: yes
EOF
# requirements.yml 생성
cat > requirements.yml << 'EOF'
---
collections:
- name: community.general
version: ">=3.0.0"
- name: ansible.posix
EOF
# Git 초기화
git init
git add .
git commit -m "Initial Ansible playbooks"
2. Semaphore에서 Repository 추가:
웹 UI에서:
- Key Store > New Key 클릭
- Type: Repository
- Name:
demo-ansible-repo
- Git URL:
file:///Users/$(whoami)/semaphore-demo
(로컬) 또는 GitHub URL - Branch:
main
Task Template 생성
웹 서버 배포 템플릿:
Name: "Deploy Web Servers"
Description: "Nginx 웹 서버 설치 및 설정"
Type: Task
Repository: demo-ansible-repo
Playbook: playbooks/site.yml
Inventory: demo-inventory
Environment: demo-env-vars
Extra Variables:
environment: production
nginx_port: 80
실행 옵션:
- ✅ Allow Override Args in Task
- ✅ Limit Hosts
- ✅ Diff Mode
- ✅ Verbose Mode
작업 실행 및 모니터링
# 웹 UI에서 Task Template 실행
# 또는 API를 통한 실행
curl -X POST http://localhost:3000/api/project/1/tasks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"template_id": 1,
"environment": {"debug": "true"}
}'
실행 결과 모니터링:
- 실시간 로그 확인
- 작업 진행 상태 추적
- 성공/실패 알림
- 실행 시간 및 리소스 사용량
Terraform 프로젝트 설정
Terraform 리포지토리 준비
# Terraform 프로젝트 생성
mkdir -p ~/semaphore-demo/terraform/aws-vpc
cd ~/semaphore-demo/terraform/aws-vpc
# main.tf 생성
cat > main.tf << 'EOF'
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
description = "AWS region"
type = string
default = "us-west-2"
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "vpc_cidr" {
description = "VPC CIDR block"
type = string
default = "10.0.0.0/16"
}
# VPC 생성
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
ManagedBy = "Semaphore"
}
}
# 서브넷 생성
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-subnet-${count.index + 1}"
Environment = var.environment
Type = "Public"
}
}
# 데이터 소스
data "aws_availability_zones" "available" {
state = "available"
}
# 인터넷 게이트웨이
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.environment}-igw"
Environment = var.environment
}
}
# 라우팅 테이블
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${var.environment}-public-rt"
Environment = var.environment
}
}
# 라우팅 테이블 연결
resource "aws_route_table_association" "public" {
count = length(aws_subnet.public)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# 출력
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "IDs of the public subnets"
value = aws_subnet.public[*].id
}
output "vpc_cidr" {
description = "CIDR block of the VPC"
value = aws_vpc.main.cidr_block
}
EOF
# 버전 관리
git add .
git commit -m "Add Terraform AWS VPC configuration"
Terraform Task Template 생성
인프라 배포 템플릿:
Name: "Deploy AWS VPC"
Description: "Terraform으로 AWS VPC 인프라 생성"
Type: Task
Repository: demo-terraform-repo
Playbook: terraform/aws-vpc/
Environment: aws-credentials
Extra Variables:
environment: staging
vpc_cidr: "10.1.0.0/16"
aws_region: "us-east-1"
AWS 자격증명 설정:
Type: Environment
Name: aws-credentials
Variables:
AWS_ACCESS_KEY_ID: "YOUR_ACCESS_KEY"
AWS_SECRET_ACCESS_KEY: "YOUR_SECRET_KEY"
TF_VAR_environment: "staging"
고급 기능 활용
1. 스케줄 작업 설정
매일 백업 작업:
Name: "Daily Database Backup"
Cron Expression: "0 2 * * *" # 매일 새벽 2시
Task Template: "Database Backup"
Active: true
주간 인프라 상태 점검:
Name: "Weekly Infrastructure Health Check"
Cron Expression: "0 9 * * 1" # 매주 월요일 오전 9시
Task Template: "Infrastructure Audit"
2. 알림 설정
Slack 통합:
# Slack 웹훅 URL 설정
curl -X POST http://localhost:3000/api/project/1/integrations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"name": "Slack Notifications",
"type": "slack",
"url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
"settings": {
"channel": "#devops",
"username": "Semaphore",
"icon_emoji": ":robot_face:"
}
}'
이메일 알림:
SMTP Settings:
Host: smtp.gmail.com
Port: 587
Username: notifications@yourcompany.com
Password: app_password
From: "Semaphore <semaphore@yourcompany.com>"
3. 멀티 환경 관리
환경별 인벤토리:
# 개발 환경
cat > inventories/development.yml << 'EOF'
[webservers]
dev-web1 ansible_host=dev.web1.internal
dev-web2 ansible_host=dev.web2.internal
[all:vars]
environment=development
debug_mode=true
EOF
# 스테이징 환경
cat > inventories/staging.yml << 'EOF'
[webservers]
staging-web1 ansible_host=staging.web1.internal
staging-web2 ansible_host=staging.web2.internal
[all:vars]
environment=staging
debug_mode=false
EOF
# 프로덕션 환경
cat > inventories/production.yml << 'EOF'
[webservers]
prod-web1 ansible_host=prod.web1.internal
prod-web2 ansible_host=prod.web2.internal
prod-web3 ansible_host=prod.web3.internal
[all:vars]
environment=production
debug_mode=false
enable_monitoring=true
EOF
4. 승인 워크플로우
프로덕션 배포 승인 설정:
# 커스텀 훅 스크립트 (Python)
#!/usr/bin/env python3
import requests
import sys
import json
def require_approval(task_data):
"""프로덕션 환경 배포 시 승인 요구"""
if task_data.get('environment') == 'production':
# Slack으로 승인 요청 전송
slack_webhook = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
message = {
"text": f"🚨 Production deployment approval required",
"attachments": [{
"color": "warning",
"fields": [
{"title": "Task", "value": task_data.get('template_name'), "short": True},
{"title": "User", "value": task_data.get('user_name'), "short": True},
{"title": "Environment", "value": "Production", "short": True}
],
"actions": [{
"type": "button",
"text": "Approve",
"url": f"http://localhost:3000/project/1/tasks/{task_data.get('task_id')}/approve"
}]
}]
}
requests.post(slack_webhook, json=message)
return False # 승인 대기
return True # 즉시 실행
if __name__ == "__main__":
task_data = json.loads(sys.argv[1])
if not require_approval(task_data):
sys.exit(1) # 승인 대기로 작업 중단
API 활용 및 자동화
RESTful API 사용
인증 토큰 생성:
# API 토큰 생성
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"auth": "admin",
"password": "changeme"
}'
# 응답에서 토큰 추출
export SEMAPHORE_TOKEN="eyJhbGciOiJIUzI1NiIsInR..."
작업 실행 API:
#!/usr/bin/env python3
import requests
import json
import time
class SemaphoreClient:
def __init__(self, base_url, token):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def run_task(self, project_id, template_id, variables=None):
"""작업 실행"""
payload = {
'template_id': template_id,
'environment': variables or {}
}
response = requests.post(
f'{self.base_url}/api/project/{project_id}/tasks',
headers=self.headers,
json=payload
)
if response.status_code == 201:
task = response.json()
print(f"Task started: {task['id']}")
return task['id']
else:
print(f"Failed to start task: {response.text}")
return None
def get_task_status(self, project_id, task_id):
"""작업 상태 확인"""
response = requests.get(
f'{self.base_url}/api/project/{project_id}/tasks/{task_id}',
headers=self.headers
)
if response.status_code == 200:
return response.json()
return None
def wait_for_completion(self, project_id, task_id, timeout=1800):
"""작업 완료 대기"""
start_time = time.time()
while time.time() - start_time < timeout:
task = self.get_task_status(project_id, task_id)
if task:
status = task.get('status')
print(f"Task {task_id} status: {status}")
if status in ['success', 'error', 'stopped']:
return status
time.sleep(10)
print(f"Task {task_id} timed out")
return 'timeout'
# 사용 예시
client = SemaphoreClient('http://localhost:3000', 'YOUR_TOKEN')
# 웹 서버 배포 실행
task_id = client.run_task(
project_id=1,
template_id=1,
variables={
'nginx_version': '1.20',
'ssl_enabled': 'true'
}
)
if task_id:
# 완료 대기
result = client.wait_for_completion(1, task_id)
print(f"Deployment result: {result}")
CI/CD 파이프라인 통합
GitHub Actions 워크플로우:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy via Semaphore
run: |
TASK_ID=$(curl -s -X POST $/api/project/1/tasks \
-H "Authorization: Bearer $" \
-H "Content-Type: application/json" \
-d '{
"template_id": 1,
"environment": {
"git_commit": "$",
"branch": "$",
"deployed_by": "$"
}
}' | jq -r '.id')
echo "Started deployment task: $TASK_ID"
echo "TASK_ID=$TASK_ID" >> $GITHUB_ENV
- name: Wait for deployment
run: |
# 배포 완료까지 대기하는 스크립트
python3 scripts/wait_for_semaphore_task.py \
--url $ \
--token $ \
--project-id 1 \
--task-id $TASK_ID
모니터링 및 로깅
작업 실행 모니터링
실시간 로그 스트리밍:
#!/usr/bin/env python3
import websocket
import json
def on_message(ws, message):
"""실시간 로그 메시지 처리"""
try:
data = json.loads(message)
if data.get('type') == 'log':
print(f"[{data.get('time')}] {data.get('message')}")
elif data.get('type') == 'status':
print(f"Status changed to: {data.get('status')}")
except json.JSONDecodeError:
print(f"Raw message: {message}")
def on_error(ws, error):
print(f"WebSocket error: {error}")
def on_close(ws, close_status_code, close_msg):
print("WebSocket connection closed")
# WebSocket 연결
ws = websocket.WebSocketApp(
"ws://localhost:3000/api/project/1/tasks/1/output",
header=["Authorization: Bearer YOUR_TOKEN"],
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever()
성능 메트릭 수집
Prometheus 메트릭 노출:
# docker-compose.yml에 추가
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
Prometheus 설정:
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'semaphore'
static_configs:
- targets: ['semaphore:3000']
metrics_path: '/api/metrics'
bearer_token: 'YOUR_API_TOKEN'
보안 및 권한 관리
사용자 및 팀 관리
팀 생성 및 권한 설정:
# 개발팀 생성
curl -X POST http://localhost:3000/api/users \
-H "Authorization: Bearer $SEMAPHORE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Development Team",
"username": "dev-team",
"email": "dev-team@company.com",
"password": "secure_password",
"admin": false
}'
# 프로젝트 권한 부여
curl -X POST http://localhost:3000/api/project/1/users \
-H "Authorization: Bearer $SEMAPHORE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": 2,
"role": "manager"
}'
권한 레벨:
- Admin: 모든 권한
- Manager: 프로젝트 관리 및 작업 실행
- Task Runner: 작업 실행만 가능
- Guest: 읽기 전용
비밀 정보 관리
HashiCorp Vault 통합:
#!/usr/bin/env python3
import hvac
import os
def get_vault_secrets():
"""Vault에서 비밀 정보 조회"""
client = hvac.Client(url='https://vault.company.com')
client.token = os.environ['VAULT_TOKEN']
# AWS 자격증명 조회
aws_secrets = client.secrets.kv.v2.read_secret_version(
path='aws/production'
)
return {
'AWS_ACCESS_KEY_ID': aws_secrets['data']['data']['access_key'],
'AWS_SECRET_ACCESS_KEY': aws_secrets['data']['data']['secret_key']
}
# Semaphore 환경 변수로 설정
secrets = get_vault_secrets()
for key, value in secrets.items():
# API를 통해 환경 변수 그룹 업데이트
pass
문제 해결 가이드
자주 발생하는 이슈
1. 작업 실행 실패:
# 로그 확인
docker logs semaphore
# 디스크 공간 확인
docker system df
# 컨테이너 재시작
docker restart semaphore
2. SSH 연결 문제:
# SSH 키 권한 확인
ls -la ~/.ssh/semaphore_key
# 올바른 권한 설정
chmod 600 ~/.ssh/semaphore_key
# SSH 연결 테스트
ssh -i ~/.ssh/semaphore_key user@target-host
3. 메모리 부족:
# docker-compose.yml에서 메모리 제한 설정
services:
semaphore:
mem_limit: 2g
memswap_limit: 2g
디버깅 모드
상세 로그 활성화:
# 환경 변수 추가
docker run -d \
--name semaphore \
-e SEMAPHORE_LOG_LEVEL=debug \
-e SEMAPHORE_LOG_FORMAT=json \
# ... 기타 설정
성능 프로파일링:
# Go 프로파일링 활성화
curl http://localhost:3000/debug/pprof/goroutine?debug=1
# 메모리 사용량 확인
curl http://localhost:3000/debug/pprof/heap?debug=1
실제 운영 사례
1. 마이크로서비스 배포 파이프라인
서비스별 배포 템플릿:
# Frontend 서비스
Name: "Deploy Frontend"
Playbook: playbooks/frontend-deploy.yml
Variables:
service_name: frontend
image_tag: ""
replicas: 3
# Backend API 서비스
Name: "Deploy Backend API"
Playbook: playbooks/backend-deploy.yml
Variables:
service_name: backend-api
database_migration: true
health_check_timeout: 300
# 전체 스택 배포
Name: "Deploy Full Stack"
Dependencies: ["Deploy Backend API", "Deploy Frontend"]
2. 인프라 자동 확장
Auto Scaling 설정:
#!/usr/bin/env python3
# 자동 확장 스크립트
import boto3
import requests
def check_load_and_scale():
"""로드 확인 후 자동 확장"""
cloudwatch = boto3.client('cloudwatch')
# CPU 사용률 확인
response = cloudwatch.get_metric_statistics(
Namespace='AWS/EC2',
MetricName='CPUUtilization',
Dimensions=[
{'Name': 'AutoScalingGroupName', 'Value': 'web-servers-asg'}
],
StartTime=datetime.utcnow() - timedelta(minutes=10),
EndTime=datetime.utcnow(),
Period=300,
Statistics=['Average']
)
avg_cpu = sum(d['Average'] for d in response['Datapoints']) / len(response['Datapoints'])
# 임계값 초과 시 확장 작업 실행
if avg_cpu > 80:
# Semaphore API를 통해 확장 작업 실행
requests.post(
'http://localhost:3000/api/project/1/tasks',
headers={'Authorization': f'Bearer {SEMAPHORE_TOKEN}'},
json={
'template_id': 5, # Scale Out Template
'environment': {'desired_capacity': '6'}
}
)
3. 재해 복구 자동화
백업 및 복구 프로세스:
# 일일 백업 스케줄
Name: "Daily Backup"
Cron: "0 1 * * *"
Tasks:
1. Database Backup
2. File System Backup
3. Configuration Backup
4. Backup Verification
# 재해 복구 템플릿
Name: "Disaster Recovery"
Steps:
1. Validate Backup Integrity
2. Provision New Infrastructure
3. Restore Database
4. Restore Application Files
5. Update DNS Records
6. Verify Service Health
결론
Semaphore UI는 현대적인 DevOps 워크플로우를 위한 강력하고 직관적인 플랫폼입니다. 복잡한 설정 없이도 Ansible, Terraform, PowerShell 등 다양한 도구들을 통합 관리할 수 있으며, 웹 기반 인터페이스를 통해 팀 전체가 쉽게 활용할 수 있습니다.
🏆 주요 장점 요약
- 통합 플랫폼: 여러 DevOps 도구를 하나의 인터페이스에서 관리
- 사용자 친화적: 직관적인 웹 UI로 학습 곡선 최소화
- 확장성: API 우선 설계로 무한 확장 가능
- 보안: 세밀한 권한 관리와 비밀 정보 보호
- 자동화: 스케줄링과 알림으로 완전 자동화 지원
🚀 추천 활용 시나리오
- 스타트업: 복잡한 CI/CD 도구 없이 빠른 배포 파이프라인 구축
- 중소기업: 기존 Jenkins 대체로 유지보수 부담 감소
- 엔터프라이즈: 다양한 팀이 사용하는 통합 배포 플랫폼
- DevOps 팀: Ansible과 Terraform 작업의 중앙화된 관리
MIT 라이선스의 완전 오픈소스 프로젝트인 Semaphore UI로, 더 안전하고 효율적인 DevOps 워크플로우를 지금 바로 구축해보세요!
참고 자료:
태그: #SemaphoreUI
#DevOps
#Ansible
#Terraform
#Docker
#CI-CD
#Automation