오토에버 클라우드 2기 68일차(ansible)
1. Ansible 개요
1.1. Ansible이란?
Ansible은 Red Hat이 개발하고 관리하는 오픈소스 IT 자동화 도구임. 프로비저닝, 환경 설정, 애플리케이션 배포 등 수작업으로 진행하던 IT 업무를 코드 기반(IaC, Infrastructure as Code)으로 작성하여, 여러 시스템에 일관성 있게 적용할 수 있도록 돕는 역할을 수행함
1.2. Ansible의 주요 특징
- 에이전트 없음 (Agentless): 관리 대상 서버에 별도의 에이전트를 설치할 필요 없이, 표준 프로토콜인 SSH를 통해 원격으로 접속하여 작업을 수행함 이는 초기 설정이 매우 간단하고 관리 부담이 적다는 큰 장점으로 작용함
- 멱등성 (Idempotent): 동일한 작업을 여러 번 수행하더라도 시스템의 최종 결과는 항상 동일하게 보장 예를 들어, “nginx가 설치되어 있어야 한다”는 작업을 100번 실행해도, nginx가 이미 설치되어 있다면 아무런 변경도 일으키지 않음 이는 예측 가능하고 안정적인 시스템 관리를 가능하게 한다
- 쉬운 사용법 (YAML): 자동화 작업 절차(Playbook)를 사람이 읽고 쓰기 쉬운 YAML 형식으로 작성 복잡한 프로그래밍 지식 없이도 시스템 관리 작업을 쉽게 기술할 수 있음
- 다양한 모듈 제공: 파일 복사, 패키지 설치와 같은 기본적인 작업부터 AWS, GCP 등 클라우드 인프라를 제어하는 수천 개의 모듈을 기본으로 제공하여, 거의 모든 자동화 작업을 수행할 수 있다
2. Ansible 아키텍처
Ansible은 제어 노드(Control Node)와 관리 노드(Managed Node)라는 두 가지 유형의 시스템으로 구성
- 제어 노드 (Control Node): Ansible이 설치되고 실행되는 중앙 서버 Linux 또는 WSL이 설치된 Windows 환경이어야 한다 이 노드에서 플레이북을 실행하여 여러 관리 노드를 제어
- 관리 노드 (Managed Node): 제어 노드가 관리하는 원격 대상 서버 별도의 에이전트 설치는 필요 없지만, 제어 노드와 SSH 통신이 가능해야 한다
- 인벤토리 (Inventory): 제어 노드가 관리할 관리 노드들의 목록(IP 주소 또는 호스트 이름)을 정의해 놓은 파일 그룹으로 묶어 관리할 수 있다
- 플레이북 (Playbook): 관리 노드에서 수행할 작업들의 절차를 YAML 형식으로 순서대로 작성해 놓은 스크립트
- 모듈 (Module): 플레이북의 각 작업(Task)에서 실제로 일을 수행하는 코드 단위 (예:
apt모듈,copy모듈) - 플러그인 (Plugin): Ansible의 핵심 기능을 확장하는 코드 (예: 인벤토리 연결 방식, 로그 출력 방식 등)
3. Ansible 설치 및 기본 설정
3.1. 제어 노드에 Ansible 설치
Python 설치 확인: Ansible은 Python 기반이므로, 제어 노드에 Python3가 설치되어 있어야 한다
Ansible 설치:
1 2 3 4 5 6
# Ubuntu/Debian sudo apt update sudo apt install -y ansible # RHEL/CentOS sudo yum install -y ansible
설치 확인:
ansible --version
3.2. 인벤토리(Inventory) 작성
관리할 서버 목록을 /etc/ansible/hosts 파일 또는 별도의 파일에 작성
기본 형식 (INI):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# /etc/ansible/hosts # 개별 호스트 192.168.1.10 server1.example.com # 그룹으로 묶어서 관리 [webservers] web1.example.com web2.example.com [db_servers] db1.example.com # EC2 인스턴스 관리 예시 [ec2_instances] worker1 ansible_host=54.180.1.1 ansible_user=ubuntu ansible_ssh_private_key_file=/path/to/my-key.pem
인벤토리 확인:
ansible-inventory -i /etc/ansible/hosts --list
3.3. 관리 노드와 SSH 접속 설정
Ansible은 비밀번호 입력 없이 SSH 접속이 가능해야한다
- 제어 노드에서 SSH 키 생성:
ssh-keygen - 관리 노드로 SSH 공개키 복사:
ssh-copy-id <관리노드_계정>@<관리노드_IP>(EC2의 경우,.pem키 파일을 사용하므로 이 과정은 필요 없음)
3.4. Ad-Hoc 명령으로 연결 테스트
플레이북 작성 전, 간단한 명령(Ad-Hoc Command)을 실행하여 인벤토리와 SSH 연결이 정상적인지 확인
모든 호스트에
ping모듈 실행 (연결 테스트):1
ansible all -m pingwebservers그룹의 메모리 사용량 확인 (shell모듈):1
ansible webservers -m shell -a "free -h"
db_servers그룹에nginx패키지 설치 (apt모듈):-b옵션은become의 약자로,sudo권한으로 실행하라는 의미임.1
ansible db_servers -m apt -a "name=nginx state=present" -b
4. 플레이북(Playbook) 작성 및 실행
4.1. 플레이북 기본 구조
플레이북은 하나 이상의 플레이(Play)로 구성되며, 각 플레이는 특정 호스트 그룹에 대해 실행할 작업(Task)들의 목록을 가짐
기본 플레이북 예시 (
first-playbook.yml):1 2 3 4 5 6 7
--- - name: My First Play hosts: all tasks: - name: Print Message debug: msg: "Hello Ansible World"
4.2. 플레이북 실행 및 검증
- 문법 검사:
ansible-playbook --syntax-check first-playbook.yml - 실행:
ansible-playbook first-playbook.yml - 실행 점검 (Dry Run):
--check옵션을 사용하면, 실제로 시스템을 변경하지 않고 어떤 변경이 일어날지만 미리 확인할 수 있음
4.3. 실습: Nginx 웹 서버 구성 플레이북
Nginx를 설치하고, 직접 만든 설정 파일과 웹 페이지를 배포하는 전체 과정을 플레이북으로 자동화
사전 파일 준비:
index.html: 배포할 웹 페이지 파일nginx.conf: 적용할 Nginx 설정 파일
플레이북 작성 (
webserver.yml):1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
--- - name: Configure Nginx Web Server hosts: webservers become: yes # 모든 작업을 sudo 권한으로 실행 tasks: - name: Ensure nginx is installed ansible.builtin.package: name: nginx state: present update_cache: yes - name: Copy Nginx config file ansible.builtin.copy: src: ./nginx.conf dest: /etc/nginx/sites-available/default - name: Copy homepage file ansible.builtin.template: src: ./index.html dest: /usr/share/nginx/html/index.html - name: Ensure nginx is started and enabled ansible.builtin.service: name: nginx state: started enabled: yes
플레이북 실행:
ansible-playbook webserver.yml
5. 변수(Variables)와 팩트(Facts)
5.1. 변수 사용법
반복적인 값을 변수로 정의하여 플레이북의 재사용성과 가독성을 높일 수 있음
변수의 종류 및 우선순위 (높은 순):
- 추가 변수 (Extra Vars):
ansible-playbook -e "user=adam"와 같이 실행 시점에 직접 전달 - 플레이북 변수: 플레이북 내의
vars:섹션에 정의 - 호스트/그룹 변수: 인벤토리 파일에 특정 호스트나 그룹에 대해 정의
- 작업 변수 (Registered Vars):
register:키워드를 사용하여 이전 작업의 실행 결과를 변수에 저장
- 추가 변수 (Extra Vars):
작업 변수 예시:
1 2 3 4 5 6 7
- name: Run whoami command ansible.builtin.command: whoami register: command_result - name: Print the result ansible.builtin.debug: var: command_result.stdout
5.2. Ansible Vault: 민감한 데이터 암호화
비밀번호, API 키 등 민감한 정보를 안전하게 암호화하여 관리하는 기능
- 암호화된 파일 생성:
ansible-vault create secrets.yml - 기존 파일 암호화:
ansible-vault encrypt vars.yml - 암호화된 파일 편집:
ansible-vault edit secrets.yml - 플레이북 실행 시 암호 요청:
ansible-playbook my-playbook.yml --ask-vault-pass
5.3. 팩트 (Facts)
Ansible이 플레이북을 실행하기 전에 각 관리 노드에 접속하여 자동으로 수집하는 시스템 정보(OS 버전, IP 주소, 메모리 등) ansible_facts 변수를 통해 접근 가능
팩트 사용 예시:
1 2 3 4 5
- name: Print OS and IP address ansible.builtin.debug: msg: > OS is and IP address is
6. 제어 구조: 반복, 조건, 핸들러
6.1. 반복문 (loop)
동일한 작업을 다른 값으로 여러 번 반복할 때 사용. item 변수로 각 항목에 접근
1
2
3
4
5
6
7
8
- name: Install multiple packages
ansible.builtin.apt:
name: ""
state: present
loop:
- nginx
- git
- tree
6.2. 조건문 (when)
특정 조건이 참일 때만 작업을 실행. Ansible 팩트와 함께 사용하면 특정 OS에서만 작업을 수행하는 등 유연한 제어가 가능
1
2
3
- name: Shutdown Debian family systems
ansible.builtin.command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian"
6.3. 핸들러 (Handlers)
특정 작업의 상태가 변경(changed)되었을 때만 실행되는 특별한 작업 주로 설정 파일이 변경되었을 때만 서비스를 재시작하는 용도로 사용됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---
- name: Configure and restart Apache
hosts: webservers
become: yes
tasks:
- name: Copy Apache config file
ansible.builtin.copy:
src: httpd.conf
dest: /etc/httpd/conf/httpd.conf
notify: # 이 작업이 'changed' 상태가 되면 아래 핸들러를 호출
- Restart Apache
handlers: # notify에 의해 호출될 작업 목록
- name: Restart Apache
ansible.builtin.service:
name: httpd
state: restarted