본문 바로가기
DevNet/기초 학습

Ansible 실습

by CBROJIN 2025. 9. 11.

1. Ansible 핵심 구성요소 개념과 역할

1) 제어 노드 (Control Node)

정의: Ansible이 설치되어 있고, 실제로 플레이북을 실행하는 서버.

역할:

  • 인벤토리 파일 관리
  • 플레이북 실행
  • 모듈 실행
  • 원격 노드(Managed Node)에 명령 전달

특징:

  • Ansible은 여기 설치됨
  • SSH 등을 통해 관리 대상 장비에 접근

2) 관리 노드 (Managed Node)

정의: Ansible이 제어하는 대상 장비(서버, 네트워크 장비 등).

역할:

  • 제어 노드에서 내려오는 명령 수행
  • 별도의 Ansible 설치 필요 없음

특징:

  • SSH 접근 가능해야 함 (리눅스 서버)
  • 네트워크 장비라면 network_cli, httpapi, netconf 같은 연결 방식 사용

3) 인벤토리(Inventory)

  • 자동화할 호스트(네트워크 장비, 서버 등)의 목록과 변수 정보를 담은 파일.
  • INI, YAML 형식으로 작성 가능.
  • 각 장비의 IP, 사용자 계정, 접속 방법, 장비 OS 타입 등을 정의.

INI(Initialization) 형식은 간단하고 직관적인 텍스트 기반 구성 파일 형식으로,

Ansible에서 자동화 대상 호스트(서버, 네트워크 장비 등)를 정의할 자주 사용됩니다.

4) 플레이북(Playbook)

  • YAML 형식의 실행 시나리오.
  • 어떤 호스트에, 어떤 모듈을, 어떤 순서와 조건으로 적용할지 기술.
  • 태스크(Task) 집합으로 구성.

5) 모듈(Module)

  • 특정 작업 단위를 수행하는 실행체.
  • 예: ios_config(Cisco 설정), junos_config(Juniper 설정), copy, command.
  • 멱등성을 보장해 이미 원하는 상태면 변경 없이 통과.

6) 플러그인(Plugin)

Ansible 기능을 확장하는 코드 조각.

종류:

  • Connection Plugin: 네트워크 장비에 SSH, NETCONF, HTTP API 등으로 연결.
  • Action Plugin: 모듈 호출 전후의 데이터 가공.
  • Lookup Plugin: 외부 데이터 소스 조회.
  • Filter Plugin: 변수 값 가공.

Ansible의 유연성을 높이는 확장 포인트.

 

2. Ansible에서 모듈과 플레이북의 역할 관계

1) 전체 실행 흐름

  1. 컨트롤러가 인벤토리에서 호스트를 선택
  2. Connection 플러그인이 세션을 열어 연결 확보 (SSH, NETCONF, HTTP API 등)
  3. 플레이북 내 각 태스크가 특정 모듈과 인자를 호출
  4. 모듈이 장비와 통신해 상태를 읽거나 변경
  5. 모듈이 JSON 결과(changed, failed, msg, diff 등)를 반환
  6. 플레이북 로직(조건, 루프, 핸들러, 예외 처리)에 따라 다음 태스크로 진행
 

2) 모듈(Module) = "무엇을 할지"

  • 한 가지 작업 단위를 수행하는 실행체
  • 네트워크 자동화 예시: ios_config, ios_facts, junos_config, eos_vlans
  • 멱등성 보장: 이미 원하는 상태면 변경 없이 통과
  • 입력: 인자(원하는 상태), 출력: 표준화된 JSON 결과
  • 리소스 모듈, 정보 수집 모듈, 구성 모듈로 구분

3) 커넥션 플러그인(Connection) = "어떻게 연결할지"

장비에 접속하는 전송 방식 담당

대표 예시:

  • network_cli: SSH CLI
  • netconf: NETCONF (YANG 기반 XML/RPC)
  • httpapi: RESTCONF, NX-API, eAPI
  • local: 로컬 실행(API 클라이언트형)

연결 실패는 주로 모듈 문제가 아니라 커넥션 설정(계정, 타임아웃, 프롬프트 패턴 등) 문제

 

4. 플레이북(Playbook) = "언제·어떤 순서로·누구에게"

  • YAML로 작성된 실행 시나리오
  • 구성 요소: hosts, vars, tasks, handlers, roles, when, loop, tags, strategy
  • 여러 모듈 호출을 오케스트레이션하고 조건·예외·롤백 제어
 

5. 네트워크 장비별 전형적 패턴

A) Cisco IOS (SSH-CLI)

인벤토리: ansible_connection=network_cli, ansible_network_os=cisco.ios.ios

태스크 흐름:

  1. ios_facts 수집
  2. ios_l3_interfaces로 SVI IP 설정
  3. 필요 시 ios_config로 보완
  4. ios_config save_when=changed로 저장

B) Juniper (NETCONF)

인벤토리: ansible_connection=netconf, ansible_network_os=junipernetworks.junos.junos

태스크 흐름:

  1. junos_facts 수집
  2. junos_config로 candidate에 머지
  3. commit으로 확정, diff 검증

