CI/CD 성공 사례

지속적 통합, 전달 및 배포는 DevOps 무브먼트를 기반으로 탄생한 소프트웨어 개발 관행입니다. 이 방식을 통해 제품 구축, 테스트 및 릴리스 프로세스가 보다 효율적으로 개선되며 사용자에게 작동하는 코드를 기존 방식보다 더욱 빠르게 제공할 수 있습니다. 적절히 수행된 경우 빌드 파이프라인은 팀이 작동하는 소프트웨어를 진행 속도에 맞춰 전달하고 최신 변경 사항에 대한 피드백을 적시에 받을 수 있도록 지원합니다.

CI/CD 파이프라인 구축은 일회성으로 그쳐서는 안 됩니다. 개발 중인 소프트웨어와 마찬가지로 CI/CD 관행에 반복적인 접근 방식을 취하는 것이 좋습니다. 지속적으로 데이터를 분석하고 피드백을 수용하여 CI/CD 프로세스를 개선해야 합니다. 이 글에서는 파이프라인에 적용을 고려할 지속적 통합/지속적 전달 성공 사례를 살펴보겠습니다.

조기에, 자주 커밋하기

모든 소스 코드, 구성 파일, 스크립트, 라이브러리 및 실행 파일이 소스 관리 시스템에 있는지 확인하는 것은 지속적 통합을 구현하여 모든 변경 사항을 추적하기 위한 필수적 첫 단계입니다.

하지만 도구만으로 충분하지 않으며, 중요한 것은 사용 방식입니다. 지속적 통합은 작은 업데이트를 더 자주 공유하여 여러 기여자의 변경 사항을 통합하는 프로세스를 보다 간편하게 만드는 것입니다.

각각의 커밋은 일련의 자동화된 테스트를 트리거하여 변경 사항에 대한 즉각적인 피드백을 제공합니다. 주기적 커밋을 통해 팀원들이 동일한 기반에서 작업할 수 있으므로 협업이 촉진되며 복잡한 대규모 변경 사항을 통합할 때 불편한 병합 충돌의 가능성이 감소합니다.

지속적 통합의 이점을 활용하려면 모두가 메인(마스터) 브랜치로 푸시하여 다른 팀원에게 변경 사항을 공유하고, 작업 사본을 업데이트하여 다른 모든 사람의 변경 사항을 수신해야 합니다. 일반적으로 하루에 한 번 이상 메인(마스터) 브랜치 커밋을 목표로 하는 것이 좋습니다.

긴 호흡(long-running)의 브랜치에서 작업하는 데 익숙한 팀이라면 변경 사항을 메인 브랜치에 이렇게 자주 푸시하는 데 불편을 느낄 수 있습니다. 다른 팀원이 꼼꼼히 살펴보는 것이 두렵거나 작업의 크기가 하루 안에 완료하기엔 너무 크게 느껴지는 것이 원인일 수 있습니다.

판단보다는 협업을 우선으로 하는 팀 문화의 조성이 필수적이며, 작업 관행 변경과 마찬가지로 한 팀으로 일하는 방법을 의논하는 것이 좋습니다. 작업을 더 작은 별개의 부분으로 쪼개어 팀으로 일하면 개별 팀원이 이러한 관행을 채택하는 데 도움이 될 수 있습니다.

라이브 릴리스 준비가 되지 않은 새 기능의 호스팅을 위해 긴 호흡의 브랜치가 사용된 경우 다른 옵션은 기능 플래그를 활용하는 것입니다. 이를 통해 다양한 환경에서 특정 기능의 가시성을 제어할 수 있으므로 코드 변경 사항이 품질 보증을 위해 병합되고 빌드에 포함되지만 최종 사용자에게 표시되지 않습니다.

빌드를 그린으로 유지

CI/CD 파이프라인을 통해 솔루션을 빌드하고 변경 사항을 커밋할 때마다 일련의 자동화된 테스트를 실행함으로써 개발자는 변경 사항에 대한 신속한 피드백을 받을 수 있습니다.

