Operating System

CentOS 종료 이후 Rocky Linux / AlmaLinux 9에서 Ansible 설치하고 첫 플레이북 실행하기

나크나로·2026년 6월 21일·조회 4

테스트 환경: Rocky Linux 9.5 / AlmaLinux 9.5, 2026-06 기준. 저장소 상태에 따라 패키지 버전 번호는 달라질 수 있다.

CentOS Linux 8은 2021-12-31, CentOS Linux 7은 2024-06-30에 종료됐다. 이제 CentOS 이름으로 남은 것은 RHEL 상류인 CentOS Stream이고, 예전 CentOS Linux처럼 쓰려면 Rocky Linux나 AlmaLinux 같은 무료 RHEL 호환 배포판을 쓰는 쪽이 현실적이다.

Rocky Linux 9.5 / AlmaLinux 9.5, 즉 EL9에서는 운영 안정성이 우선이면 dnf install ansible-core 또는 EPEL의 dnf install ansible을 권한다. 최신 Ansible이나 특정 버전 고정이 필요하면 시스템 Python에 바로 깔지 말고 가상환경에서 pip로 설치한다. 다만 pip 방식은 Python 버전 요구사항을 반드시 같이 봐야 한다.

CentOS에서 yum install ansible 한 줄로 끝내던 시절이 있었다. sarc에도 그때 정리해 둔 CentOS 기준 설치 글이 있다. 그런데 CentOS Linux가 끝나면서 그 방식은 그대로 쓰기 어려워졌다. 패키지 매니저는 dnf로 바뀌었고, 기준 배포판도 Rocky Linux와 AlmaLinux로 넘어왔다. 그래서 같은 작업을 EL9 기준으로 다시 정리한다.

CentOS 종료 후 Rocky Linux와 AlmaLinux 선택

CentOS Linux는 더 이상 예전 방식으로 이어지지 않는다. CentOS Linux 8은 2021-12-31에, CentOS Linux 7은 2024-06-30에 EOL이 됐다. 지금의 CentOS Stream은 RHEL의 상류 배포판이라, 예전 CentOS Linux처럼 "RHEL 호환 운영 서버" 느낌으로 쓰던 것과는 위치가 다르다.

무료 RHEL 호환 대안은 Rocky Linux 또는 AlmaLinux를 선택한다. 둘 다 RHEL 9 호환이라 패키지 이름, dnf 사용법, Python 버전, Ansible 설치 방식까지 사실상 같다. 아래 예시는 Rocky Linux 9.5에서 실행했지만 AlmaLinux 9.5도 동일하다.

EL9에서 먼저 확인할 것은 무엇인가?

실제로 작업하기 전에 OS 버전과 Python 버전부터 본다. EL9 계열은 기본 Python이 3.9이고, 패키지 매니저는 dnf다. yum 명령도 동작하지만 내부적으로는 dnf 별칭이다.

$ cat /etc/os-release
NAME="Rocky Linux"
VERSION="9.5 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.5"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.5 (Blue Onyx)"

$ python3 --version
Python 3.9.21

$ dnf --version
4.14.0

AlmaLinux라면 출력만 이렇게 다르다.

$ cat /etc/os-release
NAME="AlmaLinux"
VERSION="9.5 (Teal Serval)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.5"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.5 (Teal Serval)"

여기서 중요한 점은 Ansible은 제어 노드(control node)에만 설치한다는 것이다. 관리 대상 서버(managed node)에는 Python과 SSH 접속만 준비되어 있으면 된다. 처음 Ansible을 만질 때 대상 서버마다 ansible 패키지를 설치하는 경우가 있는데, 그럴 필요 없다. 단, 관리 대상 서버에서 dnf 작업을 실행하려면 Python뿐 아니라 become, 즉 sudo 권한도 필요하다.

Rocky Linux 9.5 / AlmaLinux 9.5의 Ansible 설치 방식

EL9에서 Ansible 설치는 세 갈래다.

  • 운영 안정성 우선, 엔진만 필요: AppStream에서 ansible-core 설치
  • 컬렉션 포함 전체 패키지 필요: EPEL 활성화 후 ansible 설치
  • 최신 기능 또는 특정 버전 고정 필요: Python 가상환경에서 pip 설치

