CLOUDWAVE

IaC : Ansible 구성요소 - config file, Inventory file, Playbook

갬짱 2025. 2. 1. 00:07

 
Ansible구성의 3가지 파일

  • configuration file
  • playbook file
  • inventory file

→ 작업 디렉토리를 별도로 생성하고 해당 작업파일들을 생성
→ cloud환경뿐아니라 on-premise상의 기기( VM을 로컬상에 직접 생성 )에도 전달하여 적용할 수 있음 ( 원하는 호스트에 적절한 작업을 수행 )

 

구성파일( configuration file )

Ansible의 동작방법을 설정하는 파일( 연결설정, 권한설정 )

  • 기본위치 /etc/ansible/ansible.cfg 에 위치 ( ansible --version으로 각 파일의 위치 및 설정확인가능 ) 이 위치는 기본위치일뿐이고 → 현재 ansible을 수행하는 경로의 cfg파일이 우선순위가 높음 ( 우선순위 : ./ansible.cfg > 기본경로의 .ansible.cfg )
  • 설정을 여러 섹션으로 구성( 대괄호 제목 ) & 내부설정은 키-값 쌍으로 원하는 파라미터 속성값 지정
  • 현재위치(pwd)에 따른 구성파일의 위치
사용자 홈 위치에서의 구성파
사용자 작업 디렉토리 위치에서의 구성파일

 
[ 섹션과 내용들 ]

  • defualts 섹션
    • inventory속성 : inventory파일의 경로를 저장 기본 inventory 파일은 /etc/ansible 경로의 hosts 파일에 존재함 → 대부분 사용시에는 워킹디렉토리에 새로 구축하고 그 경로를 참조함
    • remote_user 속성 : 관리호스트에 ssh 연결시 사용할 사용자 = 플레이북 실행시 원격노드에서 접근할 유저 = 명령어를 처리할 유저 기본 유저는 현재 사용자(로컬 사용자)의 이름이 지정됨
    • ask_pass : 관리호스트에 ssh 연결시 비밀번호 확인여부 ( 기본값 false )
  • privilieged_escalation 섹션 : 권한상승을 위한 사용자 전환설정
    • become : 관리 호스트에서 자동으로 사용자 전환여부 ( 기본값 false )
    • become_method : 사용자 전환방식 = 권한 상승 방식 ( sudo, su )
    • become_user : 전환할 사용자 = 상승대상이 되는 사용자 ( 기본값 root ) = 누구로 연결할 것인가
    • become_ask_pass : 패스워드 확인여부 ( 기본 false ) become_method 메커니즘에서 권한을 에스컬레이션하기 위해 사용자가 암호를 입력해야 하는 경우, 구성 파일에 become_ask_pass = true 매개 변수를 설정
    ⇒ ansible-config view 명령어로 구성파일에 설정된 내용을 확인가능

 
[ 연결설정 ] default 섹션에서 정의
* remote_user와 become_user의 차이점

  • remote_user : 초기 SSH 연결에 사용하는 사용자
  • become_user : 명령 실행 시 권한 상승 필요할 때 전환가능한 사용자

 
[ 권한상승 ] privilege-escalation 섹션에서 정의
원격 호스트에 권한이 없는 일반 사용자로 연결한 후 권한을 상승하여 관리 액세스 권한을 가진 root사용자로 전환가능하도록 설정하는 것이 일반적인 형태

관리 호스트에 ssh로 연결한 사용자는 sudo를 사용할 수 있는 권한이 사전에 설정되어 있어야 한다. ( /etc/sudoers 파일에 작성하거나 혹은 /etc/sudoers.d/디렉토리에 추가 파일을 생성하여 미리 설정해둘 것 )
remote_user로 작업을 수행하다가 특정 작업에 상승된 권한이 필요할 경우, become: yes가 설정된 작업에서 자동으로 become_user로 전환하여 실행
⇒ become_user는 필요할 때만 권한을 전환하는 방식으로 작동
 


 

인벤토리 파일 ( inventory file )

앤서블에서 관리할 호스트 목록을 정의 → 2가지 방식 : 정적구성 혹은 동적구성
 
