Zabbix 인프라 모니터링 구축 – 10. 자동화: Zabbix API로 아이템·트리거 일괄 생성 (iLO·iDRAC)

2026.10.02

·

iLO와 iDRAC 수집 스크립트를 만들었다면, 다음은 Zabbix에 호스트와 수십 개의 아이템·트리거를 등록하는 작업입니다. UI에서 하나씩 클릭하는 대신 Zabbix API를 활용하면 스크립트 한 번으로 전체 구성을 완성할 수 있습니다.


Zabbix API 구조

Zabbix API는 JSON-RPC 2.0 프로토콜을 사용합니다. 모든 요청은 단일 엔드포인트로 전송됩니다:

POST https://zabbix서버:8080/api_jsonrpc.php
Content-Type: application/json

요청 형식:

Sponsored

{
  "jsonrpc": "2.0",
  "method": "host.create",
  "params": { ... },
  "auth": "인증토큰",
  "id": 1
}

인증 토큰 발급

import requests

ZABBIX_URL = "http://localhost:8080/api_jsonrpc.php"

def zabbix_api(method, params, token=None):
    payload = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1,
    }
    if token:
        payload["auth"] = token
    r = requests.post(ZABBIX_URL, json=payload, timeout=10)
    result = r.json()
    if "error" in result:
        raise RuntimeError(f"API Error: {result['error']}")
    return result["result"]

# 로그인
token = zabbix_api("user.login", {
    "username": "Admin",
    "password": "비밀번호"
})

Zabbix 7.0부터 user 대신 username 파라미터를 사용합니다. 구버전 자료를 참고할 때 주의하세요.


호스트 생성

def create_host(token, hostname, ip, group_id):
    return zabbix_api("host.create", {
        "host": hostname,
        "name": hostname,
        "interfaces": [{
            "type": 1,       # 1=Agent (Trapper는 인터페이스 타입 무관)
            "main": 1,
            "useip": 1,
            "ip": ip,
            "dns": "",
            "port": "10050"
        }],
        "groups": [{"groupid": str(group_id)}],
    }, token)

호스트 그룹 ID는 환경마다 다릅니다. 먼저 조회합니다:

groups = zabbix_api("hostgroup.get", {"output": ["groupid", "name"]}, token)
for g in groups:
    print(g["groupid"], g["name"])

아이템 생성

def create_item(token, hostid, key, name, vtype=0):
    params = {
        "hostid":       hostid,
        "name":         name,
        "key_":         key,
        "type":         2,       # 2 = Zabbix trapper
        "value_type":   vtype,   # 0=float, 1=string, 3=unsigned, 4=text
        "history":      "30d",
        "delay":        0,       # Trapper는 수집 주기 없음
    }
    # 문자열 타입은 trends 저장 불가 — 파라미터 자체를 제외해야 함
    if vtype not in (1, 4):
        params["trends"] = "365d"

    return zabbix_api("item.create", params, token)

trends 파라미터 주의: value_type이 1(string) 또는 4(text)인 아이템에 trends 파라미터를 포함하면 API가 오류를 반환합니다. 조건부로 제외해야 합니다.

value_type 값:

값타입용도
0Numeric (float)온도, 전력, 비율
1Character (string)짧은 문자열
3Numeric (unsigned)카운터, 상태값
4Text긴 문자열, JSON

iLO 아이템 일괄 생성 예시

ILO_ITEMS = [
    ("ilo.health.system",    "시스템 전체 헬스",      3),
    ("ilo.power.state",      "전원 상태",             3),
    ("ilo.health.cpu",       "CPU 헬스",              3),
    ("ilo.cpu.count",        "CPU 수",                3),
    ("ilo.health.memory",    "메모리 헬스",           3),
    ("ilo.memory.total_gb",  "메모리 전체 (GB)",      0),
    ("ilo.power.consumed",   "소비 전력 (W)",         0),
    ("ilo.power.capacity",   "전력 용량 (W)",         0),
    ("ilo.power.ps1.health", "PSU 1 헬스",            3),
    ("ilo.power.ps1.output", "PSU 1 출력 (W)",        0),
    ("ilo.power.ps2.health", "PSU 2 헬스",            3),
    ("ilo.power.ps2.output", "PSU 2 출력 (W)",        0),
]