내 기준으로는 서버 운영 자동화의 기본 도구로 깔 때는 먼저 ansible-core를 본다. 네트워크 장비, 클라우드, 벤더 모듈 등 컬렉션이 많이 필요한 환경이면 EPEL의 ansible 패키지를 쓴다. 프로젝트별로 Ansible 버전을 고정해야 하면 그때만 가상환경 + pip로 간다.

방법 1: AppStream에서 ansible-core 설치

가장 단순하고 안정적인 방식이다. Ansible 2.10에서 컬렉션 분리가 시작됐고, 이후 ansible-core는 실행 엔진 중심 패키지, ansible은 여러 컬렉션을 포함한 메타패키지 성격으로 정리됐다.

$ sudo dnf install ansible-core
Last metadata expiration check: 0:12:31 ago on Fri 19 Jun 2026 10:20:44 AM KST.
Dependencies resolved.
================================================================================
 Package              Architecture   Version                 Repository    Size
================================================================================
Installing:
 ansible-core         x86_64         2.16.14-1.el9           appstream    3.2 M

Transaction Summary
================================================================================
Install  1 Package

Total download size: 3.2 M
Installed size: 18 M
Is this ok [y/N]: y
Downloading Packages:
ansible-core-2.16.14-1.el9.x86_64.rpm                4.2 MB/s | 3.2 MB     00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1
  Installing       : ansible-core-2.16.14-1.el9.x86_64                      1/1
  Verifying        : ansible-core-2.16.14-1.el9.x86_64                      1/1

Installed:
  ansible-core-2.16.14-1.el9.x86_64

Complete!

설치 확인은 바로 한다.

$ ansible --version
ansible [core 2.16.14]
  config file = None
  configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/admin/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.21

여기서 한 가지를 짚고 가야 한다. EL9의 시스템 Python은 3.9인데, PyPI의 ansible-core 2.16/2.17은 제어 노드 Python 3.10 이상을 요구하고, ansible-core 2.18은 Python 3.11 이상을 요구한다. 그런데 dnf로 설치한 EL9용 ansible-core 2.16은 Python 3.9에서 동작한다. Red Hat 계열 배포판이 플랫폼 Python에 맞게 패키지를 백포트해서 제공하기 때문이다. 즉 RPM으로 설치한 ansible-core 2.16PyPI에서 pip로 설치하는 ansible-core 2.16은 Python 요구사항을 똑같이 보면 안 된다.

이 방식은 서버 기본 설정, 패키지 설치, 서비스 관리 같은 일반적인 자동화에 충분하다. 단, 특정 컬렉션이 필요한 playbook을 가져와 돌리면 모듈을 못 찾는 에러가 날 수 있다.

ERROR! couldn't resolve module/action 'community.general.ufw'. This often indicates a misspelling, missing collection, or incorrect module path.

이 경우에는 필요한 컬렉션을 따로 설치하거나, 처음부터 EPEL의 full 패키지 방식을 쓰는 편이 낫다.

방법 2: EPEL에서 컬렉션 포함 ansible 패키지 설치

여러 컬렉션이 같이 필요한 환경이면 EPEL을 켜고 ansible 패키지를 설치한다. EL9에서도 full ansible 패키지는 AppStream이 아니라 EPEL에 있다. 옛 CentOS에서 "No package available"이 뜨면 epel-release부터 깔던 것과 같다.

Rocky Linux 9.5 / AlmaLinux 9.5에서는 EPEL 패키지 의존성 때문에 CRB 저장소가 필요할 수 있다. 먼저 CRB를 켠다. 환경에 따라 둘 중 하나를 쓰면 된다.

$ sudo dnf config-manager --set-enabled crb

# 또는
$ sudo crb enable

그 다음 EPEL을 설치한다.

$ sudo dnf install epel-release
Last metadata expiration check: 0:05:10 ago on Fri 19 Jun 2026 10:36:12 AM KST.
Dependencies resolved.
================================================================================
 Package              Architecture   Version              Repository       Size