C) Cisco IOS-XE (RESTCONF)

인벤토리: ansible_connection=httpapi, ansible_network_os=cisco.ios.ios

태스크 흐름:

  1. 표준 YANG 경로 조회
  2. 인터페이스/VRF/ACL 상태 선언
 

6. 현업 포인트

  1. 연결 문제는 모듈이 아니라 커넥션 변수·프롬프트 매칭·타임아웃 등 원인
  2. 멱등성 유지: 리소스 모듈 우선, 필요 시 CLI 스니펫 보완
  3. check_mode, diff 활용으로 사전 검증 습관화
  4. 네트워크 장비는 파이썬 미지원 → gather_facts 대신 네트워크 전용 facts 모듈 사용
  5. 변경 저장은 OS마다 다름(NVRAM write, commit 등)
 

한 줄 정리

  • 모듈 = 무엇을 할지 (작업자)
  • 커넥션 플러그인 = 어떻게 연결할지 (운송수단)
  • 플레이북 = 언제·어떤 순서·누구에게 적용할지 (감독)
  • 인벤토리 = 누구에게 적용할지 (대상 목록)
  • 관리/제어 노드 = 전체 실행을 총괄하는 지휘소
  • 플러그인 = 세부 기능을 확장하는 도우미

3. Ansible Automation Platform (AAP) 구성 요소와 역할

Red Hat이 제공하는 상용 배포판으로, 커뮤니티 Ansible을 확장·강화한 형태.

1) Automation Controller (옛 AWX / Ansible Tower)

  • 웹 UI와 API 기반의 중앙 관리 시스템.
  • 플레이북 실행을 스케줄링, 모니터링, RBAC(역할 기반 접근 제어) 제공.
  • 다수 사용자가 협업하며 자동화 실행을 통제 가능.

2) Automation Hub

  • 공인된 Ansible Collection(벤더 모듈, 롤, 플러그인)을 저장하고 배포하는 저장소.
  • Red Hat 인증 콘텐츠 제공 → 보안 및 신뢰성 보장.

3) Execution Environments (EE)

  • 컨테이너 기반 실행 환경.
  • 필요한 파이썬 라이브러리, 모듈, 컬렉션을 패키징해 일관된 실행 보장.
  • “내 PC에서는 되는데 서버에선 안 돼” 문제를 줄임.

4) Event-Driven Ansible (EDA)

  • 이벤트 기반 자동화 실행.
  • 예: 네트워크 장애 알람이 발생하면 자동으로 플레이북 실행.

5) Automation Mesh

  • 여러 지역·노드에 분산된 자동화 실행을 가능하게 하는 메시 네트워크.
  • 원격 사이트, 클라우드, 데이터센터 등 다양한 환경을 하나로 연결.

6) Analytics & Insights

  • 자동화 작업 결과, 사용 통계, 보안 리스크 등을 분석.
  • 운영 최적화와 거버넌스 강화.

커뮤니티 Ansible vs Ansible Automation Platform 비교

구분 커뮤니티 Ansible Ansible Automation Platform
배포 형태 오픈소스 CLI 툴 상용 + 지원, 엔터프라이즈 강화
실행 관리 CLI 중심 Web UI, API, RBAC, 중앙 통제
콘텐츠 커뮤니티 컬렉션 Red Hat 인증 콘텐츠 (Automation Hub)
실행 환경 로컬 파이썬, 모듈 설치 필요 컨테이너 기반 Execution Environment
확장성 개별 관리 노드 중심 Automation Mesh로 분산 실행
운영/보안 개별 사용자 관리 RBAC, 감사 로그, Analytics/Insights
 

한 줄 정리

  • 커뮤니티 Ansible: CLI 중심의 오픈소스 자동화 툴.
  • Ansible Automation Platform: 기업 환경을 위한 중앙 관리, 보안, 거버넌스 기능까지 포함한 상용 플랫폼.

인벤토리를 이용한 자동화 대상 호스트 설정

 

4. 역할에 따른 호스트 그룹 설정

예: 웹 서버, DB 서버, 네트워크 장비 등 그룹별로 묶어 관리

[web]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11

[db]
db1 ansible_host=192.168.1.20
 

그룹별 호스트 설정

  • 그룹마다 공통 변수를 부여 가능
[web:vars]
ansible_user=ec2-user
ansible_ssh_private_key_file=~/.ssh/web.pem
 

중첩 그룹 정의

  • 여러 그룹을 상위 그룹으로 묶을 수 있음
[app:children]
web
db
 

범위를 사용한 호스트 사양 간소화

  • 연속된 호스트 이름을 단순화 가능
[web]
web[1:5].example.com # web1 ~ web5 자동 확장
 

인벤토리 확인

  • 인벤토리 그룹 구성을 확인하는 명령
ansible-inventory -i inventory.ini --list
ansible-inventory -i inventory.ini --graph
  • --list: 모든 호스트와 변수 출력
  • --graph: 그룹 간 관계를 트리 형태로 표시

 

5. Ansible 환경 설정 파일(ansible.cfg) 정리

 

플레이북 작성 전에 Ansible이 동작하는 기본 환경을 정의하는 설정 파일.

