[Hands On] Elastic Beanstalk와 Jenkins를 이용한 CI/CD 환경 구축

  • Post category:AWS
  • Post author:

이번 포스팅에서는 이전 포스팅 ‘[Hands On] Elastic Beanstalk를 사용한 웹 애플리케이션 배포 Python(Django) – awsebcli 활용’에 이어 Jenkins, GitLab, Elastic Beanstalk를 활용하여 CI/CD 환경을 구축해 보도록 하겠습니다.

CI/CD는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 보다 짧은 주기로 고객에게 제공하는 방법입니다. CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포입니다. CI/CD는 새로운 코드 통합으로 인해 개발 및 운영팀에 발생하는 문제를 해결하기 위한 솔루션입니다.

Jenkins는 Java로 작성된 CI 서버의 오픈 소스 구현으로, 프로젝트의 빌드 주기를 자동화하는 자체 호스팅 옵션으로 사용할 수 있습니다. 모든 프로그래밍 언어 및 Windows, Linux 및 macOS를 포함한 여러 플랫폼에서 작동합니다.

Jenkins의 주요 이점 중 하나는 많은 커뮤니티 지원을 제공하는 잘 알려진 도구이며 Slack, GitHub, Docker, Build Pipeline 등을 포함하여 많은 플러그인이 있으며 손쉽게 연동이 가능합니다.

1. 개발환경

  • Amazon Linux 2
  • Python 3.7
  • Django 2.2
  • mysql

[Hands on 동작과정]

  1. 사용자가 코드 수정 후 GitLab에 Push 합니다.
  2. Webhook Trigger에 의해 젠킨스 파이프라인이 실행됩니다.
  3. 새로운 Zip 파일을 만들고 S3 버킷에 업로드합니다.
  4. Elastic Beanstalk에 Deploy 요청을 보내고, Beanstalk는 S3 버킷에서 배포할 Zip 파일을 가져옵니다.
  5. Elastic Beanstalk에서 새로운 Zip 파일을 배포합니다.

2. Jenkins

1. 플러그인 설치

Jenkins 서버에서 GitLab 플러그인을 설치합니다. (반드시 Jenkins 서버를 설치한 EC2 서버에서 git을 설치하여야 에러가 발생하지 않습니다.)

2. 새로운 item 구성

새로운 item 구성을 클릭하고 적절한 이름과 Pipeline을 선택 후 만들어줍니다.

3. webhook 설정

[webhook 이란?]

  • 웹훅은 새 이벤트가 서버에서 발생한 경우 서버 측 응용 프로그램이 클라이언트 측 응용 프로그램에 알릴 수 있는 메커니즘을 제공합니다.
  • “역방향 API”라고도 합니다. 일반적인 API는 클라이언트가 서버를 호출합니다. 반면 웹훅의 경우 구현한 웹 애플리케이션은 특정 작업이 수행될 때 URL에 대해 POST 방식으로 요청을 생성합니다. 이때 url은 웹 애플리케이션을 사용하는 유저가 자신의 url을 지정할 수 있습니다.
  • gitlab에 push 이벤트 발생 → 등록한 웹훅 동작 → 젠킨스 파이프라인 실행

Build Triggers 탭의 ‘Build when a change is pushed to GitLab’ 선택 후 마지막에 있는 url 을 복사합니다.

우측하단의 고급탭을 눌러 가장 아래쪽의 Generate 버튼을 눌러 Secret token도 복사합니다.

GitLab에 접속후 해당 repository의 settings → webhooks

복사 한 url 값과 secret token 값을 입력 후 push events에 체크한 후 Add Webhook 버튼을 눌러 웹훅을 추가합니다.

추가 후 아래쪽 테스트 버튼을 통해 200코드가 반환되면 정상적으로 연결된 것을 알 수 있습니다.

4. PipeLine 설정

  • Definition : Pipeline script from SCM
  • SCM : GIt
  • Repositories : 자신의 gitlab repositoriy 주소
  • Credentials : Add 버튼을 클릭해 자신의 gitlab 아이디와 비밀번호로 Credential을 등록.
  • Script Path : Jenkinsfile (pipeline 코드가 작성된 Jenkinsfile의 위치를 적습니다. hands on 에서는 가장 최상단에 위치시켰습니다.)

5. PipeLine 코드

프로젝트 폴더 내에 최상단 위치에 Jenkinsfile(파일명이 반드시 ‘Jenkinsfile’ 이어야 합니다.) 생성 후 아래의 코드를 작성합니다. 참고하여 코드를 작성합니다.

