Jenkins 설정

이번 장은 앞서 다뤘던 내용을 바탕으로 Jenkins 서버에서 CodeCommit 과 ECR을 연동하고, git push 부터 Docker Image 빌드를 자동화 하는 

내용을 다뤄보겠습니다.

 

얼마 전 Python flask 프레임워크를 이용해 월간보고서를 자동화 하는 백엔드 서버를 생성했는데요, 해당 서비스에 CI/CD를

구축해서 배포 자동화를 진행 해 보도록 하겠습니다.

 

 

Pipeline 생성

 

Jenkins 대시보드에서 새로운 Items 을 눌러 Pipeline 잡을 생성합니다.

 

Enter an item name 
» Required field 
Freestyle project 
Jenkins@l PI-SPLICE Jenkinse Al-g-g + 
Pipeline 
Orchestrates long-running activities that can span multiple build agents. Suitable for building pipelines (formerly known as workflows) and/or organizing complex activities that do not easily fit in free-style job type.


 

매개변수 설정

 

매개변수를 설정하기 앞서 [대시보드 - Jenkins 관리 -  Manage Credentials] 경로에서 아래와 같이 credential를 생성합니다.

 

Stores scoped to Jenkins 
Store I 
Jenkins 
Domains

 

해당 부분은 git credentials를 설정하는 부분으로 앞장에서 다뤘던 codecommit의 자격증명을 Username Password로 설정합니다.

Kind 
Back to credential domains 
Username with password 
Add Credentials 
Scope 
Global (Jenkins, nodes, items, all child items, etc) 
Username 
sanghyeon.park-a 
Treat username as secret 
Password 
Description

 

이제 다시 돌아가서 앞서 생성한 Pipeline의 매개변수를 설정합니다.

 

a 01 
Credentials Parameter 
Name 
Credential type 
Username with password 
Required


 

저희가 설정할 매개변수는 총 5개이며, type과 내용은 아래와 같습니다.

각 설정에 맞게 매개변수를 채워 넣어주시면 됩니다.

 

No.

매개변수 명

Credentials type

사용 용도

1.

GIT_CREDENTIALS_ID

Username with password

Codecommit 자격 증명

2.

GIT_URL

String

Codecommit URL

3.

ECR_URI

String

ECR URI 초기 연결

4.

ECR_BASE_URI

String

Docker build 초기 이미지가 저장된 레지스트리 URI

5.

ECR_TASK_URI

String

Build 된 이미지가 저장될 레지스트리 URI


 

Script 설정

 

Jenkins Pipeline Script 형식으로 구성이 가능합니다.

Stage 단위로 실행 단위를 나눌 수 있어 관리하기 편합니다.

 

Pipeline 
Definition 
Pipeline script 
Script 
1 • pipeline { 
5. 
8. 
branch:

 

pipeline {

    agent any

 

    stages {

        stage('Git Clone') {

            steps {

                script {

                    try{

                        git url: "https://$GIT_URL", branch: "master", credentialsId: "$GIT_CREDENTIALS_ID"

                        env.cloneResult=true

                    }catch(error){

                        print(error)

                        env.cloneResult=false

                         currentBuild.result='FAILURE'

                    }

                }

                

            }

        }

        stage('Docker Build'){

            when{

                expression {

                    return env.cloneResult ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/

                }

            }

            steps {

                script{

                    try{

                        sh"""

                        #!/bin/bash

                         cat>Dockerfile<

# build stage

FROM ${ECR_BASE_URI}:init as build-stage

COPY . /app

WORKDIR /app

RUN pip install -r requirements.txt

EXPOSE 8000

CMD ["gunicorn",   "--bind", "0.0.0.0:8000",  "flasktest:app", "-w", "2", "--timeout=300", "-k", "gevent"]

EOF"""

                        sh"""

                        aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${ECR_URI}

                        docker build -t ${env.JOB_NAME.toLowerCase()} .

                        docker tag ${env.JOB_NAME.toLowerCase()}:latest ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

                        docker push ${ECR_TASK_URI}:ver${env.BUILD_NUMBER}

                        """

                         env.dockerBuildResult=true

                    }catch(error){

                        print(error)

                         env.dockerBuildResult=false

                         currentBuild.result='FAILURE'

                    }

                }

            }

        }

        

    }

}

 

Codecommit 호출

 

기본적으로 Jenkins GitHub와 같은 git 레포지터리와 연동을 지원한다하지만 Codecommit과의 연동은 아직까지 지원하지 않기 때문에,

AWS Lambda를 설정하여 main branch에서 push가 이루어질 때 Jenkins 파이프라인을 호출하는 함수를 생성합니다.

 

Lambda Jenkins 서버의 API를 이용하여 호출 하는 형식이기에, Private 서브넷에 위치한 Jenkins 서버와 통신하기 위해 Lambda도 같은 

VPC 내의 서브넷에 위치해야 합니다.

 

Lambda VPC 내부에 위치하기 위해서는 ENI가 필요하다. ENI를 생성할 수 있는 권한 (EC2FullAccess)을 역할에 추가 해 줍니다.

물론, EC2FullAccess가 아닌 최소 권한만 주는것이 바람직합니다.