# pyinfra — 에이전트 없는 인프라 자동화, 순수 Python으로

> Clean Markdown view of GeekNews topic #30519. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=30519](https://news.hada.io/topic?id=30519)
- GeekNews Markdown: [https://news.hada.io/topic/30519.md](https://news.hada.io/topic/30519.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-06-16T09:10:45+09:00
- Updated: 2026-06-16T09:10:45+09:00
- Original source: [pyinfra.com](https://pyinfra.com)
- Points: 1
- Comments: 1

## Topic Body

- 서버 자동화 작업을 **Python 코드**로 작성하고 SSH로 병렬 실행해, 에이전트 없이 명령을 멱등적으로 수행함
- pyinfra는 동일 워크로드에서 **Ansible보다 6배 빠름**을 내세우며, gevent와 SSH 기반 동시 실행을 사용함
- `--dry` 옵션으로 적용 전 호스트별 변경 diff를 확인하고, 실제 실행 시 결과가 **병렬 스트리밍**으로 돌아옴
- 대상 호스트에는 **shell과 SSH**만 필요하며, 데몬·상태 파일·컨트롤 플레인이 없음
- YAML로 제어 흐름을 인코딩하지 않고 Python의 루프와 조건문을 그대로 쓰는 **코드 중심 구성**을 강조함

---

### 핵심 기능과 실행 흐름
- ## 수천 대 서버 자동화
  - **pyinfra**는 Python-native, agentless 자동화 도구이며 SSH로 명령을 실행함
  - 명령 실행은 동시성, 멱등성, 속도를 강조하며, 동일 워크로드에서 **Ansible보다 6배 빠름**을 내세움
  - 설치 명령은 `$ uv tool install pyinfra`임
  - 표기된 기본 조건은 MIT license, Python 3.10 이상, no agents, zero config임
- ## 배포 코드 예시
  - `apt`, `files`, `systemd` 작업을 Python 코드로 불러와 패키지 설치, 템플릿 배치, 서비스 재로드를 수행함
  - 예시 코드는 `nginx`와 `certbot` 패키지를 설치하고, `templates/nginx.conf.j2`를 `/etc/nginx/sites-enabled/api`로 배치함
  - 마지막 단계에서 `systemd.service("nginx", reloaded=True)`로 `nginx` 서비스를 재로드함
  ```python
  from pyinfra.operations import apt, files, systemd
  
  apt.packages(
      packages=["nginx", "certbot"],
      update=True,
  )
  
  files.template(
      src="templates/nginx.conf.j2",
      dest="/etc/nginx/sites-enabled/api",
  )
  
  systemd.service("nginx", reloaded=True)
  ```
- ## 인벤토리와 실행 결과
  - 인벤토리 예시는 `web-01.prod`부터 `web-23.prod`까지의 웹 호스트와 `db-01.prod`, `db-02.prod` 데이터베이스 호스트를 구성함
  - `$ pyinfra inventory.py deploy.py --limit web` 명령은 `web` 대상만 제한해 실행함
  - 실행 출력은 인벤토리 로딩, 동시 fact 수집, `deploy.py` 실행, 요약 순서로 진행됨
  - 예시 요약은 23개 호스트 성공, 18개 변경, 실패 0개, 총 2.1초를 기록함
- ## 변경 전 확인
  - `--dry`는 pyinfra가 수행할 모든 작업의 **호스트별 diff**를 먼저 확인하게 함
  - 실제 실행에서는 결과가 병렬로 스트리밍되어 각 호스트의 변경 수와 실행 시간이 표시됨
  - 예시 실행은 24개 호스트 중 18개 변경, 6개 무변경, 실패 0개, 총 2.1초를 기록함

### 특징, Ansible 비교, 원칙
- ## pyinfra를 선택하는 여섯 가지 이유
  - **Just Python**: YAML과 Jinja-in-YAML 없이 실제 제어 흐름을 Python으로 작성함
  - **Concurrent SSH**: gevent와 SSH 기반으로 동시 실행하며, 동일 워크로드에서 Ansible보다 6배 빠름
  - **Diff before apply**: `--dry`로 모든 변경을 미리 보고, 멱등 작업은 재실행 시 no-op이 됨
  - **0 agents**: 호스트에는 shell과 SSH만 필요하며, 데몬·상태 파일·컨트롤 플레인이 없음
  - **Scale-ready**: 1개 호스트부터 10,000개 호스트까지 동작하고, 병렬 실행과 실시간 스트리밍 출력을 지원함
  - **Hackable**: 10줄로 커스텀 작업을 만들 수 있고, shell과 통신하는 docker, lxc, k8s에 연결할 수 있음
- ## Ansible과 pyinfra 코드 비교
  - Ansible 예시는 `playbook.yml` 16줄로 `nginx` 설치, 템플릿 렌더링, 핸들러 기반 서비스 재로드를 구성함
  - pyinfra 예시는 `deploy.py` 8줄로 같은 흐름을 Python 코드로 작성함
  - pyinfra 예시는 `files.template` 결과의 `cfg.will_change`가 참일 때만 `systemd.service("nginx", reloaded=True)`를 실행함
  ```python
  from pyinfra.operations import apt, files, systemd
  
  apt.packages(["nginx"], update=True)
  
  cfg = files.template(
      src="nginx.conf.j2",
      dest="/etc/nginx/sites-enabled/api",
  )
  if cfg.will_change:
      systemd.service("nginx", reloaded=True)
  ```
- ## 선언문
  - **Code > config**: 루프는 루프 그대로이며, 제어 흐름을 YAML에 인코딩하지 않음
  - **Show, then do**: diff를 먼저 보고, 그다음 적용해 예기치 않은 변경을 피함
  - **Stay out of the way**: 에이전트, 상태 파일, 컨트롤 플레인 없이 SSH로 바로 실행함
  - **Read like english**: 작업은 `apt.packages`, `files.template`, `systemd.service`처럼 명사와 동사 형태로 읽힘
- ## 시작 명령
  - 설치 명령은 `$ uv tool install pyinfra`임
  - 5분 quickstart를 읽고 첫 호스트를 배포하라는 안내가 제공됨

## Comments



### Comment 59715

- Author: neo
- Created: 2026-06-16T09:10:46+09:00
- Points: 1

###### [Lobste.rs 의견들](https://lobste.rs/s/htfm3p/pyinfra_agentless_infrastructure) 
- **pyinfra**는 Ansible이 원래 이렇게 됐어야 한다는 느낌임. 템플릿 섞인 YAML에 제어 흐름을 덧붙이는 대신, 자동화를 Python으로 직접 작성할 수 있음  
  Ansible을 오래 다뤄온 뒤라 신선했고, 딱히 Ansible을 싫어하던 입장도 아니었음
  - 정확히는 Python으로 된 Ansible이라기보다는 **Python에서 셸로 변환하는 인터프리터**에 가까워 보이고, 그 나름의 문제가 있음  
    대상 서버에서도 Python을 쓰는 하이브리드가 더 나을 듯함. 파일 갱신 때 따옴표 지옥이 줄고, `sed`의 정규식 한계 같은 것도 피할 수 있기 때문임

- **pyinfra**를 좋아하고 더 널리 쓰였으면 좋겠음  
  지금까지 일한 회사들은 모두 Terraform 병행 여부와 관계없이 Ansible을 썼고, 직원들이 경험 없는 도구로 기존 자동화를 전부 다시 작성할 준비가 된 곳은 없었음  
  pyinfra는 SysOps가 Python을 알아야 하는데, 개인적으로는 SysOps가 스크립트 언어 하나쯤은 알아야 한다고 봄. 특히 Ansible에서도 Python으로 모듈을 작성하면 YAML 난장판을 줄일 수 있지만, 적어도 프랑스에서는 흔한 생각은 아닌 듯함
  - Ansible을 많이 써봤는데, 사실상 **스크립트 언어를 가장한 것**이라고 봄  
    그렇게까지 뜨거운 논쟁거리는 아닐 수도 있음

- 홈랩에서 Ansible을 쓰다가 점점 답답해졌음. YAML 설정은 끔찍하고, 모든 게 해킹처럼 느껴졌고, 속도도 슬펐음. 셸 명령 몇 개 실행하려고 서버에 `python3`가 필요한 것도 납득이 안 됐음  
  Google AI Mode 덕분에 `pyinfra`를 알게 됐고, 거의 한 달 써본 범위에서는 훨씬 상쾌했음. 장점은 Ansible보다 훨씬 빠르고, 반복과 조건을 Python으로 짤 수 있으며, 역할과 중첩 디렉터리 없이 서버에는 셸만 있으면 된다는 점임. 실행 전에 현재 상태 기반으로 계획을 만들고 `-y`를 안 주면 확인도 받음  
  단점은 기본 작업들이 Ansible 모듈에 비해 작은 부분집합이고, 코드가 금방 스파게티가 될 수 있으며, `if 'web_server' in hosts.groups` 같은 방식도 썩 좋지는 않다는 것임. `operation(..., filter_group='web_server')`가 더 나은지도 모르겠음  
  가장 나쁜 점은 **커스텀 커넥터 작성**이 너무 괴롭다는 것임. `pyinfra` 전용 entry point가 들어간 `pyproject.toml`이 필요해 보이고, `uv`를 써도 사내 커넥터 개발이 악몽 같음. 그냥 프로젝트 안의 일반 Python 파일로 만들 수 있어야 함

- 며칠 동안 pyinfra를 홈랩 배포 도구에 시험 중인데, Ansible과 비교해 지금까지 가장 마음에 든 건 Python 문법보다 **속도**임  
  Ansible은 항상 참을 수 없을 만큼 느리게 느껴졌음
  - 이 영역이 흥미로움. 나도 배포 도구를 만들고 있고, 본업에서 실제 배포에 쓰고 있음  
    대부분의 곳에서 Ansible과 Salt 사용을 대체하고 싶음

- **코드형 인프라**가 한 바퀴 돈 게 재미있음. 스크립트에서 YAML로 갔다가 다시 더 정교한 스크립트로 돌아왔음  
  접근마다 적당한 지점이 있고, Ansible 사용자 관점에서 pyinfra는 꽤 좋아 보임
  - 계속 [configuration complexity clock](https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html)을 도는 중임

- Ansible을 채택하게 된 핵심 이유는 **드라이런과 차이 보기 모드**였음. 예상 밖의 작업을 하지 않을 거라고 확신할 수 있었기 때문임  
  그런데 [pyinfra CLI에는 그런 옵션이 없어 보임](https://docs.pyinfra.com/en/3.x/cli.html). 모든 옵션을 알파벳순으로 정리한 참조 문서를 못 찾아서 놓쳤을 수도 있음
  - `—dry` 플래그가 있고, pyinfra 첫 화면에 바로 나와 있음

- 관심 있는 사람에게는 비슷한 14년 된 내 프로젝트도 있음: https://github.com/sebastien/cuisine/tree/main  
  에이전트 없이 SSH만 쓰고, 핵심 관리 기능 위에 Python다운 API를 얹었지만 드라이 모드는 지원하지 않음

- 우리는 OpenStack에서 리소스를 프로비저닝할 때 Ansible을 쓰고, 나머지는 **pyinfra**로 처리하는데 지난 몇 년간 꽤 잘 동작했음  
  가장 큰 단점은 커뮤니티가 작아서 직접 해결책을 작성하게 된다는 점임. 예를 들어 배포에 필요한 공유 비밀은 keyring + privy로 디스크에 보관하고, OpenStack 컴퓨트 인벤터리를 hosts 데이터로 바꾸는 몇 줄의 코드를 직접 씀