================================================================================
Installing:
 epel-release         noarch         9-9.el9              extras           19 k

Transaction Summary
================================================================================
Install  1 Package

Is this ok [y/N]: y
Downloading Packages:
epel-release-9-9.el9.noarch.rpm                       110 kB/s |  19 kB     00:00
Running transaction
  Installing       : epel-release-9-9.el9.noarch                         1/1
  Verifying        : epel-release-9-9.el9.noarch                         1/1

Installed:
  epel-release-9-9.el9.noarch

Complete!

그 다음 ansible을 설치한다.

$ sudo dnf install ansible
Extra Packages for Enterprise Linux 9 - x86_64          18 MB/s |  25 MB     00:01
Dependencies resolved.
================================================================================
 Package              Architecture   Version                 Repository    Size
================================================================================
Installing:
 ansible              noarch         9.13.0-1.el9            epel          45 M
Installing dependencies:
 ansible-core         x86_64         2.16.14-1.el9           appstream     3.2 M

Transaction Summary
================================================================================
Install  2 Packages

Total download size: 48 M
Installed size: 390 M
Is this ok [y/N]: y
Downloading Packages:
ansible-core-2.16.14-1.el9.x86_64.rpm                 3.9 MB/s | 3.2 MB     00:00
ansible-9.13.0-1.el9.noarch.rpm                        11 MB/s |  45 MB     00:04
Running transaction
  Preparing        :                                                        1/1
  Installing       : ansible-core-2.16.14-1.el9.x86_64                      1/2
  Installing       : ansible-9.13.0-1.el9.noarch                            2/2
  Verifying        : ansible-9.13.0-1.el9.noarch                            1/2
  Verifying        : ansible-core-2.16.14-1.el9.x86_64                      2/2

Installed:
  ansible-9.13.0-1.el9.noarch  ansible-core-2.16.14-1.el9.x86_64

Complete!

확인 출력은 ansible-core만 설치했을 때와 비슷하다. Ansible 명령 자체는 core 엔진을 보고한다.

$ ansible --version
ansible [core 2.16.14]
  config file = None
  configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/admin/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.21

여기서 자주 보는 함정은 EPEL을 안 켜고 바로 dnf install ansible을 치는 경우다. 저장소 상태에 따라 이런 식으로 나온다.

$ sudo dnf install ansible
Last metadata expiration check: 0:01:40 ago on Fri 19 Jun 2026 10:40:22 AM KST.
No match for argument: ansible
Error: Unable to find a match: ansible

이때는 ansible이라는 이름을 붙잡고 repo 파일을 뒤질 게 아니라, CRB와 EPEL을 확인한 뒤 재시도하면 된다.

방법 3: pip로 최신 Ansible 또는 특정 버전 설치

가능하다. 다만 시스템 Python에 바로 밀어 넣는 방식은 추천하지 않는다. 운영 서버에서 나중에 dnf 패키지와 pip 패키지가 섞이면 장애 분석할 때 피곤하다. 프로젝트별로 버전을 묶으려면 가상환경을 만든다.

여기서 가장 중요한 차이가 있다. EL9의 시스템 Python은 3.9다. 그런데 PyPI(pip)의 ansible-core는 제어 노드 Python 요구사항이 더 높다. ansible-core 2.16/2.17은 Python 3.10 이상, ansible-core 2.18은 Python 3.11 이상을 요구한다. 반면 앞에서 본 것처럼 dnf(RPM)로 설치한 ansible-core 2.16은 EL9의 Python 3.9에서 동작한다. Red Hat 계열이 플랫폼 Python용으로 백포트해서 제공하기 때문이다.

그래서 pip로 설치할 때는 둘 중 하나를 선택한다.

  • 최신 Ansible 사용: EL9에 Python 3.11을 추가 설치하고 그 Python으로 venv 생성
  • 시스템 Python 3.9 유지: Python 3.9를 지원하는 Ansible 버전으로 고정

선택 A: Python 3.11 venv에서 최신 Ansible 설치