보통 /etc/ansible/ansible.cfg, ~/.ansible.cfg, 또는 프로젝트 디렉토리 내 ansible.cfg에서 사용.

주요 섹션

1. [defaults]

  • 인벤토리 경로, 기본 사용자, 출력 포맷 등 기본값을 정의.
[defaults]
inventory      = ./inventory.ini   # 인벤토리 파일 경로
remote_user    = admin             # 원격 접속 기본 계정
host_key_checking = False          # SSH 호스트 키 검증 비활성화
forks          = 10                # 병렬 실행할 호스트 수
timeout        = 30                # SSH 연결 타임아웃
retry_files_enabled = False        # 실패 시 *.retry 파일 생성 여부

2. [privilege_escalation]

  • sudo 등 권한 상승 관련 설정.
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False

3. [ssh_connection]

  • SSH 접속 방식 및 성능 최적화 옵션.
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
control_path = %(directory)s/%%h-%%r
pipelining = True

4. [inventory] (선택)

  • 인벤토리 플러그인 옵션 관리.
[inventory]
enable_plugins = host_list, ini, yaml

5. [colors] (선택)

  • 출력 색상 커스터마이징.
[colors]
changed = yellow
ok      = green
error   = red
 

초보자 예시 ansible.cfg

[defaults]
inventory      = ./inventory.ini
remote_user    = cisco
host_key_checking = False
forks          = 20
timeout        = 60
retry_files_enabled = False