목표는 잘못된 기반에 빌드하지 않도록 방지하고 코드를 지속적으로 릴리스 가능한 상태로 유지하는 것입니다. 문제가 발생하는 즉시 해결하면 훨씬 더 효율적일 뿐 아니라 프로덕션에서 문제가 발생한 경우에도 수정 사항을 신속히 적용할 수 있습니다.

원인이 무엇이든 빌드 실패가 발생한 경우 다시 작동하게 수정하는 것이 팀의 우선순위여야 합니다. 변경 사항을 마지막으로 추가한 팀원을 탓하며 이슈 수정을 알아서 처리하도록 남겨두고 싶은 마음이 들 겁니다. 하지만 팀원을 탓하는 데 집중하는 경우 건설적인 팀 문화를 조성할 수 없으며 문제의 근본적 원인을 파악할 가능성도 낮습니다. 팀원 모두가 실패한 빌드 문제 해결에 책임감을 갖고 실패의 원인을 이해하려고 노력함으로써 전체 CI/CD 워크플로를 개선할 수 있습니다. 물론 압박감을 느끼며 긴장이 고조된 상황에서는 실천이 말처럼 쉽지 않을 수 있습니다. DevOps 문화를 발전시키는 것도 지속적 개선을 위한 연습입니다!

모든 일을 중단하고 실패한 빌드 수정에 전력을 기울였지만 결과적으로 구문 오류나 누락된 종속성 등의 사소한 원인으로 문제가 발생한 것을 알게 되면 답답함을 느낄 수도 있습니다. 이러한 상황을 방지하기 위해 팀원들이 변경 사항을 공유하기 앞서 먼저 빌드를 수행하고 로컬로 초기 테스트 세트를 실행하는 것이 좋습니다. 이상적으로는 모두가 CI/CD 시스템과 동일한 스크립트를 사용하여 중복 작업을 방지할 수 있어야 합니다. 또한 조직에서 CI/CD 도구 구현을 고려하세요.

단 한 번만 빌드

단계별로 새 빌드를 생성하는 것은 일반적인 실수입니다.

여러 환경에 맞춰 코드를 다시 빌드할 경우 비일관성 오류를 초래할 위험이 있으며, 따라서 이전의 모든 테스트를 통과했다고 확신하기 어렵습니다. 단계별 새 빌드 대신 동일한 빌드 아티팩트를 사용해 빌드 파이프라인의 각 단계를 진행하고 최종적으로 라이브 릴리스를 완료해야 합니다.

이를 실행하려면 시스템 제약이 없는 빌드가 필요합니다. 모든 변수와 인증 매개변수, 구성 파일 또는 스크립트가 빌드 자체에 통합되는 대신 배포 스크립트로 호출되어야 합니다. 이로써 각 환경에 테스트용으로 동일한 빌드를 배포할 수 있으며, 단계별로 해당 빌드 아티팩트에 대한 팀의 신뢰도 증가합니다.

빌드 스크립트, 구성 파일 및 배포 스크립트를 포함한 모든 것을 애플리케이션 코드와 동일한 소스 관리 시스템에 유지하는 편이 좋지만, 빌드 아티팩트 자체에도 같은 원칙이 적용되지는 않습니다. 입력의 결과물인 빌드는 소스 관리 시스템에 포함되지 않습니다. 대신에 버전별로 Nexus와 같은 중앙 아티팩트 저장소에 저장되며, 중앙 아티팩트 저장소에 저장된 빌드를 가져와서 각각의 인스턴스에 배포할 수 있습니다.

테스트 간소화

CI/CD는 주로 자동화된 테스트를 통해 소프트웨어 품질에 대한 확신을 제공하지만, 그렇다고 가능한 모든 결과에 대한 테스트를 목표로 할 필요는 없습니다.