최신 Ansible을 쓰고 싶다면 Python 3.11을 설치한 뒤 그 Python으로 가상환경을 만든다.

$ sudo dnf install python3.11 python3.11-pip
Last metadata expiration check: 0:09:21 ago on Fri 19 Jun 2026 10:44:03 AM KST.
Dependencies resolved.
================================================================================
 Package              Architecture   Version                 Repository    Size
================================================================================
Installing:
 python3.11           x86_64         3.11.9-7.el9            appstream     28 k
 python3.11-pip       noarch         22.3.1-5.el9            appstream    2.8 M

Transaction Summary
================================================================================
Install  2 Packages

Is this ok [y/N]: y
...
Complete!
$ python3.11 -m venv ~/venv/ansible
$ source ~/venv/ansible/bin/activate
(ansible) $ python -m pip install --upgrade pip
Successfully installed pip-25.1.1

(ansible) $ python -m pip install ansible
Collecting ansible
  Downloading ansible-11.7.0-py3-none-any.whl
Collecting ansible-core~=2.18.0
  Downloading ansible_core-2.18.6-py3-none-any.whl
Installing collected packages: ansible-core, ansible
Successfully installed ansible-11.7.0 ansible-core-2.18.6

가상환경에서 설치한 경우에는 어떤 ansible을 실행 중인지 꼭 확인한다. 실제로 해보면 PATH 때문에 dnf로 설치한 /usr/bin/ansible을 실행하고 있다고 착각하는 일이 있다.

(ansible) $ which ansible
/home/admin/venv/ansible/bin/ansible

(ansible) $ ansible --version
ansible [core 2.18.6]
  config file = None
  ansible python module location = /home/admin/venv/ansible/lib64/python3.11/site-packages/ansible
  executable location = /home/admin/venv/ansible/bin/ansible
  python version = 3.11.9

선택 B: 시스템 Python 3.9를 유지하고 호환 버전으로 고정

EL9의 기본 Python 3.9를 그대로 쓰려면 최신 ansible을 그대로 설치하면 안 된다. Python 3.9를 지원하는 범위로 고정한다. 예를 들어 ansible 8.x는 ansible-core 2.15.x 계열을 사용하므로 Python 3.9에서 설치할 수 있다.

$ sudo dnf install python3-pip
Last metadata expiration check: 0:10:02 ago on Fri 19 Jun 2026 10:52:10 AM KST.
Dependencies resolved.
================================================================================
 Package              Architecture   Version                 Repository    Size
================================================================================
Installing:
 python3-pip          noarch         21.3.1-1.el9            appstream    2.0 M

Transaction Summary
================================================================================
Install  1 Package

Is this ok [y/N]: y
...
Complete!
$ python3 -m venv ~/venv/ansible39
$ source ~/venv/ansible39/bin/activate
(ansible39) $ python -m pip install --upgrade pip
Successfully installed pip-25.1.1

(ansible39) $ python -m pip install 'ansible<9'
Collecting ansible<9
  Downloading ansible-8.7.0-py3-none-any.whl
Collecting ansible-core~=2.15.7
  Downloading ansible_core-2.15.13-py3-none-any.whl
Installing collected packages: ansible-core, ansible
Successfully installed ansible-8.7.0 ansible-core-2.15.13
(ansible39) $ which ansible
/home/admin/venv/ansible39/bin/ansible

(ansible39) $ ansible --version
ansible [core 2.15.13]
  config file = None
  ansible python module location = /home/admin/venv/ansible39/lib64/python3.9/site-packages/ansible
  executable location = /home/admin/venv/ansible39/bin/ansible
  python version = 3.9.21

가상환경을 쓰지 않고 사용자 영역에만 설치하려면 아래 명령도 가능하다. 다만 이 방식도 Python 버전 요구사항을 피하지 못한다. EL9 기본 Python 3.9라면 마찬가지로 호환 버전으로 고정해야 한다.

$ python3 -m pip install --user 'ansible<9'

이 경우 ~/.local/bin이 PATH에 없으면 바로 실행이 안 된다.

$ ansible --version
bash: ansible: command not found

$ echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ ansible --version
ansible [core 2.15.13]

첫 인벤토리 파일 작성

테스트용 디렉터리를 하나 만들고, ini 형식 인벤토리를 작성한다. 여기서는 제어 노드에서 관리 대상 서버 192.168.56.21, 192.168.56.22로 SSH 접속한다고 가정한다.

$ mkdir -p ~/ansible-test
$ cd ~/ansible-test

$ cat > inventory.ini <<'EOF'
[web]
web01 ansible_host=192.168.56.21 ansible_user=admin
web02 ansible_host=192.168.56.22 ansible_user=admin
EOF

$ cat inventory.ini
[web]
web01 ansible_host=192.168.56.21 ansible_user=admin
web02 ansible_host=192.168.56.22 ansible_user=admin

SSH 키가 아직 없다면 제어 노드에서 키를 만들고 대상 서버에 복사한다. 아래처럼 passphrase 없이 만드는 방식은 실습 기준이다. 운영에서는 ssh-agent를 쓰고, 전용 자동화 계정과 제한된 sudoers 정책을 함께 설계하는 편을 권한다.

$ ssh-keygen -t ed25519 -C admin@control
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/admin/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/admin/.ssh/id_ed25519
Your public key has been saved in /home/admin/.ssh/id_ed25519.pub

$ ssh-copy-id admin@192.168.56.21
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/admin/.ssh/id_ed25519.pub"
Number of key(s) added: 1

$ ssh-copy-id admin@192.168.56.22
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/admin/.ssh/id_ed25519.pub"
Number of key(s) added: 1

처음 붙는 서버라면 host key 확인 때문에 멈춘다. 한두 대 테스트면 직접 yes를 입력하고, 자동화 환경이면 known_hosts를 미리 관리한다.

$ ssh admin@192.168.56.21 hostname
The authenticity of host '192.168.56.21 (192.168.56.21)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.56.21' (ED25519) to the list of known hosts.
web01

Ansible ping 모듈로 접속 확인은 어떻게 하나?

인벤토리가 준비되면 ping 모듈로 SSH와 Python 동작을 확인한다. 여기서 말하는 ping은 ICMP ping이 아니라 Ansible 모듈 실행 테스트다.

$ ansible -i inventory.ini web -m ping
web01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
web02 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

관리 대상 서버에 Python이 없거나 경로를 못 찾으면 이런 에러가 난다.

web01 | FAILED! => {
    "changed": false,
    "module_stderr": "/bin/sh: line 1: /usr/bin/python3: No such file or directory\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}

EL9 서버라면 보통 Python 3가 있지만, 최소 설치나 특수 이미지에서는 빠져 있을 수 있다. 대상 서버에 접속해서 Python을 설치한다.

$ ssh admin@192.168.56.21
[admin@web01 ~]$ sudo dnf install python3
Dependencies resolved.
================================================================================
 Package              Architecture   Version                 Repository    Size
================================================================================
Installing:
 python3              x86_64         3.9.21-2.el9            baseos        28 k

Transaction Summary
================================================================================
Install  1 Package

Is this ok [y/N]: y
...
Complete!

SSH 사용자나 sudo 권한 문제도 자주 걸린다. 이런 출력이면 Ansible 문제가 아니라 SSH 인증 또는 계정 문제다.

web01 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: admin@192.168.56.21: Permission denied (publickey,password).",
    "unreachable": true
}

이때는 먼저 Ansible을 빼고 순수 SSH로 확인한다.

$ ssh admin@192.168.56.21 whoami
admin

첫 플레이북으로 패키지 설치

이제 간단한 플레이북을 만든다. 예시는 web 그룹에 vim-enhanced 패키지를 설치하는 작업이다. EL9에서는 패키지 모듈로 dnf를 쓴다. 관리 노드에서 dnf를 실행하는 작업이므로 become: true와 sudo 권한이 필요하다.

$ cat > site.yml <<'EOF'
---
- name: First Ansible playbook on EL9
  hosts: web
  become: true
  tasks:
    - name: Install vim-enhanced
      ansible.builtin.dnf:
        name: vim-enhanced
        state: present