host_result = create_host(token, "proxmox-idc-02-ilo", "10.0.92.112", group_id=27)
hostid = host_result["hostids"][0]

for key, name, vtype in ILO_ITEMS:
    create_item(token, hostid, key, name, vtype)
    print(f"  [OK] {key}")

온도·팬 센서처럼 서버마다 이름이 다른 동적 아이템은 수집 스크립트가 처음 데이터를 전송할 때 Zabbix에서 자동으로 인식되지 않습니다. 이 경우 먼저 스크립트를 한 번 실행해 어떤 키로 데이터가 전송되는지 확인한 뒤, 해당 키로 아이템을 등록합니다.


트리거 생성

Zabbix 7.0에서 트리거 생성 시 두 가지 함정이 있습니다.

함정 1: hostid 파라미터 불가

구버전 자료를 보면 trigger.create에 hostid를 넣는 예시가 있습니다. Zabbix 7.0에서는 이 파라미터가 없습니다. 호스트 정보는 expression 안에 포함됩니다:

# 잘못된 코드
zabbix_api("trigger.create", {
    "hostid": hostid,   # 오류: unexpected parameter
    "expression": "...",
    ...
})

# 올바른 코드
zabbix_api("trigger.create", {
    "expression": "last(/proxmox-idc-02-ilo/ilo.health.system) >= 2",
    ...
}, token)

함정 2: 트리거 표현식 포맷

3편에서 다뤘던 것처럼 Zabbix 7.0은 새 포맷만 허용합니다:

def create_trigger(token, hostname, key, name, expr, severity=2):
    # severity: 0=미분류, 1=정보, 2=경고, 3=보통, 4=심각, 5=재해
    return zabbix_api("trigger.create", {
        "description": name,
        "expression":  expr.format(host=hostname),
        "priority":    severity,
        "status":      0,  # 0=활성화
    }, token)

# 사용 예시
create_trigger(
    token,
    hostname="proxmox-idc-02-ilo",
    key="ilo.health.system",
    name="iLO: 시스템 헬스 이상",
    expr="last(/{host}/ilo.health.system) >= 2",
    severity=4,  # High
)

iLO/iDRAC 공통 트리거 목록

COMMON_TRIGGERS = [
    # (이름, 표현식, 심각도)
    ("시스템 헬스 Critical",
     "last(/{host}/ilo.health.system) >= 2",    4),  # High

    ("전원 OFF",
     "last(/{host}/ilo.power.state) = 0",       4),  # High

    ("CPU 헬스 이상",
     "last(/{host}/ilo.health.cpu) >= 1",       3),  # Average

    ("메모리 헬스 이상",
     "last(/{host}/ilo.health.memory) >= 1",    3),  # Average

    ("PSU 1 이상",
     "last(/{host}/ilo.power.ps1.health) >= 1", 4),  # High

    ("PSU 2 이상",
     "last(/{host}/ilo.power.ps2.health) >= 1", 4),  # High

    ("소비 전력 과다 (500W 초과)",
     "last(/{host}/ilo.power.consumed) > 500",  2),  # Warning
]

iLO와 iDRAC의 키 이름 앞부분(ilo. / idrac.)만 다르고 구조는 동일합니다. 공통 트리거 목록을 만들고 prefix만 교체하면 재사용할 수 있습니다.


전체 자동화 흐름

