웹사이트 검색

구성 관리 101: Ansible 플레이북 작성


소개

간단히 말해서, 서버 구성 관리(일반적으로 IT 자동화라고도 함)는 인프라 관리를 코드베이스로 전환하기 위한 솔루션으로, 서버를 배포하는 데 필요한 모든 프로세스를 버전화하고 쉽게 재사용할 수 있는 일련의 프로비저닝 스크립트로 설명합니다. 시간이 지남에 따라 모든 서버 인프라의 무결성을 크게 향상시킬 수 있습니다.

이전 가이드에서 서버 인프라에 대한 구성 관리 전략 구현의 주요 이점, 구성 관리 도구의 작동 방식 및 일반적으로 이러한 도구의 공통점에 대해 설명했습니다.

시리즈의 이 부분에서는 완전한 자동화 프레임워크와 오케스트레이션 기능을 제공하는 구성 관리 도구인 Ansible을 사용하여 서버 프로비저닝을 자동화하는 동시에 궁극적인 단순성과 미니멀리즘이라는 목표를 유지하는 과정을 안내합니다. Apache를 사용하여 Ubuntu 18.04 웹 서버의 배포를 완전히 자동화하기 위해 간단한 예제를 만드는 데 필요한 언어 용어, 구문 및 기능에 중점을 둘 것입니다.

다음 목록에는 목표를 달성하기 위해 자동화해야 하는 모든 단계가 포함되어 있습니다.

  1. apt 캐시 업데이트
  2. 아파치 설치
  3. 사용자 정의 문서 루트 디렉토리 생성
  4. 사용자 지정 문서 루트에 index.html 파일 배치
  5. 템플릿을 적용하여 맞춤형 가상 호스트 설정
  6. Apache 다시 시작

먼저 Ansible에서 사용하는 용어를 살펴보고 플레이북을 작성하는 데 사용할 수 있는 주요 언어 기능에 대한 개요를 살펴보겠습니다. 가이드의 끝에서 Ubuntu 18.04에서 Apache를 설정하는 데 설명된 단계를 자동화하는 전체 프로비저닝 예제의 내용을 찾을 수 있습니다.

참고: 이 가이드는 Ansible 언어를 소개하고 서버 프로비저닝을 자동화하기 위한 플레이북 작성 방법을 제공하기 위한 것입니다. 이 도구를 설치하고 시작하는 데 필요한 단계와 Ansible 명령 및 플레이북을 실행하는 방법을 포함하여 Ansible에 대한 소개 보기를 보려면 Ubuntu 18.04에서 Ansible을 설치하고 구성하는 방법 가이드를 확인하세요.

시작하기

Ansible에 대한 보다 실질적인 보기로 이동하기 전에 이 도구에서 소개하는 중요한 용어와 개념을 숙지하는 것이 중요합니다.

술어

다음 목록에는 Ansible에서 사용되는 가장 관련성이 높은 용어에 대한 간략한 개요가 포함되어 있습니다.

  • 제어 노드: Ansible이 설치된 시스템으로 관리 중인 서버에서 프로비저닝 실행을 담당합니다.
  • 인벤토리: 관리 중인 서버에 대한 정보가 포함된 INI 파일입니다.
  • 플레이북: 자동화해야 하는 일련의 절차가 포함된 YAML 파일입니다.
  • 작업: 실행할 단일 절차를 정의하는 블록(예: 패키지 설치)
  • 모듈: 모듈은 일반적으로 패키지 처리 또는 파일 생성 및 변경과 같은 시스템 작업을 추상화합니다. Ansible에는 다양한 내장 모듈이 있지만 사용자 지정 모듈을 생성할 수도 있습니다.
  • 역할: 재사용 및 공유를 용이하게 하기 위해 미리 정의된 방식으로 구성된 일련의 관련 플레이북, 템플릿 및 기타 파일입니다.
  • 재생: 처음부터 끝까지 실행되는 프로비저닝을 재생이라고 합니다.
  • 사실: 네트워크 인터페이스 또는 운영 체제와 같은 시스템에 대한 정보를 포함하는 전역 변수
  • 핸들러: 서비스 다시 시작 또는 다시 로드와 같은 서비스 상태 변경을 트리거하는 데 사용됩니다.