EOF

$ cat site.yml
---
- name: First Ansible playbook on EL9
  hosts: web
  become: true
  tasks:
    - name: Install vim-enhanced
      ansible.builtin.dnf:
        name: vim-enhanced
        state: present

문법 검사는 습관처럼 한다.

$ ansible-playbook -i inventory.ini site.yml --syntax-check

playbook: site.yml

실행한다.

$ ansible-playbook -i inventory.ini site.yml

PLAY [First Ansible playbook on EL9] *******************************************

TASK [Gathering Facts] *********************************************************
ok: [web01]
ok: [web02]

TASK [Install vim-enhanced] ****************************************************
changed: [web01]
changed: [web02]

PLAY RECAP *********************************************************************
web01                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web02                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

한 번 더 실행하면 이미 설치되어 있으므로 changed가 0이 된다. 이게 Ansible을 쓰는 이유 중 하나다. 같은 플레이북을 여러 번 돌려도 목표 상태에 맞춰진다.

$ ansible-playbook -i inventory.ini site.yml

PLAY [First Ansible playbook on EL9] *******************************************

TASK [Gathering Facts] *********************************************************
ok: [web01]
ok: [web02]

TASK [Install vim-enhanced] ****************************************************
ok: [web01]
ok: [web02]

PLAY RECAP *********************************************************************
web01                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web02                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

sudo 비밀번호가 필요한 서버에서는 어떻게 실행하나?

관리 대상 서버에서 admin 사용자가 sudo 비밀번호를 요구하는 경우, 그냥 실행하면 이런 에러가 난다.

TASK [Install vim-enhanced] ****************************************************
fatal: [web01]: FAILED! => {
    "msg": "Missing sudo password"
}

이 경우 -K 옵션을 붙인다. 대문자 K다.

$ ansible-playbook -i inventory.ini site.yml -K
BECOME password:

PLAY [First Ansible playbook on EL9] *******************************************
...
PLAY RECAP *********************************************************************
web01                      : ok=2    changed=1    unreachable=0    failed=0
web02                      : ok=2    changed=1    unreachable=0    failed=0

운영 자동화에서는 매번 비밀번호를 치는 구조가 불편하다. sudo 비밀번호를 Vault에 넣는 것보다 먼저 전용 자동화 계정과 최소권한 sudoers 정책을 정리하는 쪽이 우선이다. Vault는 필요한 비밀값을 안전하게 보관하는 도구이지, 과한 sudo 권한을 정당화하는 도구가 아니다. 처음 테스트 단계에서는 -K로 원인을 분리하는 게 빠르다.

ansible-core와 ansible 선택 기준

내 추천은 간단하다.

  • OS 기본 설정, 패키지, 서비스, 파일 배포 정도: sudo dnf install ansible-core
  • 여러 컬렉션을 포함한 일반적인 Ansible 전체 패키지: sudo dnf config-manager --set-enabled crb, sudo dnf install epel-releasesudo dnf install ansible
  • 최신 버전, 프로젝트별 버전 고정, 테스트랩: Python 가상환경 생성 후 pip로 설치. 최신 Ansible은 Python 3.11 venv, 시스템 Python 3.9 유지 시에는 python3 -m pip install 'ansible<9'

운영 서버의 기본값으로는 dnf 설치가 관리하기 쉽다. pip 설치는 버전 선택권이 넓지만, 어디에 설치됐는지와 어떤 Python을 물고 있는지까지 같이 관리해야 한다.

자주 만나는 에러 정리

dnf install ansible이 안 보이는 경우

EPEL이 없어서 그렇다. EL9 기본 AppStream에는 ansible-core가 있고, full 패키지인 ansible은 EPEL을 통해 설치한다. Rocky Linux 9.5 / AlmaLinux 9.5에서는 CRB도 같이 확인한다.

$ sudo dnf config-manager --set-enabled crb
$ sudo dnf install epel-release
$ sudo dnf install ansible

pip install ansible이 Python 버전 오류로 실패하는 경우

