[DevOps] Jenkins Job을 통한 자동화

[DevOps] Jenkins Job을 통한 자동화

안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 간단하게 젠킨스 자동화 구성을 한가지 소개해보려고 합니다.
필자가 속한 프로젝트에서는 운영팀 이다보니, 반복적이고 간단한 작업들이 굉장히 많이 이뤄지고 있습니다. 그러다보니, 사람이 하나하나 꼼꼼히 한다고 하더라도 실수가 발생하는 소지가 많이 있는데요. 필자는 이런 상황에 대해서 어떻게 하면 자동화를 할 수 있을까에 대한 고민을 많이 했던 것 같습니다.

필자의 프로젝트 스펙을 간단하게 소개하면 다음과 같습니다.

  • Git lab 사용

  • Jenkins 사용

  • AEM solution 사용
    • 다소 생소 한 개념이긴 할 수 있습니다. 공식 URL은 다음과 같고, 간단히 말해 CMS(Content Management System)입니다.
  • AWS 사용

AEM 공식 URL

배포도 기존의 Spring Framework와는 다르게, war 파일이 아닌, zip 파일로 배포를 진행합니다.

1. 반복적인 작업 ..귀찮음.

반복적인 작업이 그럼 도대체 어떤 내용이 있을까요?

특명! 정기배포된 파일을 다른 서버에도 배포를 해주어 형상을 맞춰라. 사실, 정기 배포시에 해당 서버까지 배포를 해되 무방합니다. 하지만, 배포시에 문제가 발생하면 다른태그로 다시 배포를 해야되는 등 여러가지 변수가 있을 수 있습니다.

결국엔, 정기 배포시에 완료된 태그들에 한하여 추가 서버에 형상을 맞춰두는 작업을 하는 것인데요.

다음 그림에서 보이듯이 녹색 화살표에 따라 2가지 스텝으로 구성이 되어있습니다.

  • 1 Step : 파일 이동 (빌드 된 파일을 이동합니다. )
  • 2 Step : 여러개의 해당 파일을 반복 배포 합니다.

그림에서 위에 그려진 부분은 실제 운영에 서비스 되는 내용입니다. 결국 Jenkins에서 빌드를 수행하고, 배포를 하는 작업인데요.

배포가 완료가되면, 1,2 Step의 순서대로 빌드 된 파일을 옮기고, 추가 서버에 배포를 하는 내용을 그동안 손수 작업을 해왔습니다.

그러다가, 중간에 젠킨스 with Docker를 배치하여 1,2 Step을 자동화 하기로 했습니다.

2. Job을 구성해 보자.

젠킨스는 정말로 많은 기능들을 갖고 있습니다. 여러가지 플러그인들을 잘만 활용하면 특별한 기능을 만들지 않고도 손쉽게 자동화를 구성할 수 있습니다.

필자가 사용한 플러그인들의 목록입니다.

  • Ocean Blue -> Build Pipeline
  • Parameterized Trigger Plugin
  • Extensible chice paramter
  • Multi-line String Parameter

위의 기능들이 핵심이고, 이제 job구성을 어떻게 하는지 정리해보겠습니다.

  1. Blue Ocean

먼저 소개 해드릴 내용은 Blue Ocean 입니다. 이 플러그인을 통해서 빌드 파이프라인을 구축할 수 있습니다. 필자 같은 경우는 1개의 TAG를 2대의 서버로 배포를 해야되기 떄문에 이부분이 병렬로 진행되어야 했습니다. 그렇기 때문에 파이프라인으로 구축을 했습니다.

def ZIP_FILE

pipeline {
    agent any
    parameters {

        text(name: 'FILE', defaultValue: '', description: '.zip file name')

    }
    stages {
        stage('Parallel Stage') {    //스테이지 : 병렬로 수행시킬 내용을 스테이지로 구성 
            parallel {
                stage('PREVIEW_A01') { //스테이지 1 : 프리뷰 서버에 배포 내용 
                    steps {
                        script{
                              //API를 통한 BUILD JOB 수행 ( 파라미터 : 타겟서버, 빌드 타이틀, 서버 패스워드, 배포태그 )

                              def myjob=build job: 'Deploy_Server_Component', parameters: [[$class: 'com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterValue', name: 'SERVER', value: "http://{IP변경}:{PORT 변경}"], string(name: 'TITLE', value: 'Deploy_AEM_Server_Component'), password(description: '', name: 'PASSWORD', value: '{password 변경}'), text(name: 'FILE', value: "${params.FILE}")]
                        }
                    }
                }
                stage('QA_A01') {  //스테이지 2 : 큐에이 서버에 배포 내용
                    steps {
                        script{
                              def myjob=build job: 'Deploy_Server_Component', parameters: [[$class: 'com.cwctravel.hudson.plugins.extended_choice_parameter.ExtendedChoiceParameterValue', name: 'SERVER', value: "http://{IP변경}:{PORT 변경}"], string(name: 'TITLE', value: 'Deploy_AEM_Server_Component'), password(description: '', name: 'PASSWORD', value: '{password 변경}'), text(name: 'FILE', value: "${params.FILE}")]

                        }

                    }
                }
            }
        }
    }
}