[ 정적 인벤토리 ] : 관리할 호스트들을 하나씩 리스트업

  • 다양한 형식(INI스타일, YAML형식.. ) → 보통 YAML이 아닌 일반문자열로 입력
  • 호스트명 혹은 IP주소를 입력 → 보통 ip대신 호스트명을 등록

 

  • 집합적 관리 : 호스트들을 그룹에 할당하여 집합적으로 관리 ( 그룹은 하위그룹을 포함가능, 호스트는 여러 그룹에 소속가능 )
    • 특성, 용도, 위치에 따라 호스트 집합에 ansible play를 적용
    • 자동적으로 구성되는 두개의 호스트 그룹 : all( 모든 호스트 목록을 포함하는 그룹 ), ungrouped( 인벤토리에서 그룹에 속하지 않는 모든 호스트 목록 )
    • 하나의 호스트를 여러 그룹에 멤버로 등록가능( multiple )
이때 빈줄은 무시 → 그룹으로 포함하지 않을 호스트( 단일호스트 )는 보통 맨 윗줄에 입력할 것

 
[ 중첩그룹 ]
여러 개의 그룹을 묶어서 함께 사용가능 → 그룹 생성시 접미사 :children 키워드를 추가
그룹들을 멤버로 포함 = 해당 중첩그룹에 명령을 내릴때 포함된 그룹에 포함된 호스트들이 모두 대상이 됨

[dev]
web1.test.com
web2.test.com

[prod]
web3.test.com
web4.test.com

[web-servers:children]
dev
prod

 
 
[ 범위지정 ]
호스트 목록을 범위로 지정하여 간편하게 여러 대 등록가능( 한줄로 모두 지정가능 )
숫자와 영문에 해당하는 값을 처음값과 마지막 값을 입력하여 표현

[처음값:마지막값]

[a:e] = a부터 e까지 범위지정

# 192.168.4.0 ~ 192.168.7.255 범위의 모든 IP 주소
192.168.[4:7].[0:255] 

# server01.example.com 부터 server20.example.com 까지 모든 호스트
server[01:20].example.com

# a.dns.example.com 부터 e.dns.example.com 까지의 호스트
[a:e].dns.example.com

 
 
[ 인벤토리 파일 재정의 ]
인벤토리 파일의 기본위치는 /etc/ansible/hosts 로 설정된다.
그러나 대부분 작업 디렉토리에서 새로 생성하여 구성파일, 플레이북과 함께 위치시켜 관리하는 것이 일반적이다.
 
인벤토리 파일위치를 재정의시키는 2가지 방법
(1) ansible 명령의 -i 옵션 : 인벤토리 파일의 기본위치가 아닌 사용자 지정위치 파일로 대체하는 옵션

ansible -i ./inventory

(2) 구성파일의 inventory 파라미터 값( defaults 섹션 )으로 해당경로를 지정

[defaults]
inventory = ./inventory

 
 
[ 동적 인벤토리 ]
동적인 특성이 많은 클라우드 서비스 시스템 등에서는 자동화 설정으로 인한 호스트의 배포가 일반적
사용자가 정적으로 목록을 관리하지 않아도, 프로바이더 스크립트와 CLI를 통해 자동으로 호스트를 감지하고 목록화
클라우드 벤더에서 스크립트 형태로 제공( aws dynamic inventory )→ 여기에 넣어줌 & 현재 클라우드에 구성된 목록들을 가져와서 비교, 자동으로 등록( 자격증명을 넣어둠 )
 


 

플레이북 파일( playbook file )

작업대상 & 작업내용을 미리 정의

  • YAML 포맷으로 작성된 텍스트 파일( .yml ) : 공백문자를 사용하여 들여쓰기하여 데이터 구조를 표현
    (* 중요 : 탭 문자는 오류가 발생하기 때문에 사용하는 것을 권장하지 않고 스페이스바로 공백을 입력 )
  • 문서의 시작을 나타내는 시작 마커인 세개의 하이픈(---) 기호로 줄을 시작
---
- name: test play
	hosts: web1.test.com
	tasks:
		- name: create new user
			user:
				name: user01
				uid: 4000
				state: present

 

플레이 작성