[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False

[ssh_connection]
pipelining=True
 

정리

  • [defaults], [privilege_escalation], [ssh_connection] → 필수적으로 많이 사용.
  • [inventory], [colors] → 필요 시 확장.
  • cfg를 잘 설정해두면 플레이북 실행 시 옵션을 매번 주지 않아도 됨.

→ 인벤토리 → cfg 환경 설정 → 플레이북 실행 순으로 흐름이 이어진다.

 

 

6. Ansible 변수와 팩트 사용하기

  • 네트워크 자동화에서 플레이북 로직은 최대한 단순하게, 환경 차이는 “변수”로 분리하는 것이 유지보수의 핵심이다.
  • 이 문서는 예시 코드를 바꾸지 않고, 각 항목의 쓰임과 배경, 흔한 함정, 실무 팁을 더 자세히 설명한다.

왜 변수를 쓰나?

  • 재사용성: 같은 플레이북을 테스트/운영, 지역/사이트, 장비 모델이 달라도 변수 파일만 바꿔서 돌릴 수 있다.
  • 표준화: 공통 정책(NTP, Syslog, 보안 배너, 관리 VRF 등)을 한 곳(group_vars)에 모아 일관되게 배포한다.
  • 멱등성 강화: “원하는 상태”를 변수로 선언하면 리소스 모듈이 차이를 계산해 필요한 변경만 적용한다.
  • 변경 추적: 변수 파일은 텍스트(YAML)이므로 Git으로 버전 관리가 쉽다. 누가 무엇을 바꿨는지 이력 확인 가능.
  • 온보딩 용이: 새 팀원이 플레이북 로직을 뜯어보지 않아도 변수 파일만 읽어도 환경 구성을 이해할 수 있다. • 주의: 값이 자주 바뀌는 운영 스위치포트 상태 같은 항목은 변수화 대상이 아니다. “정책·설계의 의도”를 변수로 담는 것이 좋다.

변수 종류와 특징

 

(1) 그룹 변수(group_vars)

  • 적용 범위: 특정 그룹 전체. 역할(Access/Dist/Core), OS 타입(IOS/NXOS/JunOS), 환경(Dev/Prod)별 공통값 저장.
  • 저장 위치: project/group_vars/.yml 또는 group_vars/all.yml(모든 호스트 공통). 
  • 쓰임: 공통 NTP/Syslog, 접속 방식(ansible_connection), 네트워크 정책 기본값 등.

(2) 호스트 변수(host_vars) 

  • 적용 범위: 특정 장비 하나. 장비의 고유 식별자·포트·IP·우선순위 등. 
  • 저장 위치: project/host_vars/.yml 
  • 쓰임: VRRP 우선순위, 업링크 인터페이스명, Loopback 주소 등.

(3) 플레이 변수(play vars)

  • 적용 범위: 플레이 실행 동안. 실행 컨텍스트성 값(배너 문구, 저장 정책 토글 등)에 적합. 
  • 장점: 변수의 “가시성”이 좋아져 해당 플레이의 의도를 바로 파악 가능.

 

(4) 태스크 변수(task vars)

  • 적용 범위: 특정 태스크·루프 내부. loop_var, register 변수, with_items 등과 함께 국소적으로 사용.

(5) 파일 변수(vars_files) 

  • 외부 YAML로 변수를 분리. 민감정보/환경 변수를 파일로 나눠서 관리할 때 유용.

(6)추가 변수(extra vars, -e) 

  • 실행 시점에 커맨드라인로 주입. 우선순위 최상위. 긴급 오버라이드, 단발성 배포에 사용. 
  • 남용하면 “숨은 의존성”이 생긴다. 반복되는 값은 파일에 정착.
  • set_fact 실행 중 계산해 만드는 동적 변수. 탐색 결과를 다음 태스크에서 재사용할 때 편리. 범위는 “현재 호스트/현재 플레이”에 한정. 영구 저장이 아니다.

(6) 매직 변수(magic vars)

Ansible이 항상 제공하는 특수 변수. inventory_hostname, hostvars, groups, group_names 등. 

크고 복잡한 구조이므로 debug 출력 시에는 필요한 필드만 보거나 필터(to_nice_json)로 보기 좋게 출력. 

보안 팁: 패스워드/토큰/프리셰어드키는 ansible-vault로 암호화해 저장. 예: ansible-vault encrypt group_vars/ios.yml 

타입 팁: 08 같은 값은 문자열로 취급되어야 한다. 따옴표로 감싸 타입 오류·8진수 해석을 방지.

 

프로젝트 디렉토리 구조 예시

project/
  inventory.ini         # 대상 장비/서버 목록
  group_vars/           # 그룹 단위 변수 저장
    all.yml             # 모든 장비 공통값
    ios.yml             # IOS 장비 전용값
    dist.yml            # Distribution 스위치 전용값
  host_vars/            # 호스트별 변수 저장
    dist-1.yml
    dist-2.yml
  playbooks/
    site.yml            # 메인 플레이북
  • group_vars/all.yml은 “전 사내 표준” 같은 초공통값. ios.yml, dist.yml은 역할·OS별 표준.
  • host_vars/는 개별 장비의 차이를 담는다. 폴더 구조가 “무엇이 공통이고 무엇이 고유인지”를 드러내게 설계.

인벤토리 예시 (inventory.ini)

[dist]
dist-1 ansible_host=192.168.100.11
dist-2 ansible_host=192.168.100.12

[ios]
dist-1
dist-2
  • ansible_host는 실제 접속 IP/도메인. inventory_hostname(키)은 dist-1, dist-2로 유지되어 가독성과 변수 파일 매핑이 쉬워진다.
  • 호스트는 여러 그룹에 중복 소속될 수 있다. ios 그룹은 접속 방식 등 OS 공통값을 적용하는 데 유용하다.
  • 대규모 환경에서는 상위/하위 그룹(children)을 활용해 “역할 × 환경” 매트릭스를 만든다.(예: [prod:children] dist)

그룹 변수 (group_vars)

그룹 단위 공통 설정을 정의한다. 동일 설정을 여러 파일에 반복 기입하는 실수를 줄인다.

 

모든 호스트 공통값 (all.yml)

ntp_servers:
  - 192.168.99.10
  - 192.168.99.11
syslog_server: 192.168.99.20
mgmt_vrf: MGMT
  • ntp_servers는 리스트 형태로 관리해 사이트 추가가 쉽다. 템플릿/루프에서 상위 n개만 쓰는 등 응용 가능.
  • mgmt_vrf는 이후 태스크에서 관리 VRF로 통일적으로 참조되어, 장비마다 명령이 달라지는 위험을 줄인다.

IOS 장비 공통값 (ios.yml)

ansible_connection: network_cli
ansible_network_os: cisco.ios.ios
ansible_user: admin
ansible_password: "C!sco123"
logging_buffer_size: 16384
  • ansible_connection은 network_cli(SSH/CLI), netconf(XML/RPC), httpapi(RESTCONF/NX-API/eAPI) 중 선택.
  • ansible_network_os는 컬렉션 네임스페이스를 포함(cisco.ios.ios)해야 Ansible이 올바른 플러그인/모듈을 로딩한다.
  • logging_buffer_size 같은 정책성 값은 한 곳에서 바꾸면 전체에 반영된다.

Distribution 스위치 공통값 (dist.yml)

vlan_list:
  - { id: 10, name: USERS }
  - { id: 20, name: SERVERS }
  - { id: 99, name: MGMT }
  • 리소스 모듈(ios_vlans)은 이렇게 “상태”를 구조화된 데이터로 받는다. state: merged와 함께 쓰면 기존과의 차이만 반영한다.
  • 선언형 데이터는 코드 리뷰가 쉽다. 숫자/이름만 보고 의도를 이해할 수 있다.

호스트 변수 (host_vars)

특정 장비에만 다른 값이 필요한 항목을 담는다. 파일명이 inventory_hostname과 1:1로 매칭되어 직관적이다.

 

dist-1.yml

loopback0: 10.255.0.1/32
uplink_intf: GigabitEthernet1/0/1
vrrp_priority:
  vlan10: 110
  vlan20: 90

 

dist-2.yml

loopback0: 10.255.0.2/32
uplink_intf: GigabitEthernet1/0/2
vrrp_priority:
  vlan10: 90
  vlan20: 110
  • vrrp_priority처럼 “같은 키 구조를 유지하고 값만 다른” 패턴을 쓰면 템플릿/태스크를 재사용하기 좋다.
  • 네이밍은 일관되게: vlan10처럼 공백/특수문자를 피하고 소문자+언더스코어를 권장.

플레이 변수 (play vars)

플레이 안에서만 의미가 있는 임시값을 둔다. 실행 컨텍스트가 눈에 잘 보인다.

 

site.yml

- name: Dist 스위치 공통 구성
  hosts: dist
  gather_facts: false
  vars:
    login_banner: |
      Authorized access only. Violators will be prosecuted.
    save_when: changed
  tasks:
    - name: NTP 서버 설정
      ios_config:
        lines: "ntp server {{ item }} vrf {{ mgmt_vrf }}"
      loop: "{{ ntp_servers }}"

    - name: 로깅 버퍼 크기 설정
      ios_config:
        lines: "logging buffered {{ logging_buffer_size }}"

    - name: VLAN 생성
      ios_vlans:
        config: "{{ vlan_list }}"
        state: merged
  • login_banner처럼 텍스트 블록은 YAML 멀티라인(|)을 써야 줄바꿈이 보존된다.
  • save_when은 저장 정책을 중앙에서 토글할 때 유용하다(예: 운영은 changed, 개발은 never).
  • loop와 변수 조합으로 ntp_servers 리스트를 깔끔히 순회한다.

변수 우선순위 (간단 버전) 낮음 → 높음 (높은 쪽이 우선 적용)

  1. group_vars/all
  2. 다른 group_vars (ios, dist 등)
  3. host_vars/호스트
  4. 플레이 변수 (vars)
  5. vars_files 불러온 값
  6. extra-vars (-e) 설명
  • 충돌 시 아래쪽이 위쪽 값을 덮어쓴다. 긴급 변경은 -e를 쓰되, 반복되면 파일에 영구 반영.
  • 역할(roles)을 쓰는 큰 프로젝트에서는 role defaults/vars가 추가된다. 여기서는 초보자 흐름에 맞춰 단순화했다.

팩트(Facts) 개념

  • 대상 호스트의 “실제 상태”를 Ansible이 수집해 ansible_facts 딕셔너리에 담는다. 조건 분기, 검증, 보고에 활용한다.
  • 서버는 기본 gather_facts: true로 setup 모듈이 광범위한 정보를 수집한다. 네트워크 장비는 전용 facts 모듈을 사용한다.

예시: Cisco IOS facts 수집

- name: IOS facts 수집
  hosts: ios
  gather_facts: false
  tasks:
    - ios_facts:
        gather_subset: min
    - debug:
        msg: "{{ ansible_facts.ansible_net_model }} {{ ansible_facts.ansible_net_version }}"
  • gather_subset: min은 최소한의 키만 수집해 실행을 빠르게 한다.
  • ansible_facts는 중첩 구조다. 필요한 키만 골라 쓰고, 전체를 볼 때는 debug: var=ansible_facts로 점검한다.

자주 쓰는 IOS facts 키

  • ansible_facts.ansible_net_hostname (호스트 이름)
  • ansible_facts.ansible_net_model (장비 모델)
  • ansible_facts.ansible_net_version (OS 버전)
  • ansible_facts.ansible_net_serialnum (시리얼 번호)
  • ansible_facts.ansible_net_interfaces (인터페이스 목록)

조건/분기에서 facts 활용

- name: 17.x 이상에서만 기능 A 적용
  when: ansible_facts.ansible_net_version is search('^17\.')
  ios_config:
    lines: feature a-foo
  • 정규식으로 메이저 버전을 판별하는 간단한 패턴이다. 복잡한 비교는 버전 비교용 테스트(version, version_compare)를 고려한다.

set_fact 활용

- name: VRRP 우선순위 선택
  set_fact:
    vrrp10_prio: "{{ vrrp_priority.vlan10 | default(100) }}"

- name: 우선순위 적용
  ios_config:
    lines:
      - interface Vlan10
      - vrrp 10 priority {{ vrrp10_prio }}

 

  • default 필터로 값이 없을 때의 안전한 기본값(100)을 준다. 런타임 계산 결과를 다음 태스크에서 재사용한다.
  • set_fact는 “현재 플레이/호스트 범위”에만 유효하며 다른 호스트나 다음 플레이로 자동 전파되지 않는다.

매직 변수 (핵심)

  • inventory_hostname: 인벤토리에 정의된 현재 호스트 키. host_vars/<이름>.yml과 1:1 매칭된다.
  • hostvars: 모든 호스트의 변수 사전. 교차 참조가 필요할 때 쓴다(예: hostvars['dist-1'].loopback0).
  • group_names: 현재 호스트가 소속된 그룹 리스트. 조건에 따라 그룹별 분기 처리 가능.
  • groups: 그룹명 → 호스트 리스트 매핑. 특정 그룹의 모든 호스트를 순회할 때 유용.

템플릿 예시 templates/ntp.j2

ntp server {{ ntp_servers[0] }} vrf {{ mgmt_vrf }}
ntp server {{ ntp_servers[1] }} vrf {{ mgmt_vrf }}

 

태스크에서 템플릿 적용

- name: NTP 템플릿 배포
  ios_config:
    src: templates/ntp.j2
  • ios_config의 src는 컨트롤러에 있는 템플릿 파일을 읽어 Jinja2로 렌더링한 결과를 장비로 보낸다.
  • 템플릿 파일 경로는 프로젝트 루트 기준 상대 경로로 관리하면 이식성이 좋다.

디버깅 팁

- name: 현재 호스트 변수 전체 보기
  debug:
    var: hostvars[inventory_hostname]

- name: 실제 적용될 값 확인
  debug:
    msg: "syslog={{ syslog_server }} buffer={{ logging_buffer_size }}"
  • var:는 딕셔너리를 그대로 출력한다. 큰 출력은 로그 가독성을 해칠 수 있으니 필요한 순간에만 쓰자.
  • msg:는 사람이 읽기 쉬운 요약을 만들 때 유용하다. to_nice_json, to_yaml 필터로 가독성을 높일 수 있다.

 

7. Ansible 네트워크 자동화 핵심 정리

1)  Ansible 변수 종류와 사용법