주석에 내용이 표기 되어있습니다. 단순히 다른 JOB(Deploy_Server_Component) 를 파라미터까지 같이 던져서 호출하는 것이고, parallel 로 수행이 가능하도록 구성했습니다.

  • Deploy Pipeline -> Deploy Job 을 병렬로 호출하여 파이프라인을 구축했습니다.

파이프라인까지는 구성을 했는데, 여기까지 한것은 1개의 태그에 대해 n개의 job호출 입니다. 그런데, 반복 수행하는 작업은 n개의 태그들이 입력이 됩니다. 따라서, 지금까지 구성한것 상위로 JOB을 한개 더 구성하여 for문으로 호출하도록 구성했습니다.

  1. 멀티라인 스트링 파라미터

멀티라인으로 파라미터를 쓸 수 있도록 플러그인을 구섷하였습니다.

#!/bin/bash

file=$FILE
filearray=$(echo $file | tr "," "\n")
for eachfile in $filearray
do
    curl -X POST -u admin:admin http://{젠킨스 ip변경 }:{젠킨스 port 변경 }/job/Deploy_AEM_Server_PIPE/buildWithParameters?FILE=$eachfile
done

상위로 pipe 라인 job을 수행하되, 멀티라인으로 받은 파라미터에 대해서 for문 형태로 돌면서 수행하도록 했습니다.

  1. 파라미터라이즈드 플러그인 & 익스텐시블 초이스 파라미터

그럼 지금까지 한 작업은 위의 그림에서 Step 2 에 해당하는 작업을 진행했습니다. Step 1을 수행하고나서, Step 2가 진행될 수 있도록 2가지 job을 연결해보도록 하겠습니다.

날짜를 선택하여 운영 빌드 job 수행시 생성되는 날짜폴더에 접근을 하여 안에 있는 태그들을 가져오고 싶었습니다. 그래서 날짜를 익스텐시블 초이스 파라미터로 가져오도록 설정해봤습니다.

그르비 스크립트를 선택하여 안에 코드를 넣어두면, 스크립트 수행후 출력되는 내용에 대해서 초이스 파라미터를 구성해줍니다.

import java.text.SimpleDateFormat

SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMdd")
Date dt = new Date();
Calendar c = Calendar.getInstance(); 
c.setTime(dt); 
c.add(Calendar.DATE, -7);

def x = []
//x.add(''DEFAULT")

for (i = 0; i <8; i++) {
dt = c.getTime() +i
x.add(sdf.format(dt))
}

x.each { println it }

코드 내용은 위와 같고, 단순하게 yyyMMdd 꼴의 형태로 파라미터를 선택할 수 있도록 해줍니다.

그런 뒤, 빌드 후 조치Step 1Step 2를 연결합니다. 연결시 트리거링을 파라미터로 전달할 수 있도록 Predefined parameter로 전달을 하면됩니다. 위에서는 배포 태그에 대해서 전달을 하도록 셋팅해두었습니다.

3. Job을 수행해 보자.

최종적으로 Step 1 에 해당하는 Main job을 클릭하면 위와 같은 화면이 노출됩니다.

  • 실제 운영에 나간 날짜를 선택합니다. (운영 배포된 내용을 추가 서버에 배포하므로..)
  • 실제 운영 서버에 나간 태그들을 입려합니다.(운영에 이미 나갔기에 태그명을 알고 있음)

그럼 순차적으로 Step1 -> Step2를 수행하고, 결과만 기다리면 됩니다.

뒤에 결과는 Slack으로 연결을 해둘 수도 있고, SNS로 메일링을 수행해도 됩니다.

기존에 Manually로 수행하기에는 단순하지만, 굉장히 짜증나면서도 실수를 유발할 수 있었다면, 지금은 간단하게 날짜와 태그명만 입력해주면, 일련의 배포 파이프라인으로 자동화 되어 수행됩니다.

4. 마치며...

자동화는 정말 IT에선 없어서는 안될 필수 요소라고 생각합니다. 필자는 DevOps에 굉장한 매력을 느끼고 IT 업무에 있어서, 특히 운영프로젝트의 성격상 반드시 베어 있어야될 문화라고 생각합니다. 단순하고 반복적인 작업들이 없어서는 안될 업무들이지만, 이러한 것들이 자동화되고, 정확도를 높이고, 장애 유발 요소를 제거 해 나간다면 그 시간에 다른 유익한 업무들을 할 수 있을 것이라고 봅니다.

비록 위의 내용은 다소 복잡하고 굳이 저렇게 까지 구성을 해야되나 싶을 정도로 오바스럽게 만든 경향이 있습니다. 하지만, 제가 하는 업무들을 자동화 시키고 신속하게 처리해낸다면 주변 동료들에게도 신뢰가 생기고 더욱더 유익한 업무를 할 수 있지 않을까 라는 생각이 듭니다.

앞으로 지속적으로 Jenkins의 다른 플러그인들을 활용하여 자동화업무의 내용들을 포스팅하겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다