Post

오토에버 클라우드 2기 68일차(ansible)

오토에버 클라우드 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 접속이 가능해야한다

  1. 제어 노드에서 SSH 키 생성: ssh-keygen
  2. 관리 노드로 SSH 공개키 복사: ssh-copy-id <관리노드_계정>@<관리노드_IP> (EC2의 경우, .pem 키 파일을 사용하므로 이 과정은 필요 없음)

3.4. Ad-Hoc 명령으로 연결 테스트

플레이북 작성 전, 간단한 명령(Ad-Hoc Command)을 실행하여 인벤토리와 SSH 연결이 정상적인지 확인

  • 모든 호스트에 ping 모듈 실행 (연결 테스트):

    1
    
    ansible all -m ping
    
  • webservers 그룹의 메모리 사용량 확인 (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를 설치하고, 직접 만든 설정 파일과 웹 페이지를 배포하는 전체 과정을 플레이북으로 자동화

  1. 사전 파일 준비:

    • index.html: 배포할 웹 페이지 파일
    • nginx.conf: 적용할 Nginx 설정 파일
  2. 플레이북 작성 (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
    
  3. 플레이북 실행: ansible-playbook webserver.yml

 

5. 변수(Variables)와 팩트(Facts)

5.1. 변수 사용법

반복적인 값을 변수로 정의하여 플레이북의 재사용성과 가독성을 높일 수 있음

  • 변수의 종류 및 우선순위 (높은 순):

    1. 추가 변수 (Extra Vars): ansible-playbook -e "user=adam" 와 같이 실행 시점에 직접 전달
    2. 플레이북 변수: 플레이북 내의 vars: 섹션에 정의
    3. 호스트/그룹 변수: 인벤토리 파일에 특정 호스트나 그룹에 대해 정의
    4. 작업 변수 (Registered Vars): register: 키워드를 사용하여 이전 작업의 실행 결과를 변수에 저장
  • 작업 변수 예시:

    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
This post is licensed under CC BY 4.0 by the author.