변수는 “같은 의도를 여러 장비에 일관되게 적용”하기 위한 핵심 도구다. 수백 대 장비를 운영할수록 변수 설계가 곧 유지보수성이다. 네트워크 자동화에서는 사이트별 표준값(AAA, NTP, SYSLOG, SNMP), 장비별 개별값(관리 IP, 호스트명, 인터페이스 매핑), 역할별 정책값(ACL 세트, 라우팅 정책)을 분리해 담는다.

 

핵심 분류와 용도

  • 인벤토리 변수: host_vars(장비 단위), group_vars(그룹 단위)에 저장한다. 그룹은 벤더별, 모델별, 지역/사이트별, 역할별(ACCESS/DIST/CORE)로 나누는 것이 일반적이다. 한 변수명이 여러 곳에 존재하면 더 구체적 범위(호스트)가 우선된다.
  • 플레이 변수: 특정 Play에서만 일시적으로 쓰는 값. vars, vars_files, vars_prompt가 있다. 재사용을 고려하면 역할/인벤토리 쪽으로 이동하는 것이 좋다.
  • 롤 변수: defaults는 우선순위가 가장 낮아 “안전한 기본값”을 넣는 곳, vars는 높은 우선순위로 “역할 내부 강제값”이 필요할 때 사용한다. 외부에서 덮어써야 한다면 defaults에 두는 편이 좋다.
  • 명령행 변수(--extra-vars): 가장 강력한 오버라이드 수단이다. 배포 파이프라인에서 배포 창구, 변경 티켓 번호, 긴급 플래그 등을 주입할 때 활용한다.
  • 동적 변수: set_fact(런타임 계산값), register(Task 결과 캡처). 예를 들어 ios_facts 결과를 register해서 조건 분기를 할 수 있다.
  • 팩트/매직 변수: ansible_facts, inventory_hostname, groups, hostvars 등. 매직 변수는 인벤토리 구조를 탐색하거나 교차 참조할 때 유용하다.