파이프 라인 코드 동작 과정

  • 기존에 있던 젠킨스 서버의 zip 파일 삭제
  • 수정된 파일 압축
  • S3 버킷에 zip 파일 업로드(파일 이름 : beanstalk_v${BUILD_NUMBER}.zip)
  • 새로운 버전의 애플리케이션 생성
  • 업로드된 zip 파일 배포
pipeline {
    agent any
    stages {
        stage('delete origin zip file'){
            steps{
                script{
                    try{
                        sh 'rm -rf *.zip'
                    } catch(error){
                        print(error)
                        env.cloneResult = false
                        currentBuild.result = 'FAILURE'
                    }
                }
            }
        }
        stage('make zip file'){
            steps{
                script{
                    try{
                        sh 'zip -r beanstalk_v${BUILD_NUMBER}.zip .'
                    } catch(error){
                        print(error)
                        env.cloneResult = false
                        currentBuild.result = 'FAILURE'
                    }         
                }
            }
        }
        stage('upload to S3'){
            steps{
                script{
                    try{
                        sh 'aws s3 cp beanstalk_v${BUILD_NUMBER}.zip \
                        s3://{S3 버킷 이름}/django-tutorial/beanstalk_v${BUILD_NUMBER}.zip \
                        --region ap-northeast-1'   
                    } catch(error){
                        print(error)
                        env.cloneResult = false
                        currentBuild.result = 'FAILURE'
                    }             
                }
            }
        }
        stage('deploy'){
            steps{
                script{
                    try{
                        sh 'aws elasticbeanstalk create-application-version --region ap-northeast-1 \
                        --application-name {애플리케이션 이름} \
                        --version-label beanstalk_v${BUILD_NUMBER} \
                        --source-bundle S3Bucket="{S3 버킷 이름}",S3Key="{애플리케이션 이름}/beanstalk_v${BUILD_NUMBER}.zip"'
                        sh 'aws elasticbeanstalk update-environment --region ap-northeast-1 \
                        --environment-name django-env \
                        --version-label beanstalk_v${BUILD_NUMBER}'
                    } catch(error){
                        print(error)
                        env.cloneResult = false
                        currentBuild.result = 'FAILURE'
                    }                
                }
            }
        }        
    }
}
Dockerfile

참고 자료

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-services-s3-commands.html

https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/environments-create-awscli.html

https://docs.aws.amazon.com/cli/latest/reference/elasticbeanstalk/create-application.html

6. 빌드 확인

Build Now 버튼을 눌러 빌드를 실행합니다.

7. 수정된 코드를 GitLab에 push 후 자동으로 빌드와 배포가 되는지 확인

  • 코드 수정

msg의 값을 ‘hello Jenkins’로 수정한 후 정상적으로 배포되는지 확인해 보도록 하겠습니다.

  • 로컬에서 코드 수정 후 git push
  • 젠킨스 빌드 확인
  • beanstalk 에서 배포 확인
  • 웹 페이지 접속

정상적으로 수정한 코드가 배포된 것을 확인할 수 있습니다.

  • 애플리케이션 버전 확인

이 곳에서 언제든지 애플리케이션의 버전을 변경할 수 있습니다.

  • S3 버킷 확인

S3 버킷 내 해당 애플리케이션 폴더 안에서 모든 버전의 배포 파일을 확인할 수 있습니다.

정리

이번 hands on 과정에서 Jenkins, GitLab, Elastic Beanstalk를 통해 CI/CD 환경을 구축해 보았습니다.

동작 과정에 대해 간략하게 요약해 보겠습니다.

  1. 애플리케이션 코드 수정 후 GitLab Push
  2. Jenkins 파이프라인 실행
  3. 배포 파일 S3 업로드 및 Beanstalk 배포

AWS Elastic Beanstalk는 웹 애플리케이션 및 서비스를 간편하게 배포하고 조정할 수 있는 서비스입니다.

코드를 업로드하기만 하면 Elastic Beanstalk가 용량 프로비저닝, 로드 밸런싱, 오토 스케일링부터 시작하여 애플리케이션 상태 모니터링에 이르기까지 배포를 자동으로 처리합니다.

GitLab, Jenkins, 그리고 간편하게 배포할 수 있는 Elastic Beanstalk 를 통해 손쉽게 CI/CD 환경을 구축할 수 있습니다.

이상으로 Hands On을 마치겠습니다.

감사합니다.

문의 사항이 있으시면, NDS Sales팀으로 연락 주시길 바랍니다. 
cloud.sales@nongshim.co.kr

SA 설재홍