작업 형식

작업은 Ansible에서 실행해야 하는 단일 자동화 단계를 정의합니다. 일반적으로 모듈 사용 또는 원시 명령 실행이 포함됩니다. 작업은 다음과 같이 표시됩니다.

- name: This is a task
  apt: name=vim state=latest

name 부분은 실제로 선택 사항이지만 작업이 실행될 때 프로비저닝 출력에 표시되므로 권장됩니다. apt 부분은 Debian 기반 배포판에서 패키지 관리를 추상화하는 내장 Ansible 모듈입니다. 이 예제 작업은 패키지 vim의 상태가 latest로 변경되어야 한다고 Ansible에 지시합니다. 그러면 패키지가 아직 설치되지 않은 경우 패키지 관리자가 이 패키지를 설치하게 됩니다.

플레이북 형식

플레이북은 서버 프로비저닝을 자동화하기 위한 일련의 지시문이 포함된 YAML 파일입니다. 다음 예제는 apt 캐시를 업데이트하고 나중에 vim을 설치하는 두 가지 작업을 수행하는 간단한 플레이북입니다.

---
- hosts: all
  become: true
  tasks:
     - name: Update apt-cache 
       apt: update_cache=yes

     - name: Install Vim
       apt: name=vim state=latest

YAML은 들여쓰기를 사용하여 데이터 구조를 직렬화합니다. 따라서 플레이북을 작성할 때, 특히 예제를 복사할 때 올바른 들여쓰기를 유지하기 위해 각별히 주의해야 합니다.

이 가이드가 끝나기 전에 플레이북의 보다 실제적인 예를 자세히 설명합니다. 다음 섹션에서는 Ansible 플레이북을 작성하는 데 사용할 수 있는 가장 중요한 요소와 기능에 대한 개요를 제공합니다.

플레이북 작성

이제 Ansible에서 기본 용어와 플레이북 및 작업의 전체 형식에 익숙해졌으므로 보다 다양한 자동화를 생성하는 데 도움이 되는 몇 가지 플레이북 기능에 대해 알아보겠습니다.

변수 작업

Ansible에서 변수를 정의할 수 있는 다양한 방법이 있습니다. 가장 간단한 방법은 플레이북의 vars 섹션을 사용하는 것입니다. 아래 예제는 나중에 작업 내에서 사용되는 변수 package를 정의합니다.

---
- hosts: all
  become: true
  vars:
     package: vim
  tasks:
     - name: Install Package
       apt: name={{ package }} state=latest

package 변수는 전역 범위를 가지며, 이는 포함된 파일 및 템플릿에서도 프로비저닝의 모든 지점에서 액세스할 수 있음을 의미합니다.

루프 사용

루프는 일반적으로 다른 입력 값을 사용하여 작업을 반복하는 데 사용됩니다. 예를 들어, 10개의 서로 다른 패키지를 설치하기 위해 10개의 작업을 만드는 대신 단일 작업을 만들고 루프를 사용하여 설치하려는 모든 다른 패키지로 작업을 반복할 수 있습니다.

작업 내에서 루프를 만들려면 값 배열과 함께 with_items 옵션을 포함합니다. 콘텐츠는 아래 예와 같이 루프 변수 item을 통해 액세스할 수 있습니다.

- name: Install Packages
  apt: name={{ item }} state=latest
  with_items:
     - vim
     - git
     - curl  

배열 변수를 사용하여 항목을 정의할 수도 있습니다.

---
- hosts: all
  become: true
  vars:
     packages: [ 'vim', 'git', 'curl' ]
  tasks:
     - name: Install Package
       apt: name={{ item }} state=latest
       with_items: "{{ packages }}"

조건부 사용

조건문은 예를 들어 변수 또는 명령의 출력을 기반으로 작업을 실행해야 하는지 여부를 동적으로 결정하는 데 사용할 수 있습니다.