우선순위 실무 감각

  • 같은 이름의 변수가 여러 위치에 있으면 보통 extra-vars > role vars > play vars > host_vars > group_vars > role defaults 순으로 생각하면 된다. 혼동을 줄이려면 “동일 변수는 한 곳에만 둔다”는 규칙과 네이밍 컨벤션(예: site_, global_, device_)을 정해두자.

템플릿과 변수

  • 네트워크 자동화는 Jinja2 템플릿과 변수가 결합해 힘을 발휘한다. 예를 들어 ntp_servers 리스트를 루프 돌려 ios_config lines로 변환한다. 공백·인덴트·개행에 따라 네트워크 장비 CLI가 민감하므로 템플릿에서 여분의 스페이스, 탭, 줄바꿈을 엄격히 관리하자.

예시 (인벤토리):

[ios]
dist-1 ansible_host=192.168.100.3
dist-2 ansible_host=192.168.100.4

[ios:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=cisco.ios.ios
ansible_user=netops
ansible_password={{ vault_ios_ssh_pw }}
ansible_become=true
ansible_become_method=enable
ansible_become_password={{ vault_ios_enable_pw }}
  • 그룹 설계는 “벤더/OS 버전/사이트/역할” 축으로 겹칠 수 있다. 중복을 줄이려 그룹별 설정을 최소화하고, 공통값은 group_vars/all, 사이트 특화는 group_vars/site_x처럼 계층화하자.
  • 비밀 값은 반드시 Vault 변수 참조로만 소비하고, 평문 변수와 섞지 않는다.

2) Ansible Vault

Vault는 비밀정보(SSH 비밀번호, enable 비밀번호, API 토큰 등)를 암호화해 Git에 안전하게 보관하게 해준다. 팀 협업에서 필수이며, 보안 감사를 통과하기 위한 기본 요건이기도 하다.

 

핵심 개념

  • 암호화 단위: 파일 전체, 문자열 한 줄, YAML의 값 단위까지 가능하지만, 운영 관점에서는 파일 단위로 다루는 것이 일관적이다.
  • 접근 방식: --vault-id를 쓰면 실행 시 암호를 묻거나, 사내 비밀관리 도구와 스크립트로 연동해 자동 주입도 가능하다.
  • 키 롤오버: 재발급(rekey) 기능으로 팀 변경 시 키 교체가 쉽다.

