Jenkins Pipeline 마스터하기: 선언형(Declarative) vs 스크립트(Scripted) 전격 비교
1. Pipeline as Code: Jenkinsfile의 등장
과거의 Jenkins는 모든 빌드, 테스트, 배포 작업을 웹 UI를 통해 마우스 클릭으로 설정했습니다. 이는 직관적이지만, 파이프라인이 복잡해질수록 관리가 어렵고, 변경 이력을 추적할 수 없으며, 재사용이 불가능하다는 치명적인 단점이 있었습니다. 이러한 문제를 해결하기 위해 등장한 것이 바로 'Pipeline as Code' 개념이며, 이를 Jenkins에서 구현한 것이 Jenkinsfile입니다.
Jenkinsfile은 CI/CD 파이프라인의 전체 흐름을 코드로 정의한 텍스트 파일입니다. 이 파일을 소스 코드와 함께 버전 관리 시스템(Git 등)에서 관리함으로써, 파이프라인의 변경 이력을 투명하게 추적하고, 코드 리뷰를 통해 안정성을 높이며, 동일한 파이프라인을 여러 프로젝트에서 재사용할 수 있게 되었습니다. Jenkinsfile을 작성하는 문법에는 크게 두 가지 방식, 즉 스크립트(Scripted) 파이프라인과 선언형(Declarative) 파이프라인이 존재합니다.
2. 전통의 강자, 최고의 자유도: 스크립트(Scripted) 파이프라인
스크립트 파이프라인은 Jenkins Pipeline의 초기부터 존재했던 전통적인 방식입니다. Groovy 프로그래밍 언어를 기반으로 하며, 거의 완전한 Groovy 문법을 지원합니다. 이는 개발자가 조건문(if/else), 반복문(for), 예외 처리(try/catch) 등 일반적인 프로그래밍 로직을 사용하여 매우 복잡하고 동적인 파이프라인을 자유롭게 구현할 수 있다는 것을 의미합니다.
스크립트 파이프라인 예제
node('master') {
stage('Build') {
echo 'Building the application...'
sh 'mvn clean install'
}
stage('Test') {
echo 'Testing the application...'
sh 'mvn test'
}
stage('Deploy') {
echo 'Deploying the application...'
sh './deploy.sh'
}
}
3. 쉽고 구조적인 현대적 방식: 선언형(Declarative) 파이프라인
선언형 파이프라인은 스크립트 파이프라인의 복잡성을 개선하기 위해 나중에 도입된, 더 구조화되고 배우기 쉬운 문법입니다. "어떻게(How)"를 기술하는 스크립트 방식과 달리, "무엇을(What)" 할지를 미리 정의된 구조에 따라 선언하는 방식입니다. pipeline, agent, stages, stage, steps 와 같이 명확하게 정해진 블록 구조를 따르기 때문에 코드를 읽고 이해하기가 훨씬 쉽습니다.
또한, 파이프라인을 실행하기 전에 Jenkins가 코드의 구조적인 오류를 미리 검증해주므로 안정성이 높고, Blue Ocean과 같은 시각화 도구와도 더 잘 통합됩니다.
선언형 파이프라인 예제
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building the application...'
sh 'mvn clean install'
}
}
stage('Test') {
steps {
echo 'Testing the application...'
sh 'mvn test'
}
}
stage('Deploy') {
steps {
echo 'Deploying the application...'
sh './deploy.sh'
}
}
}
}
4. 한눈에 비교: 스크립트 vs. 선언형
| 구분 | 스크립트 (Scripted) 파이프라인 | 선언형 (Declarative) 파이프라인 |
|---|---|---|
| 문법 스타일 | 명령형 (Imperative): Groovy 코드로 절차를 직접 작성 | 선언형 (Declarative): 미리 정의된 구조에 맞춰 상태를 선언 |
| 학습 곡선 | 높음 (Groovy 언어에 대한 이해 필요) | 낮음 (단순하고 명확한 구조) |
| 유연성 | 매우 높음 (거의 모든 프로그래밍 로직 구현 가능) | 상대적으로 낮음 (정해진 구조를 따라야 함) |
| 가독성 | 복잡해질수록 낮아짐 | 높음 (구조가 명확하여 이해하기 쉬움) |
| 구문 검증 | 실행 시점에 오류 발견 | 실행 전 구문 검증 지원으로 안정성 높음 |
| 추천 사용 사례 | 매우 복잡하고 동적인 로직이 필요한 파이프라인, 기존의 레거시 파이프라인. | 대부분의 새로운 파이프라인. 표준적이고 예측 가능한 CI/CD 구성. |
어떤 파이프라인 문법을 선택할지는 프로젝트의 요구사항에 따라 달라집니다. 하지만 Jenkins 커뮤니티의 공식적인 권장 사항은 대부분의 경우 더 단순하고 구조적인 선언형 파이프라인으로 시작하는 것입니다. 선언형 파이프라인은 CI/CD의 모범 사례를 자연스럽게 따르도록 유도하며, 유지보수가 훨씬 용이합니다. 만약 선언형의 구조로는 도저히 구현할 수 없는 매우 특수한 로직이 필요할 때만, script { ... } 블록을 사용하여 선언형 파이프라인 내부에 스크립트 코드를 부분적으로 포함시키는 하이브리드 방식을 고려하는 것이 현명한 접근법입니다.
댓글
댓글 쓰기