다음 예는 Debian 기반 시스템만 종료합니다.

- name: Shutdown Debian Based Systems
  command: /sbin/shutdown -t now
  when: ansible_os_family == "Debian"

조건부 when은 평가할 식을 인수로 받습니다. 작업은 표현식이 true로 평가되는 경우에만 실행됩니다. 이 예에서는 운영 체제가 데비안 계열인지 확인하기 위해 팩트를 테스트했습니다.

IT 자동화에서 조건문의 일반적인 사용 사례는 명령의 출력에 따라 작업 실행이 달라지는 경우입니다. Ansible을 사용하여 이를 구현하는 방법은 명령 실행 결과를 보유할 변수를 등록한 다음 후속 작업에서 이 변수를 테스트하는 것입니다. 명령의 종료 상태(실패 또는 성공한 경우)를 테스트할 수 있습니다. 정규 표현식과 문자열 구문 분석 명령을 사용해야 할 수도 있지만 출력 내부의 특정 내용을 확인할 수도 있습니다.

다음 예는 php -v 명령의 출력을 기반으로 하는 두 가지 조건부 작업을 보여줍니다. PHP가 이 서버에 설치되지 않은 경우 실행에 실패할 것임을 알고 있으므로 명령의 종료 상태를 테스트합니다. 작업의 ignore_errors 부분은 명령 실행이 실패하더라도 프로비저닝이 계속되도록 하는 데 중요합니다.

- name: Check if PHP is installed
  register: php_installed
  command: php -v
  ignore_errors: true

- name: This task is only executed if PHP is installed
  debug: var=php_install
  when: php_installed|success
  
- name: This task is only executed if PHP is NOT installed
  debug: msg='PHP is NOT installed'
  when: php_installed|failed

여기에 사용된 debug 모듈은 변수의 내용이나 디버그 메시지를 표시하는 데 유용한 모듈입니다. 문자열을 인쇄하거나( msg 인수를 사용할 때) 변수의 내용을 인쇄할 수 있습니다( var 인수를 사용할 때).

템플릿 작업

템플릿은 일반적으로 구성 파일을 설정하는 데 사용되며 이러한 파일을 보다 다양하고 재사용 가능하게 만드는 변수 및 기타 기능을 사용할 수 있습니다. Ansible은 Jinja2 템플릿 엔진을 사용합니다.

다음 예제는 이 호스트에 대한 문서 루트를 설정하기 위한 변수를 사용하여 Apache 가상 호스트를 설정하기 위한 템플릿입니다.

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot {{ doc_root }}

    <Directory {{ doc_root }}>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

기본 제공 모듈 템플릿은 작업에서 템플릿을 적용하는 데 사용됩니다. vhost.tpl 위에 템플릿 파일의 이름을 지정하고 플레이북과 동일한 디렉터리에 배치한 경우 템플릿을 적용하여 기본 Apache 가상 호스트를 대체하는 방법은 다음과 같습니다.

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf

핸들러 정의 및 트리거

핸들러는 재시작 또는 중지와 같은 서비스의 상태 변경을 트리거하는 데 사용됩니다. 일반 작업과 매우 유사해 보일 수 있지만 핸들러는 이전에 작업의 notify 지시문에서 트리거된 경우에만 실행됩니다. 일반적으로 플레이북의 handlers 섹션에서 배열로 정의되지만 별도의 파일에 있을 수도 있습니다.

Apache 가상 호스트를 설정한 이전 템플릿 사용 예를 고려해 보겠습니다. 가상 호스트 변경 후 Apache가 다시 시작되도록 하려면 먼저 Apache 서비스에 대한 핸들러를 생성해야 합니다. 플레이북 내에서 핸들러를 정의하는 방법은 다음과 같습니다.

handlers:
    - name: restart apache
      service: name=apache2 state=restarted
    
    - name: other handler
      service: name=other state=restarted

여기서 name 지시문은 이 핸들러의 고유한 식별자이기 때문에 중요합니다. 작업에서 이 핸들러를 트리거하려면 notify 옵션을 사용해야 합니다.

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf
  notify: restart apache

Ansible 플레이북 작성을 시작하는 데 사용할 수 있는 가장 중요한 기능 중 일부를 살펴보았습니다. 다음 섹션에서는 Ubuntu에서 Apache의 설치 및 구성을 자동화하는 플레이북의 보다 실제적인 예를 살펴보겠습니다.

예제 플레이북

이제 이 가이드의 소개에서 설명한 대로 Ubuntu 18.04 시스템 내에서 Apache 웹 서버 설치를 자동화하는 플레이북을 살펴보겠습니다.

Apache 설정을 위한 템플릿 파일과 웹 서버에서 제공할 HTML 파일을 포함한 전체 예제는 Vagrant에서 찾을 수 있습니다.

플레이북 콘텐츠

플레이북의 전체 내용은 귀하의 편의를 위해 여기에서 제공됩니다.

  1. ---
  2. - hosts: all
  3. become: true
  4. vars:
  5. doc_root: /var/www/example
  6. tasks:
  7. - name: Update apt
  8. apt: update_cache=yes
  9. - name: Install Apache
  10. apt: name=apache2 state=latest
  11. - name: Create custom document root
  12. file: path={{ doc_root }} state=directory owner=www-data group=www-data
  13. - name: Set up HTML file
  14. copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
  15. - name: Set up Apache virtual host file
  16. template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
  17. notify: restart apache
  18. handlers:
  19. - name: restart apache
  20. service: name=apache2 state=restarted

이 플레이북의 각 부분을 자세히 살펴보겠습니다.

호스트: 모두

되다: 사실

바르스

작업

세 번째 작업은 내장 모듈 파일을 사용하여 문서 루트 역할을 할 디렉토리를 만듭니다. 이 모듈은 파일 및 디렉토리를 관리하는 데 사용할 수 있습니다.

네 번째 작업은 모듈 복사를 사용하여 로컬 파일을 원격 서버에 복사합니다. Apache에서 호스팅하는 웹 사이트로 사용할 간단한 HTML 파일을 복사하고 있습니다.

핸들러

플레이북 실행

이 플레이북의 콘텐츠를 Ansible 제어 노드에 다운로드하면 ansible-playbook을 사용하여 인벤토리의 하나 이상의 노드에서 실행할 수 있습니다. 다음 명령은 현재 시스템 사용자로 연결하기 위해 SSH 키 쌍 인증을 사용하여 기본 인벤토리 파일의 모든 호스트에서 플레이북을 실행합니다.

  1. ansible-playbook playbook.yml

-l을 사용하여 단일 호스트 또는 인벤토리의 호스트 그룹으로 실행을 제한할 수도 있습니다.

  1. ansible-playbook -l host_or_group playbook.yml

원격 서버에 연결하기 위해 다른 SSH 사용자를 지정해야 하는 경우 해당 명령에 -u user 인수를 포함할 수 있습니다.

  1. ansible-playbook -l host_or_group playbook.yml -u remote-user

Ansible 명령 및 플레이북을 실행하는 방법에 대한 자세한 내용은 Ubuntu 18.04에서 Ansible을 설치하고 구성하는 방법에 대한 가이드를 참조하세요.

결론

Ansible은 프로비저닝 스크립트에 YAML을 사용하여 학습 곡선이 낮은 미니멀리스트 IT 자동화 도구입니다. 여기에는 패키지 설치 및 템플릿 작업과 같은 작업을 추상화하는 데 사용할 수 있는 많은 내장 모듈이 있습니다. 간소화된 인프라 요구 사항과 간단한 언어는 구성 관리를 시작하는 사용자에게 적합할 수 있습니다. 그러나 Puppet 및 Chef와 같은 보다 복잡한 도구에서 찾을 수 있는 일부 고급 기능이 부족할 수 있습니다.

이 시리즈의 다음 부분에서는 프로비저닝 스크립트를 작성하기 위해 Ruby 기반의 표현력 있고 강력한 사용자 지정 DSL을 사용하는 잘 알려진 구성 관리 도구인 Puppet의 실용적인 개요를 살펴보겠습니다.