EL9 기본 Python 3.9에서 PyPI의 최신 ansible을 설치하려 해서 그렇다. 최신 ansible 11.x / ansible-core 2.18.x를 쓰려면 Python 3.11 venv를 만든다.

$ sudo dnf install python3.11 python3.11-pip
$ python3.11 -m venv ~/venv/ansible
$ source ~/venv/ansible/bin/activate
(ansible) $ python -m pip install ansible

시스템 Python 3.9를 유지해야 한다면 호환 버전으로 고정한다.

$ python3 -m venv ~/venv/ansible39
$ source ~/venv/ansible39/bin/activate
(ansible39) $ python -m pip install 'ansible<9'

ansible 명령이 command not found인 경우

pip --user 설치 후 ~/.local/bin이 PATH에 없을 때 흔하다.

$ echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ which ansible
/home/admin/.local/bin/ansible

ping 모듈이 SSH Permission denied로 실패하는 경우

Ansible 문제가 아니다. 먼저 SSH 단독으로 접속되는지 본다.

$ ssh admin@192.168.56.21 hostname

여기서 안 되면 인벤토리의 ansible_user, SSH 키, 대상 서버의 authorized_keys, 방화벽, sshd 상태를 먼저 봐야 한다.

Missing sudo password가 나오는 경우

플레이북에 become: true가 있는데 sudo 비밀번호를 넘기지 않은 것이다.

$ ansible-playbook -i inventory.ini site.yml -K

운영에서는 sudo 비밀번호를 저장하는 방향보다, 전용 자동화 계정에 필요한 명령만 허용하는 최소권한 sudoers 구성이 먼저다.

예전 CentOS 기준 yum 설치 글은 여기서 볼 수 있다: /articles/yum-ansible-centos

자주 묻는 질문 (FAQ)

CentOS Linux 종료 후 Ansible 제어 노드는 무엇으로 바꾸는 게 좋은가?

예전 CentOS Linux처럼 RHEL 호환 서버를 원하면 Rocky Linux 또는 AlmaLinux가 현실적인 대안이다. CentOS Stream은 현재 RHEL 상류 배포판이므로 위치가 다르다.

Rocky Linux 9와 AlmaLinux 9에서 yum install ansible을 써도 되나?

EL9에서는 dnf를 기준으로 쓰는 것이 맞다. yum도 dnf 별칭으로 동작하지만, 문서와 운영 절차는 dnf install ansible-core 또는 EPEL 활성화 후 dnf install ansible로 적는 게 낫다.

ansible-core와 ansible 패키지의 차이는 무엇인가?

Ansible 2.10에서 컬렉션 분리가 시작됐고, 이후 ansible-core는 실행 엔진 중심 패키지, ansible은 여러 컬렉션을 포함한 메타패키지 성격으로 정리됐다. 기본 서버 자동화는 ansible-core로 충분한 경우가 많고, 컬렉션이 많이 필요하면 ansible 패키지를 설치한다.

관리 대상 서버에도 Ansible을 설치해야 하나?

아니다. Ansible은 제어 노드에만 설치한다. 관리 대상 서버에는 SSH 접속과 Python 실행 환경이 있으면 된다. 패키지 설치나 서비스 변경처럼 권한이 필요한 작업에는 sudo, 즉 become 권한도 필요하다.

최신 Ansible을 쓰려면 dnf와 pip 중 무엇을 써야 하나?

운영 안정성이 우선이면 dnf 설치를 권한다. 최신 기능이나 특정 버전 고정이 필요하면 시스템 Python에 직접 설치하지 말고 Python 가상환경을 만든 뒤 pip로 ansible을 설치한다. 단, EL9 기본 Python 3.9에서는 PyPI의 최신 ansible-core 요구사항을 만족하지 못하므로, 최신 ansible 11.x / ansible-core 2.18.x는 Python 3.11 venv에서 설치한다. Python 3.9를 유지해야 한다면 python3 -m pip install 'ansible<9'처럼 ansible 8.x / ansible-core 2.15.x 계열로 고정한다.

댓글 0

로그인 후 댓글을 남길 수 있습니다.

아직 댓글이 없습니다.