Declarative Pipeline은 Jenkins Pipeline의 최신 기능으로써 Script 구조가 잘 정의되어 있다.
따라서 Scripted보다 가독성이 좋으며 개발자가 사용할 수 있는 구문 기능도 훨씬 다양하다.
단지 Script 구조가 너무 잘 정의되어 있어 Scripted Pipeline보다는 제한적인 기능을 가진다.
Script 구조가 잘 정의되어 있어 제한적인 기능을 가진다는 말이 이해가 안 된다면 Windows 같은 경우 사용이 쉽지만 서버 설정 폭이 좁으며 AWS EC2나 VM Container의 Linux 서버는 사용은 어렵지만 수행할 수 있는 서버 설정 폭이 넓다는 것을 생각하면 될 것이다.
즉, 어려운 설정 과정을 미리 처리해 두었기 때문에 사용은 쉽지만 이미 처리된 설정에 대해 수정하기엔 제한사항이 있다는 의미이다.
Groovy DSL을 기반으로 하는 Jenkins Pipeline 정통적인 방법이다.
Jenkins Pipeline에서 처음 도입한 방식이 Scripted Pipeline으로써 변수 선언이나 설정에 제한이 거의 없어 자유롭고 다양한 작업을 할 수는 있으나 사용 방법이 어렵다는 단점이 존재한다.
Declarative Pipeline은 Script의 Top Level을 "pipeline { }"로 지정하고 Scripted Pipeline은 Script의 Top Level을 "node { }"로 지정한다. 그렇다면 이 둘(pipeline과 node)에는 어떤 차이가 있을까?
일단 매우 간단하게 설명하자면 pipeline이 node를 포함하는 더 큰 범주라고 이해하면 편하다.
"pipeline"은 우리가 지금까지 배웠던 파이프라인 개념으로 전체적인 Build 프로세스를 정의하고 이 과정에서 수행되어야 하는 빌드/배포/테스트에 대한 Stage를 명시하도록 제공한다.
"node"는 Jenkins 환경의 일부분으로써 Pipeline 로직을 실행할 수 있는 시스템이다. 즉, Pipeline에서 수행되어야 하는 전체 로직 중 일부분을 실행할 수 있는 주체가 node라는 의미이다.
즉, Pipeline은 CI/CD 흐름 전체 과정을 1개 문서로 모두 표현한 Script이며 node는 Pipeline의 CI/CD 중 필요한 절차를 수행할 수 있게 도와주는 시스템이라고 할 수 있다.
이렇다 보니 Pipeline은 무조건 1개밖에 존재할 수 없지만 Node는 Pipeline의 일부 절차를 수행할 수 있게 도와주는 시스템이므로 여러 개 존재할 수 있다는 특징을 가진다.
그렇다면 왜 node가 Scripted Pipeline이고 pipeline이 Declarative Pipeline에 활용되는지를 유추할 수 있을 것이다.
Declarative란 프로그램이 어떻게 수행되야할지는 관심이 없으며 단지 프로그램이 무엇을 수행해야 할지 관심이 있다. 따라서 Pipeline이라는 1개의 전체적인 CI/CD 절차에 어떤 과정이 포함되어 있는지가 중요해지고 이 때문에 "pipeline { }"를 사용하는 것이다.
반대로 Scripted는 "Script" 중심이기 때문에 어떻게 프로그램을 수행해야 할지에 조금 더 관심이 있다. 따라서 실제로 Pipeline 절차를 실행하는 시스템인 "node { }"를 사용하게 되는 것이다.
예를 들어 Pipeline에 Itme 1, 2, 3이 있고 Item 2에서 에러가 발생할 경우 Declarative는 Pipeline 시작 전 유효성 검사를 통해 Item 2에서 오류가 발생할 것이라는 것을 인지하고 Build를 수행하지 않는다.(실패시킨다) Scripted는 Item 1을 모두 실행시킨 상태에서 Item 2를 실행하다 에러가 발생해 실행이 멈추며 이때 이미 실행된 Item 1은 취소되지 않는다.
Declarative 방식은 when을 사용할 수 있으나 Scripted는 when 구문을 사용할 수 없다.
그렇다면 when 구문이 무엇인지에 대해 알아보자.
stage('Example Build') {
if(branch=='operation'){
echo 'Productin If'
}
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'operation'
}
steps {
echo 'Deploying'
}
}
branch = 'proudction' 상황이라고 가정하자.
"Example Build" Stage에서는 if문에 False 값이 적용되므로 "Production If"라는 문구가 출력되지 않을 것이다.
하지만 "Hello World"라는 다음 Step의 문구는 출력될 것이다.
"Example Deploy" Stage에서는 when문을 활용했다.
만약 when 안에 있는 구문이 False라면 해당 when을 포함하고 있는 Stage 전체가 실행되지 않는다.
즉, when 뒤에 있는 Step인 "Deploying"이라는 문구를 출력하는 명령도 실행되지 않는 것이다.
둘 모두 각각의 장점이 존재하기 때문에 어떤 용도로 활용할지에 따라 사용해야 할 문법이 달라질 것이다.
만약 단순하며 지속적인 배포를 진행하고 싶다면 관리가 쉬운 Declarative Pipeline이 이상적일 것이며 CI/CD 과정에 복잡한 요구사항이 존재할 경우에는 구조 및 구문에 제한이 적은 Scripted Pipeline이 이상적일 것이다.
우리는 복잡한 요구사항을 통해 세부 설정을 하고 싶다기 보다는 관리하기 쉬운 CI/CD 과정을 구현하고 싶은 목적이기 때문에 Declarative Pipeline을 활용하도록 하자.