Ansible Playbook 작성하는 구성 관리 101

소개

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

이전 가이드에서 서버 인프라에 구성 관리 전략을 구현하는 주요 이점, 구성 관리 도구의 작동 방식 및 이러한 도구의 일반적인 특징에 대해 이야기했습니다.

이 시리즈의 이 부분에서는 Ansible을 사용하여 서버 프로비저닝을 자동화하는 프로세스를 안내합니다. Ansible은 완전한 자동화 프레임워크와 오케스트레이션 기능을 제공하면서 궁극적인 단순함과 최소주의를 유지합니다. 우리는 Ubuntu 18.04 웹 서버를 Apache를 사용하여 완전히 자동화하는 간단한 예제를 만드는 데 필요한 언어 용어, 구문 및 기능에 중점을 둘 것입니다.

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

  1. apt 캐시 업데이트
  2. Apache 설치
  3. 사용자 정의 문서 루트 디렉토리 생성
  4. 커스텀 문서 루트에 index.html 파일을 배치합니다.
  5. 우리의 커스텀 가상 호스트를 설정하기 위해 템플릿을 적용합니다.
  6. 아파치를 재시작합니다.

우리는 먼저 Ansible에서 사용하는 용어를 살펴본 후, 플레이북을 작성하는 데 사용할 수 있는 주요 언어 기능을 개요로 살펴볼 것입니다. 가이드의 끝에는 Ubuntu 18.04에서 아파치를 설정하는 단계를 자동화하기 위한 전체 프로비저닝 예제의 내용이 포함되어 있습니다.

참고: 이 가이드는 Ansible 언어를 소개하고 서버 프로비저닝을 자동화하기 위해 플레이북을 작성하는 방법에 대해 알려드립니다. Ansible을 설치하고 이 도구를 시작하는 데 필요한 단계뿐만 아니라 Ansible 명령 및 플레이북 실행 방법을 포함한 Ansible의 보다 입문적인 뷰를 얻으려면 우리의 Ubuntu 18.04에 Ansible 설치 및 구성하는 방법 가이드를 확인하세요.

시작하기

Ansible을 더 실용적으로 살펴보기 전에, 이 도구에서 소개된 중요한 용어와 개념을 알아야 합니다.

용어

다음 목록은 Ansible에서 사용하는 가장 중요한 용어들을 간단히 설명한 것입니다:

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

작업 형식

A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:

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

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

플레이북 형식

플레이북은 서버 프로비저닝을 자동화하기 위한 지시문 시리즈를 포함하는 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로 평가될 경우에만 작업이 실행됩니다. 이 예에서는 운영 체제가 Debian 패밀리인지 확인하기 위해 fact를 테스트했습니다.

A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.

다음 예제는 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>

내장 모듈 template은 템플릿을 작업에서 적용하는 데 사용됩니다. 위에서 템플릿 파일의 이름을 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 파일의 완전한 예제는 Github에서 찾을 수 있습니다. 해당 폴더에는 Vagrant가 관리하는 가상 머신을 사용하여 단순화 된 설정에서 플레이북을 테스트 할 수있게하는 Vagrantfile도 포함되어 있습니다.

플레이북 내용

이 플레이북의 전체 내용은 여기에서 편의를 위해 사용할 수 있습니다:

playbook.yml
  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

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

호스트: 모두
플레이북은 인벤토리(호스트: 모두)에 있는 모든 호스트에 적용되어야 함을 명시하여 시작됩니다. 이 플레이북의 실행을 특정 호스트나 호스트 그룹으로 제한할 수 있습니다. 이 옵션은 실행 시간에 덮어쓸 수 있습니다.

become: true
become: true 부분은 모든 작업을 실행할 때 권한 상승 (sudo)을 사용하도록 Ansible에 지시합니다. 이 옵션은 작업별로 덮어쓸 수 있습니다.

vars
작업에서 사용되는 doc_root와 같은 변수를 정의합니다. 이 섹션에는 여러 변수가 포함될 수 있습니다.

tasks
실제 작업이 정의되는 섹션입니다. 첫 번째 작업은 apt 캐시를 업데이트하고, 두 번째 작업은 apache2 패키지를 설치합니다.

세 번째 작업은 내장된 모듈 file을 사용하여 문서 루트로 사용할 디렉토리를 생성합니다. 이 모듈은 파일 및 디렉토리를 관리하는 데 사용될 수 있습니다.

네 번째 작업은 copy 모듈을 사용하여 로컬 파일을 원격 서버로 복사합니다. 우리는 Apache가 호스팅하는 웹사이트로 제공될 간단한 HTML 파일을 복사합니다.

handlers
마지막으로, 서비스가 선언되는 handlers 섹션이 있습니다. Apache 템플릿이 적용되는 네 번째 작업에서 알림을 받는 apache 재시작 핸들러를 정의합니다.

플레이북 실행하기

이 플레이북 내용을 Ansible 제어 노드에 다운로드한 후에는 인벤토리에서 하나 이상의 노드에 대해 실행하려면 ansible-playbook을 사용할 수 있습니다. 다음 명령은 현재 시스템 사용자로서 SSH 키페어 인증을 사용하여 기본 인벤토리 파일에서 모든 호스트에서 플레이북을 실행합니다:

  1. ansible-playbook playbook.yml

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

  1. ansible-playbook -l host_or_group playbook.yml

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

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

Ansible 명령 및 플레이북을 실행하는 방법에 대한 자세한 내용은 우분투 18.04에 Ansible을 설치하고 구성하는 가이드를 참조하십시오.

결론

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

이 시리즈의 다음 부분에서, 우리는 Puppet을 실용적으로 살펴볼 것입니다. Puppet은 Ruby를 기반으로 한 표현력 있고 강력한 사용자 정의 DSL을 사용하여 프로비저닝 스크립트를 작성하는 인기있고 잘 확립된 구성 관리 도구입니다.

Source:
https://www.digitalocean.com/community/tutorials/configuration-management-101-writing-ansible-playbooks