결국 지속적 통합의 목표는 신속한 피드백을 제공하고, 사용자에게 가치 있는 제품을 기존 방식보다 더욱 빠르게 전달하는 것입니다. 즉, 테스트 커버리지와 성능 간의 균형이 중요합니다. 테스트 결과를 얻는 데 너무 오랜 시간이 소요될 경우 사람들은 프로세스를 우회할 사유와 방법을 모색하기 마련입니다.

최대한 빠른 피드백을 위해 가장 신속히 완료되는 테스트를 실행하고, 빌드에 대해 어느 정도 확신이 가는 경우에만 더 오랜 시간이 소요되는 테스트에 투자해야 합니다. 수동 품질 보증에 들어가는 시간과 해당 검사를 수행할 수 있는 팀의 의존성을 고려하면 자동화된 테스트가 모두 성공적으로 완료될 때까지 이 단계를 제한하는 것이 최선입니다.

일반적으로 자동화된 테스트의 첫 번째 계층은 광범위한 커버리지를 제공하며 최신 변경 사항에 따라 발생한 명백한 이슈를 알려주는 유닛 테스트입니다. 유닛 테스트 이후 자동화된 통합 또는 구성 요소 테스트 계층을 통해 코드의 여러 부분 간의 상호작용을 테스트할 수 있습니다.

그 외에도 GUI 테스트, 성능 및 부하 테스트 또는 보안 테스트 등의 한층 복잡한 자동화된 테스트를 실행하고 마지막으로 수동 탐색 또는 수용 테스트에 시간을 할애할 수 있습니다. 자동 테스트든 수동 테스트든 이처럼 긴 호흡의 테스트를 효율적으로 실행하려면 특정 제품과 사용자에게 가장 큰 위험 요소인 영역에 집중해야 합니다.

환경 정리

QA 스위트를 적절히 활용하려면 시간을 드려 각 배포 사이의 사전 프로덕션 환경을 정리하는 것이 좋습니다.

환경이 장기간 실행 중인 경우에는, 각 환경에 적용된 모든 구성 변경 사항과 업데이트를 추적하기가 점차 어려워집니다.

시간이 흐르며 초기 설정 및 다른 환경과의 차이가 발생하기 마련이므로, 어떤 환경에서 통과하거나 실패한 테스트가 다른 환경에서 동일한 결과를 반환하지 않을 수도 있습니다. 정적 환경을 유지하는 데 관리 비용이 수반되므로 QA 프로세스 속도 저하 및 릴리스 프로세스가 지연되는 문제가 발생할 수 있습니다.

컨테이너를 사용하여 환경을 호스팅하고 테스트를 실행할 경우, 해당 단계를 스크립트로 작성하는 코드로서 인프라 접근 방식을 통해 각각의 새로운 배포를 위한 환경을 간편하게 생성하고 해체할 수 있습니다. 매번 새로운 컨테이너를 인스턴스화하면 일관성이 보장되고 환경을 보다 쉽게 확장할 수 있으므로 필요한 경우 여러 빌드의 동시 테스트 실행이 가능합니다.

신뢰할 수 있는 프로덕션 배포 방식

어떤 사유로든 프로세스 우회를 허용하여 노력의 결실을 훼손하는 것은 원치 않으므로 안정성, 속도, 보안을 모두 갖춘 CI/CD 파이프라인을 구축하는 데 투자했다면 이는 빌드의 품질에 대한 확신을 제공합니다.

일반적으로 변경 사항의 사소함이나 긴급함을(혹은 두 가지 모두) 핑계로 릴리스 프로세스 우회를 요청하지만 그러한 요구를 받아들이면 추후 더 큰 대가를 치르게 됩니다.

자동화된 품질 보증 단계를 생략하는 경우 방지할 수 있는 문제를 초래할 위험이 있습니다. 또한 테스트 인스턴스에 배포할 빌드를 쉽게 이용할 수 없으므로 문제의 재현 및 디버깅이 훨씬 어렵습니다.