명령 예 ansible-vault create group_vars/all/vault.yml ansible-playbook play.yml --vault-id @prompt

 

운영 사례

  • vault 파일 분리: 글로벌 비밀값(all), 사이트별 비밀값(site_x), 벤더별 비밀값(ios)처럼 역할에 맞게 쪼갠다.
  • 변수 접두어: vault_ 접두어를 붙여 가독성·검색성을 높인다.
  • 금기 사항: Vault 암호 파일 자체를 저장소에 커밋하지 않는다. CI/CD에서는 조직 표준 비밀 저장소와 vault-id 스크립트로 연동한다.

3) 자동 예약 변수와 팩트 (ansible_facts)

네트워크 플레이는 보통 gather_facts: no로 시작하고, 플랫폼 전용 facts 모듈(예: cisco.ios.ios_facts)로 필요한 정보만 가져온다. 수집된 값은 ansible_facts 사전에 구조화되어 들어오고, 모델/버전/시리얼/인터페이스 상태 등 운영 의사결정에 사용된다.

활용 시나리오

  • 조건부 배포: 특정 OS 버전 이상에서만 새로운 리소스 모듈을 적용하거나, 모델별 인터페이스 네이밍 차이를 흡수한다.
  • 변경 영향 최소화: 베타 펌웨어가 탐지되면 해당 장비는 제외한다.
  • 리포팅/감사: facts를 파일로 떨어뜨려 CMDB/재고관리와 동기화한다.

성능·정확도 팁

  • 서브셋 옵션으로 필요한 항목만 수집하면 속도가 빨라진다.
  • facts 캐시를 켜면 대규모 환경에서 중복 수집을 줄일 수 있다.

Cisco IOS 예시:

- name: IOS facts 수집
  cisco.ios.ios_facts:
  register: f

- debug:
    msg: "{{ f.ansible_facts.ansible_net_model }} / {{ f.ansible_facts.ansible_net_version }}"

 

4) 핸들러 (Handler)

핸들러는 특정 Task가 실제 변경(changed)을 일으켰을 때만 실행되는 후속 조치다. 네트워크에서는 재시작, 세션 플러시 같은 위험 동작을 핸들러에 묶어 “변경이 확인된 경우에만” 수행하도록 만드는 안전장치다.

 

동작 원리

  • notify에 의해 큐에 쌓이고, Play의 일반 Task가 끝난 뒤 한 번만 실행된다(동일 이름의 핸들러는 dedup된다).
  • 즉시 실행이 필요하면 meta: flush_handlers를 사용한다.
  • 여러 Task가 한 핸들러를 호출할 수 있고, listen 키워드로 핸들러 그룹을 만들 수도 있다.

안전 운영 팁

  • “저장(write memory)”는 save_when: modified로 처리하면 불필요한 저장을 줄일 수 있다.
  • clear 명령(예: BGP/OSPF 리셋)은 서비스 영향이 크므로 핸들러로 조건부 실행하고, 배포 창구·변경관리와 연계해 통제하자.

예시:

- name: OSPF 네트워크 선언
  cisco.ios.ios_config:
    lines:
      - router ospf 10
      - network 10.10.0.0 0.0.255.255 area 0
  notify: OSPF 재시작

handlers:
  - name: OSPF 재시작
    cisco.ios.ios_command:
      commands:
        - clear ip ospf process
 

5) 롤(Role) 구조와 사용법

Roles는 “정책·구성·템플릿·핸들러”를 패키징해 재사용성과 테스트 용이성을 높이는 단위다. 팀 표준 설정을 역할화하면 프로젝트 간 복제가 쉬워지고, 버전 관리와 코드 리뷰가 가능해진다.

 

디렉터리 의미

  • defaults: 외부에서 덮어쓸 수 있는 안전한 기본값. 사이트/장비 특화값은 여기를 override한다.
  • vars: 역할 내부에서 강제해야 하는 값. 외부 override를 기대하지 않을 때 사용한다.
  • tasks: ios_config·리소스 모듈 호출 등의 본문. 파일을 나눠 include/import로 구성하면 가독성이 좋아진다.
  • handlers: 변경 시에만 돌려야 하는 후속 조치.
  • templates: Jinja2 템플릿. 줄바꿈·들여쓰기로 CLI가 민감하니 유효성 검사를 습관화하자.
  • meta: 역할 의존성 명시(예: ios_base 전에 netcommon 설치 확인).

리소스 모듈 vs CLI 모듈

  • 리소스 모듈(예: ios_acls, ios_interfaces)은 선언적·idempotent하게 상태를 맞춘다.
  • CLI 기반 ios_config는 유연하지만 텍스트 일치에 의존하므로 템플릿·정규식 관리가 중요하다.

표준 구조:

roles/
  ios_base/
    defaults/main.yml
    tasks/main.yml
    handlers/main.yml
    templates/banner.j2

 

예시:

- name: NTP 서버 설정
  cisco.ios.ios_config:
    lines: "ntp server {{ item }}"
  loop: "{{ ntp_servers }}"
  notify: 저장

 

handlers/main.yml:

- name: 저장
  cisco.ios.ios_config:
    save_when: modified

 

운영 팁

  • 역할 단위로 분리 테스트를 수행하고, check mode 지원 여부를 문서화하자.
  • 역할 버전을 태깅하고, requirements 파일이나 컬렉션으로 배포하면 재현성이 올라간다.
 

6) Ansible Galaxy

Galaxy는 커뮤니티·벤더가 배포한 Roles/Collections를 검색·설치하는 허브다. 바퀴를 다시 만들지 말고, 공신력 있는 컬렉션을 가져와 표준화된 모듈을 쓰는 것이 시간·리스크를 줄인다.

 

활용

  • 공식 네임스페이스와 최근 업데이트, 문서 품질, 이슈 응답성을 확인한다.
  • requirements.yml로 버전 고정하고, 사내 미러/프록시를 통해 오프라인 환경에서도 일관성 있게 설치한다.
  • AWX/Automation Controller를 쓰면 프로젝트 동기화 시 컬렉션 자동 설치를 걸어둘 수 있다.

설치: ansible-galaxy collection install cisco.ios

 

7) 콘텐츠 컬렉션(Collections)

Collection은 모듈, 플러그인, 롤, 필터, 콜백 등을 네임스페이스로 묶은 배포 단위다.

호출은 FQCN으로 한다(예: cisco.ios.ios_config).

네트워크에서는 ansible.netcommon(연결 플러그인: network_cli, httpapi, netconf)이 토대가 되고,

벤더 컬렉션을 그 위에 올린다.

 

주요 네트워크 컬렉션

  • ansible.netcommon: 공통 연결·유틸리티. network_cli, httpapi, netconf 제공.
  • cisco.ios, cisco.nxos, cisco.iosxr: Cisco IOS/NX-OS/IOS-XR용 모듈.
  • arista.eos, junipernetworks.junos, frr.frr, paloaltonetworks.panos 등 환경에 맞게 채택.

버전·호환성 팁

  • 컬렉션 버전과 네트워크 OS 버전을 매핑해 호환성을 문서화한다.
  • FQCN을 사용하면 네임 충돌을 피하고, 린터/IDE에서 자동완성이 잘 동작한다.

예시 플레이북:

- name: IOS VLAN 생성
  cisco.ios.ios_config:
    lines:
      - vlan 30
      - name USERS_30
  notify: 저장

handlers:
  - name: 저장
    cisco.ios.ios_config:
      save_when: modified

 

9. Ansible 실습

Ansible을 활용해서 실제 네트워크 장비들(S1~S5)을 자동화 관리하는 실습.

Ansible의 인벤토리와 플레이북을 구성해 네트워크 장비들에 일괄적으로 접근하고 결과를 저장하는 과정이다.


0) 토폴로지 구성

실습 토폴로지는 Linux 서버(NetworkAutomation-1)에서 Ansible을 실행하고, 이 서버가 스위치들을 관리하는 구조다.

  • Ansible 서버 → Core 스위치(S1, S2)
  • Core 스위치 → Access 스위치(S3, S4, S5)

즉,  중앙 관리 서버 → Core → Access 계층형 구조를 가상 환경에 구현했다.


1) 인벤토리 설정 (hosts)

/etc/ansible/hosts 파일에 관리할 장비들을 그룹으로 나누어 정리했다.

  • Core 스위치 그룹: S1, S2
  • Access 스위치 그룹: S3, S4, S5
  • 공통 변수: IOS 장비이므로 network_cli, ansible_network_os=ios, ansible_user, ansible_password를 정의

이렇게 설정해두면, 플레이북에서 hosts: all만 지정해도 전체 장비에 접속할 수 있다.


2) Ansible 환경 설정 (ansible.cfg)

/etc/ansible/ansible.cfg 에 기본 환경을 지정했다.

  • 인벤토리 위치 지정
  • SSH Key Checking 비활성화 (비밀번호 기반 로그인 위해)
  • Timeout 값 설정

.cfg 파일에매번 옵션을 붙이지 않아도 된다.


3) 플레이북 작성 (getversion.yml)

플레이북에서는 세 가지 주요 작업을 구성했다.

  1. ios_command 모듈을 사용해 show version 실행
  2. 결과를 debug로 출력하여 확인
  3. 결과를 /etc/ansible/outputs 디렉토리에 장비별 텍스트 파일로 저장

이 과정을 통해 CLI에서 개별 장비에 들어가지 않고도, 여러 장비의 OS 버전 정보를 한 번에 수집할 수 있다.


4) 실습 결과

  • 단순 반복 명령을 Ansible로 자동화하면 시간과 노력이 크게 절약된다.
  • 결과를 텍스트 파일로 저장하면, 장비별 버전/상태를 기록으로 남길 수 있어 트러블슈팅이나 자산 관리에 유용하다.
 

'DevNet > 기초 학습' 카테고리의 다른 글

vSphere  (0) 2025.09.04
RESTCONF API로 인터페이스 및 관리 IP 수집 실습  (0) 2025.09.03
인프라와 자동화  (2) 2025.09.02
API  (4) 2025.09.01
데이터 형식  (3) 2025.08.29