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 { ... } 블록을 사용하여 선언형 파이프라인 내부에 스크립트 코드를 부분적으로 포함시키는 하이브리드 방식을 고려하는 것이 현명한 접근법입니다.

댓글