플레이 단위(Play) = 플레이명(name) + 작업대상이 되는 관리호스트(hosts) + 작업내용(tasks)
( 플레이북 내에서 각 플레이 단위는 리스트(-)로 구분 )

  • 작업이름(name) : 생략가능, 가독성을 높여주기에 플레이의 목적 및 목표를 기입
  • 작업대상(hosts) : inventory에 목록화 되어있는 대상 혹은 그룹 → 인벤토리에 등록되지 않은 대상의 경우 error발생
  • 작업내용(tasks) : 실제로 수행할 작업목록을 구성 리스트(-)로 여러개의 하위 내용을 작성, 모듈로 구성, 작성 순서대로 실행됨
    • name : 생략가능 → 각 task에서 output 출력결과를 구분하기 위함
    • 모듈명
      ** 모듈 : 하위 수준으로 입력된 인자를 통해 원하는 작업 내용을 구성, 사용자가 원하는 작업 내용을 수행할 수 있도록 미리 설계된 파이썬 프로그 → 키워드만 입력

 
(1) user 모듈 : 사용자를 생성, 관리해주는 모듈

  • name 속성 필수 → 대상이 되는 사용자를 기입
  • state : present(존재) / absent( 존재시 삭제, 존재하지 않으면 유지 )
tasks:
	- name: create new user
		user:
			name: user01
			uid: 4000
			state: present

uid가 4000인 user01 사용자가 현존하는지 확인해서 사용자가 없다면 새로 생성하고, 있다면 그대로 두는 작업( 멱등성 보장 )
 
(2) service 모듈 : 리눅스 시스템에서 서비스(데몬)을 제어하는 데 사용 → 서비스의 시작(started), 중지(stopped), 재시작(restarted), 상태 확인 등을 자동화 sudo systemctl start/enable/stop/restart/status 서비스명

- name: Ensure nginx is enabled and started
  service:
    name: nginx
    state: started
    enabled: true  # 부팅 시 자동 시작 설정

nginx 서비스가 실행 중이지 않다면 시작한다. 이미 실행 중인 경우 아무 작업도 하지 않는다. (멱등성 보장)
 
 
작업목록(task)에는 단일 모듈 혹은 여러개의 모듈이 정의될 수 있다.
arg로 구성한 task → 파이썬 모듈로 전달 → 노드에서 동작

tasks:
  - name: web server start
    service:
      name: httpd      # 웹 서버 서비스 이름 (ex: Apache)
      state: started   # 서비스를 시작

  - name: ntp server start
    service:
      name: chronyd    # NTP 시간 동기화 서비스
      state: started

  - name: mail server start
    service:
      name: postfix    # 메일 서비스 데몬
      state: started

 
 

플레이북 실행

ansible-playbook 플레이북이름

 

[ 실습 ]

# vi site.yaml ( 플레이북 파일명 = site.yaml )
- name: ansible test
  hosts: dev
  tasks:
  - name: Install httpd
    yum:
      name: httpd
      state: latest

리스트 내의 같은 인자들은 순서상관이 없음, 그러나 길어지는 tasks 속성을 최하위로 배치하는 것이 바람직하다
hosts는 그룹을 사용 ( inventory에서 정의된 dev그룹 = serverc )
yum이라는 모듈을 사용( name: 대상레포, state:latest → 최신버전 )
 

ansible-playbook site.yaml

play[ 플레이단위 ] → task( gathering facts ) → tasks( install httpd ) : changed( 기존 상태는 목표 상태가 아니었기에 명령으로 바꾸었다 = 새로 설치하였다 )

한번더 실행한다면? tasks( install httpd ) : ok ( 원하는 상태 만족, 멱등성을 보장하기에 더 실행하지 않음 )
 
 

다중 플레이

여러 플레이를 하나의 플레이북에 담음 ( 다양한 작업 대상을 지정해서 각각의 대상에게 맞는 작업 목록들을 구성 )

  • task를 여러개로 늘리는 것과 개념이 다름 : 같은 호스트에 여러작업을 수행 ↔ 작업대상 호스트가 달라짐, 각기 다른 작업을 수행
  • host와 task사이에 필요한 옵션이 있는 경우 삽입가능 : remote_user, become 등… ( 플레이단위로 서버에 연결할 사용자를 재구성하거나 권한 상승을 조정 )
  • 각 호스트에서 play 실행은 병렬로 수행됨 → serial로 작성

 

YAML 문법

  • dictionary 형태 : 키-값 페어 데이터
name: testservice
serviceport: 80

{name: testservice, serviceport: 80}
  • 속기형식 : 한줄로 작성 → 가독성은 떨어짐, 간단하게 작성가능
tasks:
- name: httpd service start
	service: name:httpd enabled=true state=started