개발자는 언젠가 "딱 한 번만" 프로세스를 우회하자는 요청을 받게 될 가능성이 높습니다. 그런 경우엔 매우 시급한 문제를 해결해야 할 상황에 놓여 있을 테지만, 회고 또는 사후 분석을 활용해 이면의 동기를 이해하는 것이 좋습니다. 프로세스 속도가 너무 느린 것 같습니까? 성능 향상이나 개선이 필요할 수 있습니다. 적절한 사용 시기에 대한 오해가 있습니까? CI/CD 파이프라인의 이점을 전달하면 관련자들을 쉽게 참여시키고 다음에 있을 급박한 상황에서 이러한 종류의 요구를 피할 수 있습니다.

파이프라인 모니터링 및 평가

CI/CD 파이프라인 설정의 일환으로 문제의 신호를 최대한 빨리 경고하는 프로덕션 환경 모니터링을 구현했을 수 있습니다.

릴리스 대상인 제품과 마찬가지로 빌드 프로세스에도 피드백 루프를 활용하면 유용합니다.

CI/CD 도구를 통해 수집한 메트릭을 분석함으로써 잠재적 문제와 개선 영역을 파악할 수 있습니다.

  • 주, 일 또는 시간 단위로 트리거되는 빌드 수를 비교하여 파이프라인 인프라가 사용되는 방식, 확장 또는 축소 필요성, 최대 부하 발생 가능성이 높은 시점 등에 대한 유용한 인사이트를 도출할 수 있습니다.
  • 시간 경과에 따른 배포 속도를 추적하고 더 오랜 시간이 소요되는 경향을 모니터링하면 성능 최적화에 투자할 시점을 알 수 있습니다.
  • 자동화된 테스트로 얻은 통계 자료는 병렬화를 활용하면 좋은 영역을 결정하는 데 도움이 됩니다.
  • QA 결과 검토를 통해 자주 간과하는 부분을 발견하여 품질 보증 커버리지를 간소화할 수 있는 영역을 파악할 수 있습니다.

팀으로 협업하기

효과적인 CI/CD 워크플로 구축에 있어 팀과 조직 문화도 사용하는 프로세스 및 도구만큼 중요합니다.

지속적 통합, 전달 및 배포DevOps 모범 방식입니다. 이를 실천하려면 개발자, QA 엔지니어 및 운영 팀 간의 통상적인 사일로를 제거하고 여러 분야의 협업을 촉진해야 합니다.

사일로를 제거하면 엔드투엔드 워크플로의 가시성이 개선되며 팀은 협업의 기회와 다양한 전문 분야의 이점을 얻을 수 있습니다. 한 사람이 홀로 파이프라인 유지를 담당해서는 안 됩니다. CI/CD 플랫폼을 구현하면 운영 방식을 개선하는 데 도움이 될 수도 있습니다.

소프트웨어 제공과 관련한 공동의 책임감을 조성함으로써 모든 팀원이 빌드 수정에 참여하거나, 환경 컨테이너화에 시간을 할애하거나 예상만큼 자주 수행되지 않는 수동 작업을 자동화하는 등 팀에 기여하도록 장려할 수 있습니다.

팀원들이 아이디어를 실험하고 공유할 수 있는 신뢰의 문화를 촉진하면 사람뿐 아니라 조직과 제공하는 소프트웨어에도 유익한 결과를 낳습니다. 문제가 발생하면 팀원 한 명의 책임 소재를 파악하는 데 집중하는 대신 실패로부터의 배움을 목표로 근본적 원인과 앞으로 방지하기 위한 방법을 이해해야 합니다.

이 기회를 활용하여 CI/CD 관행을 더욱 강력하고 효과적으로 개선하세요. 팀원들이 질책을 두려워하지 않고 실험하고 혁신할 수 있도록 허용할 때 지속적 개선의 선순환을 창출할 수 있습니다.