def setup_ilo_host(token, site_key, cfg, group_id):
    hostname = cfg["zabbix_host"]
    ip       = cfg["ilo_host"]

    # 1. 호스트 생성
    result = create_host(token, hostname, ip, group_id)
    hostid = result["hostids"][0]
    print(f"[OK] 호스트 생성: {hostname} (ID: {hostid})")

    # 2. 아이템 생성
    for key, name, vtype in ILO_ITEMS:
        create_item(token, hostid, key, name, vtype)
    print(f"[OK] 아이템 {len(ILO_ITEMS)}개 생성")

    # 3. 트리거 생성
    for tname, expr, severity in COMMON_TRIGGERS:
        create_trigger(token, hostname, "", tname,
                       expr.replace("{host}", hostname), severity)
    print(f"[OK] 트리거 {len(COMMON_TRIGGERS)}개 생성")

# 실행
token = zabbix_api("user.login", {"username": "Admin", "password": "pw"})
for site_key, cfg in HOSTS.items():
    setup_ilo_host(token, site_key, cfg, group_id=27)

API 사용 시 자주 보는 오류

오류 메시지원인해결
No permissions to referred object해당 호스트/그룹 접근 권한 없음Admin 계정 사용 확인
unexpected parameter "hostid"trigger.create에 hostid 포함파라미터 제거
Invalid parameter "trends"string 타입 아이템에 trends 설정vtype 1·4이면 trends 제외
Invalid parameter "username"구버전 user 파라미터 사용username으로 변경
Trigger expression ... is incorrect구버전 트리거 표현식 포맷신규 포맷으로 변경

마치며

이번 편에서 다룬 핵심 포인트입니다:

  • Zabbix API는 JSON-RPC 2.0 — 단일 엔드포인트로 모든 요청
  • string/text 타입 아이템은 trends 파라미터 제외 필수
  • trigger.create에 hostid 파라미터 없음 — 표현식에 호스트명 직접 포함
  • Zabbix 7.0 트리거 표현식: last(/hostname/key) >= 값
  • iLO와 iDRAC은 키 prefix만 다르고 트리거 구조 동일 — 재사용 가능

다음 편에서는 OPNsense 방화벽 모니터링을 다룹니다.


MORE POSTS

다른 글 보기

테크 랩

PMBOK 완독기 – 00. 오리엔테이션: 왜 정석을 완독하나 + 6판·7판 지도

PMBOK을 목차대로 완독하며 IT 현장에 번역하는 시리즈 시작. 6판(10지식영역)·7판(원칙·테일러링) 지도와 15편 로드맵.
2026.10.22
guniq 인사이트 썸네일 — 중소기업 OpenLDAP 통합 인증 구축 – 07. 백업·로그·운영 자동화: 장애 없는 LDAP 서버 유지하기
테크 랩

중소기업 OpenLDAP 통합 인증 구축 – 07. 백업·로그·운영 자동화: 장애 없는 LDAP 서버 유지하기

LDAP 서버는 설치 후가 더 중요합니다. 데이터 유실을 막는 백업 전략(daily/weekly/monthly), slapd 로그 관리와 logrotate 설정, 헬스체크 자동화까지 — 실제 운영 중인 스크립트를 바탕으로 LDAP 서버를 안정적으로 유지하는 방법을 정리합니다.
2026.10.21
guniq 인사이트 썸네일 — 중소기업 OpenLDAP 통합 인증 구축 – 06. Synology NAS LDAP 연동: DSM 설정과 그룹 권한 매핑
테크 랩

중소기업 OpenLDAP 통합 인증 구축 – 06. Synology NAS LDAP 연동: DSM 설정과 그룹 권한 매핑

Synology DSM의 LDAP 클라이언트를 커스텀 프로파일로 설정하는 방법을 정리합니다. groupPosixAux 필터, memberUid 매핑, LDAPS 인증서 처리까지 — 표준을 지킨 LDAP 구조가 NAS 연동을 얼마나 단순하게 만드는지 확인합니다.
2026.10.20

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.

무료 3분 자가진단

우리 회사, 자체 클라우드가 답일까?

AWS vs 자체 인프라 · 11개 항목 3분 체크