워크플로우
이 문서는 워크플로우 YAML의 모든 필드를 다뤄요.
입문자라면 첫 워크플로우부터 보시는 게 좋아요.
파일 규칙
- 위치: Agent의
./workflows/(기본) - 확장자:
.yaml또는.yml - 파일명 =
name필드 값 (예:deploy-prod.yaml안엔name: deploy-prod)
최상위 필드
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
name | string | ✓ | — | ^[a-z0-9][a-z0-9_-]{0,63}$ |
timeout-minutes | int | 60 | 전체 워크플로우 timeout | |
env | object | {} | 모든 step에 적용되는 환경변수 | |
secrets | string[] | [] | 마스킹할 환경변수 이름 목록 | |
log_retention | int | 20 | 로컬 로그 보관 개수 | |
force_allowed | bool | true | force 명령 허용 여부 | |
limits | object[] | [] | 레이트 리밋 규칙 (cooldown 1개 + bucket 1개) | |
steps | object[] | ✓ | — | 최소 1개 |
Step 필드
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
name | string | ✓ | — | ^[A-Za-z0-9][A-Za-z0-9 _.-]{0,63}$ |
run | string | ✓ | — | 실행할 셸 명령 (multi-line 가능) |
working-directory | string | (Agent 작업 폴더) | cd 후 실행 | |
env | object | {} | step별 환경변수 | |
timeout-minutes | int | 10 | step별 timeout | |
continue-on-error | bool | false | 실패해도 다음 step 진행 | |
log_level | enum | summary | silent / summary / verbose |
log_level 동작
| 값 | stdout/stderr 처리 | 서버 전송 |
|---|---|---|
silent | 화면에 안 보임 | 시스템 메시지만 |
summary | 라인 단위 요약 (level 자동 분류) | 요약만 |
verbose | 원본 그대로 보존 | 원본 보존 |
시크릿 값은 어떤 레벨에서도 ***로 마스킹돼요.
환경변수 우선순위
- Step의
env - 워크플로우의
env - Agent 프로세스 환경변수
같은 키가 여러 곳에 있으면 위쪽이 이겨요.
트리거 주입 변수
| 환경변수 | 의미 |
|---|---|
REF | 트리거 호출 시 ref 값 |
PARAMS_<KEY> | 트리거 호출 시 params.<key> 값 |
DEBUG | debug: true 호출 시 1 |
JOB_ID | 현재 Job의 UUID |
출력 (output)
마지막 step에서 stdout으로 단일 라인 JSON을 출력하면 Job의 output 필드로 저장돼요.
- name: Deploy
run: |
DEP_ID=$(deploy.sh)
echo "{\"deploymentId\":\"$DEP_ID\",\"url\":\"https://app.example.com\"}"대시보드와 API 응답에서 이 JSON을 그대로 받을 수 있어요.
레이트 리밋
자세한 동작은 제한과 정책에서 다뤄요.
limits:
- type: cooldown
after: 5m # 5분 쿨다운
on: success # success | any
- type: bucket
capacity: 3
refill: 1/10m # 10분마다 1개 충전한 워크플로우는 cooldown 1개, bucket 1개까지 가질 수 있어요.
시크릿
secrets:
- DATABASE_URL
- API_KEY여기 나열된 이름은 stdout에서 자동 마스킹되고, 어떤 경우에도 서버로 전송되지 않아요.
시크릿 값은 Agent 머신의 환경변수(/etc/deplite/agent.env 등)에서 주입하세요.
검증 규칙 모음
name: 위 정규식timeout-minutes: 1 이상, 1440 이하 권장limits.cooldown.after: Go duration (30s,5m,1h)limits.bucket.refill:<count>/<duration>(1/10m,5/1h)steps: 1개 이상
규칙을 어기면 Agent 시작 시 또는 워크플로우 보고 시 에러 로그가 남고, 해당 파일은 서버 카탈로그에서 제외돼요.
실전 레시피 모음
1) DB 야간 백업
name: backup-pg
timeout-minutes: 60
secrets:
- DATABASE_URL
- AWS_SECRET_ACCESS_KEY
limits:
- type: cooldown
after: 23h # 하루 1회만
steps:
- name: dump
run: |
pg_dump "$DATABASE_URL" | gzip > /tmp/backup.sql.gz
timeout-minutes: 30
- name: upload
run: |
aws s3 cp /tmp/backup.sql.gz \
s3://backups/pg/$(date +%F).sql.gz
timeout-minutes: 15
- name: cleanup
run: rm -f /tmp/backup.sql.gz
continue-on-error: true2) Docker 이미지 빌드·푸시·배포
name: deploy-myapp
timeout-minutes: 25
env:
IMAGE: registry.example.com/myapp
secrets:
- REGISTRY_PASSWORD
limits:
- type: cooldown
after: 2m
on: success
- type: bucket
capacity: 5
refill: 1/10m
steps:
- name: build
run: docker build -t $IMAGE:$REF .
timeout-minutes: 12
- name: push
run: |
echo "$REGISTRY_PASSWORD" | docker login -u deploy --password-stdin registry.example.com
docker push $IMAGE:$REF
timeout-minutes: 8
- name: rollout
run: |
kubectl set image deployment/myapp myapp=$IMAGE:$REF
kubectl rollout status deployment/myapp --timeout=5m
timeout-minutes: 6
- name: report
run: |
DEP_URL=$(kubectl get ingress myapp -o jsonpath='{.spec.rules[0].host}')
echo "{\"deployedRef\":\"$REF\",\"url\":\"https://$DEP_URL\"}"3) 외부 API → 데이터 웨어하우스 ETL
name: etl-orders
timeout-minutes: 45
secrets:
- SHOPIFY_TOKEN
- SNOWFLAKE_PWD
env:
WINDOW_HOURS: "24"
steps:
- name: extract
run: |
curl -H "X-Shopify-Access-Token: $SHOPIFY_TOKEN" \
"https://store.myshopify.com/admin/api/2024-01/orders.json?updated_at_min=$(date -d '24 hours ago' -Iseconds)" \
> /tmp/orders.json
timeout-minutes: 15
- name: transform
run: python3 /opt/etl/transform.py /tmp/orders.json /tmp/orders.parquet
timeout-minutes: 10
- name: load
run: python3 /opt/etl/load_snowflake.py /tmp/orders.parquet
env:
SNOWFLAKE_USER: deplite
SNOWFLAKE_ACCOUNT: ab12345.us-east-1
timeout-minutes: 204) 헬스체크 + 자동 복구
name: healthcheck
timeout-minutes: 5
limits:
- type: cooldown
after: 4m
on: any # 매번 5분 간격을 강제
steps:
- name: probe
run: |
if ! curl -fsS https://app.example.com/health > /dev/null; then
echo "UNHEALTHY"
exit 1
fi
echo "OK"
log_level: summary
- name: restart-if-failed
run: kubectl rollout restart deployment/myapp
continue-on-error: truelimits.cooldown.on: any로 실패해도 폭주가 막혀요. Cron 트리거를 1분 간격으로 걸어도 안전해요.
5) 디버그 환경 임시 부팅
name: spin-up-debug
timeout-minutes: 15
steps:
- name: launch
run: |
ID=$(docker run -d --rm -p 0:3000 myapp:debug)
HOST_PORT=$(docker port "$ID" 3000 | awk -F: '{print $2}')
echo "{\"containerId\":\"$ID\",\"url\":\"http://debug.internal:$HOST_PORT\"}"Webhook으로 호출 → 응답의 output.url을 그대로 Slack에 던질 수 있어요.
다음으로
최종 수정 일자: