순차 Ansible 플레이북을 이용한 다단계 배포 마스터하기

Ansible을 이용해 복잡한 다단계 애플리케이션 배포를 설계하고 실행하는 방법을 알아보세요. 이 가이드는 개별 배포 단계를 위한 순차 플레이북 생성, 효과적인 오류 처리 구현, 그리고 롤백 전략 개발을 다룹니다. 실용적인 예시와 모범 사례를 통해 견고하고 자동화된 애플리케이션 배포 기술을 마스터하세요.

33 조회수

순차 Ansible 플레이북을 활용한 다단계 배포 마스터하기

애플리케이션 배포 자동화는 현대 DevOps 실무의 초석입니다. 단일 플레이북으로 많은 작업을 처리할 수 있지만, 복잡한 애플리케이션은 종종 단계별 다단계 배포 프로세스를 필요로 합니다. 여기에는 데이터베이스 스키마 업데이트, 애플리케이션 코드 배포, 구성 변경 및 배포 후 검증이 포함될 수 있습니다. 이러한 개별 단계를 효율적이고 안정적으로 오케스트레이션하려면 구조화된 접근 방식이 필요합니다. 강력한 플레이북 기능을 갖춘 Ansible이 이에 이상적입니다. 이 가이드에서는 명확한 순서 지정, 효과적인 오류 처리 및 단계 간의 원활한 전환에 중점을 두어 순차 Ansible 플레이북을 활용하여 강력한 다단계 배포를 설계하고 실행하는 방법을 안내합니다.

다단계 배포에 순차 플레이북을 사용하는 이유?

애플리케이션 배포는 단순히 파일을 복사하는 것 이상을 포함하는 경우가 많습니다. 다음과 같은 작업이 필요할 수 있습니다.

  • 환경 준비: 디렉토리 생성, 권한 설정, 종속성 설치.
  • 데이터베이스 업데이트: 스키마 마이그레이션 실행, 초기 데이터 시딩.
  • 애플리케이션 코드 배포: 새 코드 버전 전송, 서비스 재시작.
  • 서비스 구성: 애플리케이션 구성 업데이트, 데몬 다시 로드.
  • 배포 후 확인: 스모크 테스트 실행, 서비스 가용성 확인.

이를 별도의 순차 플레이북으로 나누면 여러 가지 이점이 있습니다.

  • 모듈성: 각 플레이북은 단일 단계에 중점을 두어 이해, 유지 관리 및 재사용이 더 쉽습니다.
  • 가독성: 복잡한 논리가 관리 가능한 청크로 나뉩니다.
  • 제어: 특정 단계를 독립적으로 또는 더 큰 워크플로우의 일부로 실행할 수 있습니다.
  • 오류 격리: 한 단계에서 오류가 발생하면 다른 배포 부분에 영향을 주지 않고 원인을 쉽게 파악하고 특정 변경 사항을 롤백할 수 있습니다.
  • 멱등성: 잘 작성된 플레이북은 본질적으로 멱등성이므로 여러 번 실행해도 한 번 실행하는 것과 동일한 효과를 냅니다. 이는 안전한 재시도에 중요합니다.

다단계 배포 워크플로우 설계

Ansible 코드를 작성하기 전에 배포 단계를 계획하십시오. 논리적 단계, 종속성 및 실행 순서를 파악합니다. 일반적인 워크플로우는 다음과 같습니다.

  1. 배포 전 확인: 대상 환경이 준비되었는지 확인합니다.
  2. 데이터베이스 마이그레이션: 필요한 데이터베이스 스키마 변경 사항을 적용합니다.
  3. 애플리케이션 배포: 새 버전의 애플리케이션 코드를 배포합니다.
  4. 서비스 재시작/다시 로드: 새 코드로 애플리케이션 서비스를 온라인 상태로 전환합니다.
  5. 배포 후 검증: 배포 성공을 확인하기 위한 테스트를 실행합니다.

각 단계에 대해 필요한 Ansible 작업과 해당 작업이 포함될 플레이북을 고려합니다.

플레이북 순차 실행

Ansible은 --playbook-diransible-playbook 명령을 사용하여 플레이북을 하나씩 실행하는 간단한 방법을 제공합니다. 가장 간단한 방법은 CI/CD 파이프라인이나 명령줄에서 명령을 연결하는 것입니다.

다음과 같은 플레이북 파일이 있다고 가정해 보겠습니다.

  • 01-database-migration.yml
  • 02-deploy-application.yml
  • 03-restart-services.yml
  • 04-smoke-tests.yml

다음과 같이 순차적으로 실행할 수 있습니다.

ansible-playbook -i inventory.ini 01-database-migration.yml
ansible-playbook -i inventory.ini 02-deploy-application.yml
ansible-playbook -i inventory.ini 03-restart-services.yml
ansible-playbook -i inventory.ini 04-smoke-tests.yml

--skip-tags 또는 --limit 사용

더 고급 시나리오에서는 여러 논리적 단계를 단일 플레이북으로 결합하고 태그를 사용하여 실행을 제어할 수 있습니다. 그러나 진정한 다단계 분리를 위해서는 별도의 플레이북이 일반적으로 선호됩니다. 플레이북의 일부를 실행하거나 특정 플레이북을 건너뛰려면 명령줄 인수를 사용할 수 있습니다.

플레이북 건너뛰기: 03-restart-services.yml에 실패하면 이전 플레이북을 다시 실행한 다음 서비스 다시 시작을 다시 시도할 수 있습니다. 성공한 플레이북을 건너뛸 수 있습니다.

특정 단계로 제한: --limit 플래그를 사용하여 실행을 특정 호스트 또는 그룹으로 제한할 수도 있으며, 이는 테스트에 유용할 수 있습니다.

오류 처리 및 롤백 전략 통합

안정적인 배포에는 문제가 발생했을 때를 대비한 계획이 필요합니다.

ignore_errorsfailed_when

기본적으로 Ansible은 작업이 실패하면 실행을 중지합니다. 이 동작을 제어할 수 있습니다.

  • ignore_errors: true: 작업이 실패하더라도 플레이북을 계속 진행할 수 있습니다. 일반적으로 중요하지 않은 작업이나 후속 작업에서 정리 또는 보상 작업을 수행할 때 주의해서 사용합니다.
  • failed_when:: 작업이 실패한 것으로 간주될 사용자 지정 조건을 정의합니다. 이는 예상되는 비치명적 오류를 처리하거나 특정 결과를 검증하는 데 강력합니다.
- name: Check service status (potentially non-fatal)
  command: systemctl status myapp
  register: service_status
  ignore_errors: true

- name: Fail if service is not active
  fail:
    msg: "Service myapp is not running!"
  when: "service_status.rc != 0"

롤백 플레이북

중요한 배포의 경우 전용 롤백 플레이북을 준비합니다. 이러한 플레이북은 해당 배포 플레이북이 만든 변경 사항을 되돌리기 위해 설계되어야 합니다.

  • 01-database-migration-rollback.yml: 스키마 변경 사항을 되돌립니다.
  • 02-deploy-application-rollback.yml: 이전 애플리케이션 버전을 배포하거나 백업을 복원합니다.
  • 03-restart-services-rollback.yml: 이전 상태로 서비스를 다시 시작합니다.

롤백 트리거 예시: CI/CD 파이프라인에서 04-smoke-tests.yml 플레이북이 실패하면 롤백 플레이북을 역순으로 실행합니다.

# 04-smoke-tests.yml이 실패하는 경우:
ansible-playbook -i inventory.ini 03-restart-services-rollback.yml
ansible-playbook -i inventory.ini 02-deploy-application-rollback.yml
ansible-playbook -i inventory.ini 01-database-migration-rollback.yml

block, rescue, always 사용

Ansible의 block, rescue, always 구문은 단일 플레이북 내에서 오류를 처리하는 보다 구조화된 방법을 제공합니다. 플레이북 간의 순차 지정에는 사용되지 않지만, 실패할 수 있는 작업 그룹을 캡슐화하고 실패 시 수행할 작업을 정의하는 데 탁월합니다.

- block:
    - name: Deploy new application code
      copy:
        src: /path/to/new/app/
        dest: /var/www/myapp/

    - name: Restart application service
      service:
        name: myapp
        state: restarted

  rescue:
    - name: Attempt to revert to previous version
      copy:
        src: /path/to/old/app/
        dest: /var/www/myapp/

    - name: Restart application service after rollback
      service:
        name: myapp
        state: restarted

  always:
    - name: Log deployment attempt
      debug:
        msg: "Deployment attempt finished."

이 접근 방식은 단일 배포 단계 플레이북 내에서 관련 작업을 그룹화하는 데 유용합니다.

고급 고려 사항

플레이북 간 상태 관리

때로는 한 플레이북의 작업이 다른 플레이북에 결과를 알려야 할 수 있습니다. 다음을 사용하여 이를 달성할 수 있습니다.

  • 팩트 캐싱: 팩트 캐싱이 활성화된 경우 한 플레이북에서 수집한 팩트는 동일한 Ansible 세션 내에서 실행되는 후속 플레이북에서 사용할 수 있습니다.
  • 임시 파일/데이터베이스: 중요 상태 정보 또는 출력을 임시 파일이나 전용 상태 테이블에 기록하여 후속 플레이북에서 읽을 수 있도록 합니다.

버전 관리 및 오케스트레이션 도구

복잡한 오케스트레이션의 경우 순차 Ansible 플레이북을 상위 수준 도구에 통합하는 것을 고려합니다.

  • CI/CD 파이프라인: Jenkins, GitLab CI, GitHub Actions 또는 CircleCI와 같은 도구는 다단계 배포를 정의하고 트리거하는 데 탁월합니다. 파이프라인 구성 내에서 ansible-playbook 명령의 순서를 정의합니다.
  • Ansible Tower/AWX: 엔터프라이즈급 오케스트레이션의 경우 Ansible Tower(현재 Automation Platform) 또는 해당 오픈 소스 동반자인 AWX는 여러 플레이북을 연결할 수 있는 복잡한 작업 템플릿을 예약, 모니터링 및 관리하기 위한 강력한 UI를 제공합니다.

세분화된 제어를 위한 태깅

별도의 플레이북을 사용하여 개별 단계를 구분하는 것을 권장하지만, 플레이북 내에서 태그를 사용할 수도 있습니다. 단일 단계에 대해 매우 큰 플레이북(예: 데이터베이스 마이그레이션)이 있는 경우 특정 작업을 태그하고 ansible-playbook --tags <tag_name>을 사용하여 해당 작업만 실행할 수 있습니다.

이는 단계 간의 순차 지정보다는 단계 내에서 세분화된 제어에 관한 것입니다.

다단계 배포 모범 사례

  • 플레이북 집중 유지: 각 플레이북은 한 가지 작업을 잘 수행해야 합니다(예: 데이터베이스 마이그레이션, 애플리케이션 배포).
  • 플레이북 이름 명확하게 지정: 단계와 순서를 반영하는 명명 규칙을 사용합니다(예: 01-, 02-).
  • 멱등성 구현: 안전한 재시도를 위해 모든 작업이 멱등성이 되도록 합니다.
  • 롤백 테스트: 롤백 절차가 예상대로 작동하는지 정기적으로 테스트합니다.
  • 버전 관리 사용: 모든 플레이북과 인벤토리 파일을 버전 관리 시스템(Git 등)에 저장합니다.
  • 오케스트레이션 자동화: CI/CD 파이프라인 또는 Ansible Tower/AWX와 같은 도구를 사용하여 순차 플레이북 실행을 자동화합니다.
  • 워크플로우 문서화: 단계, 목적, 종속성 및 롤백 절차를 명확하게 문서화합니다.

결론

Ansible을 사용하여 다단계 배포를 마스터하는 것은 구조화된 계획과 도구 기능을 효과적으로 활용하는 것입니다. 복잡한 배포를 일련의 순차적이고 명확하게 정의된 플레이북으로 분할함으로써 모듈성, 제어 및 복원력을 얻을 수 있습니다. 강력한 오류 처리 및 롤백 전략을 구현하면 자동화가 효율적일 뿐만 아니라 안전하여 다운타임과 위험을 최소화할 수 있습니다. 명령줄에서 연결되든 전용 CI/CD 플랫폼에서 오케스트레이션되든, 순차 Ansible 플레이북은 안정적인 애플리케이션 전달을 위한 강력한 프레임워크를 제공합니다.