75DAYS) [Cloud] 배포 자동화 - Automated Deployment, AWS Pipeline을 통한 배포 자동화

nacSeo (낙서)·2023년 2월 3일
0

◉ 학습목표

1. 배포 자동화의 정의와 이점, 배포 파이프라인에 대해 이해할 수 있다.
2. AWS 개발자 도구를 이용하여 파이프라인을 구축할 수 있다.
  1. Automated Deployment

⦿ 학습내용

☞ 배포 자동화

✔︎ 한번의 클릭 또는 명령어 입력을 통해 전체 배포 과정을 자동으로 진행하는 것

☞ 배포 자동화 파이프라인


✔︎ 파이프라인(Pipeline) : 소스 코드의 관리부터 실제 서비스로의 배포 과정을 연결하는 구조
✔︎ 파이프라인 세 가지 단계

  • Source 단계
    • 원격 저장소에 관리되고 있는 소스 코드에 변경 사항이 일어날 경우, 이를 감지하고 다음 단계로 전달하는 작업 수행
  • Build 단계
    • Source 단계에서 전달받은 코드를 컴파일, 빌드, 테스트하여 가공
    • Build 단계를 거쳐 생성된 결과물을 다음 단계로 전달하는 작업 수행
  • Deploy 단계
    • Build 단계로부터 전달받은 결과물을 실제 서비스에 반영하는 작업 수행

🚨 주의 ❗️
: 파이프라인 단계는 상황과 필요에 따라 더 세분화되거나 간소화될 수 있음

☞ AWS 개발자 도구

✔︎ AWS의 개발자 도구 섹션에서 제공하는 서비스를 활용하여 배포 자동화 파이프라인 구축 가능
✔︎ 개발자 도구 서비스 목록

✔︎ CodeCommit

  • Source 단계를 구성할 때 이용
  • GitHub와 유사한 서비스를 제공하는 버전 관리 도구
  • 비교했을 때 보안 관련 기능에 강점
  • 과금 가능성 고려
    ※ GitHub : 사이드 프로젝트나 가볍게 작성한 소스 코드 저장 시 효과적

✔︎ CodeBuild

  • Build 단계에서 이용
  • 유닛 테스트, 컴파일, 빌드와 같은 빌드 단계에서 필수적으로 실행되어야 할 작업들을 명령어를 통해 실행 가능

✔︎ CodeDeploy

  • Deploy 단계를 구성할 때 이용
    Deploy 단계에서는 기본적으로 다양한 서비스 이용 가능
    ex) CodeDeploy, S3 등
  • 실행되고 있는 서버 애플리케이션에 실시간으로 변경 사항 전달 가능
  • S3 버킷을 통해 업로드된 정적 웹 사이트에 변경 사항을 실시간으로 전달 및 반영 가능

✔︎ CodePipeline

  • 각 단계를 연결하는 파이프라인 구축 시 이용
    🚨 주의 ❗️
    : AWS 프르티어 계정 사용 시 한 계정에 두 개 이상의 파이프라인을 생성하면 추가 요금 부여
  1. AWS Pipeline을 통한 배포 자동화

⦿ 학습내용

☞ 개발 환경 구축

✅ EC2 인스턴스에서 진행
✔︎ 자바 설치

  • 패키지 정보 최신 상태 업데이트
$ sudo apt update
  • java 설치
$sudo apt install openjdk-11-jre-headless

✔︎ AWS CLI 설치

  • AWS CLI 설치
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ sudo apt install unzip
$ unzip awscliv2.zip
$ sudo ./aws/install
  • AWS CLI 설치 여부 확인
$ aws --version

aws-cli/2.1.39 Python/3.8.8 Darwin/20.4.0 exe/x86_64 prompt/off
# 이런식의 문구가 보인다면 설치가 성공적으로 마무리된 것입니다.

✔︎ CodeDeploy Agent 설치

  • CodeDeploy Agent 설치
$ sudo apt update
$ sudo apt install ruby-full                # [Y / n] 선택시 Y 입력
$ sudo apt install wget
$ cd /home/ubuntu
$ sudo wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ sudo chmod +x ./install
$ sudo ./install auto > /tmp/logfile

※ 에러 발생 시 로그 지운 뒤 다시 설치
❗️ 삭제 로그 파일
- /tmp/codedeploy-agent.update.log
- /tmp/logfile

  • 서비스 실행 확인
$ sudo service codedeploy-agent status

# active(runnung) 문구를 확인할 수 있으면 정상 설치 후 실행중

☞ EC2 인스턴스 역할 부여

✔︎ AWS EC2 대시보드 - 인스턴스 - 태그 확인
✔︎ 보안 - IAM 역할 - 권한 추가 - 정책 연결
✔︎ S3 검색 - AmazonS3FullAccess 선택
✔︎ EC2Role 검색 - AmazonEC2RoleforAWSCodeDeploy 선택
✔︎ CodeDeployRole 검색 - AWSCodeDeployRole 선택
✔︎ SSMFull 검색 - AmazonSSMFullAccess 선택
✔︎ 정책 연결 - 권한 정책 확인
✔︎ 신뢰 관계 - 신뢰 정책 편집
✔︎ 기존 "Service": "ec2.amazonaws.com" 에서 →
"Service": ["ec2.amazonaws.com", "codedeploy.ap-northeast-2.amazonaws.com"] 추가

☞ EC2를 활용한 파이프라인 구축

✅ 개인 PC의 로컬에서 진행
✔︎ 실습 활용할 로컬 환경의 폴더에 appspec.yml 파일 추가

  • appspec.yml
    • CodeDeploy가 읽는 파일
    • CodeDeploy에서 지정한 각 단계에 맞춰 어떤 셸 스크립트를 실행하는지 지정
version: 0.0
os: linux

files:
  - source: /
    destination: /home/ubuntu/build

hooks:
  BeforeInstall:
    - location: server_clear.sh
      timeout: 3000
      runas: root
  AfterInstall:
    - location: initialize.sh
      timeout: 3000
      runas: root
  ApplicationStart:
    - location: server_start.sh
      timeout: 3000
      runas: root
  ApplicationStop:
    - location: server_stop.sh
      timeout: 3000
      runas: root

✔︎ 실습 활용할 로컬 환경의 폴더에 buildspec.yml 파일 추가

  • buildspec.yml
    • CodeBuild가 읽는 파일
    • CodeBuild가 지정한 각 단계에 맞춰 동작을 특정하여 명령
version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto11
  build:
    commands:
      - echo Build Starting on `date`
      - cd DeployServer
      - chmod +x ./gradlew
      - ./gradlew build
  post_build:
    commands:
      - echo $(basename ./DeployServer/build/libs/*.jar)
artifacts:
  files:
    - DeployServer/build/libs/*.jar
    - DeployServer/scripts/**
    - DeployServer/appspec.yml
  discard-paths: yes

✔︎ 실습 활용할 로컬 환경의 폴더에 scripts 디렉토리 생성
✔︎ scripts 폴더에 initialize.sh 생성

  • intialize.sh
    • 빌드 결과물을 실행할 수 있도록 실행 권한 추가
#!/usr/bin/env bash
chmod +x /home/ubuntu/build/**
  • server_clear.sh
    • 빌드 결과물이 저장되어있는 build 디렉토리 제거
#!/usr/bin/env bash
rm -rf /home/ubuntu/build
  • server_start.sh
    • DeployServer-0.0.1-SNAPSHOT.jar라는 빌드 결과물 실행
#!/usr/bin/env bash
cd /home/ubuntu/build
sudo nohup java -jar DeployServer-0.0.1-SNAPSHOT.jar > /dev/null 2> /dev/null < /dev/null &
  • servver_stop.sh
    • 실행중인 Spring Boot 프로젝트 종료
#!/usr/bin/env bash
sudo pkill -f 'java -jar'

☞ 서버 배포 자동화 결과 확인

✔︎ Postman 또는 브라우저를 이용해 테스트 진행
✔︎ 생성한 EC2 인스턴스의 IP 주소를 이용해 테스트 진행
.env파일의 환경 변수 값을 변경하여 S3 활용 가능

  1. 환경 변수 설정

⦿ 학습내용

☞ 서버 환경 변수 설정

✔︎ Parameter Store 대시 보드 - 파라미터 생성
✔︎ properties 파일을 확인하면 spring.datasource.url, spring.datasource.username, spring.datasource.password, config.domain 존재
✔︎ 이름 - /spring-boot-aws/be-35-nacseo/spring.datasource.url,
- properties 이름에 해당하는 값을 설정
✔︎ 이름 - /spring-boot-aws/be-35-nacseo/spring.datasource.username,
- properties 이름에 해당하는 값을 설정
✔︎ 이름 - /spring-boot-aws/be-35-nacseo/spring.datasource.password,
- properties 이름에 해당하는 값을 설정
🚨 password의 경우, 유형보안 문자열로 설정하여 더 안전하게 관리 가능
✔︎ 이름 - /spring-boot-aws/be-35-nacseo/config.domain,
- properties 이름에 해당하는 값을 설정
✔︎ build.gradle 파일에 해당 내용 추가

  • dependencies
    implementation 'org.springframework.cloud:spring-cloud-starter-aws-parameter-store-config' 추가
  • 해당 블록 추가
dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-starter-parent:Hoxton.SR12"
	}
}

✔︎ src/main/resources/bootstrap.yml 파일 생성

aws:
  paramstore:
    enabled: true
    prefix: /spring-boot-aws
    name: be-35-nacseo
    profileSeparator: _

✔︎ commitpush하여 파이프라인을 통해 전달

◉ 느낀 점

☞ 배포 과정을 학습하면서 변경사항이 발생할 때마다 매번 배포를 수동으로 진행하면, 엄청 복잡하고 시간도 많이 소요될 것 같았다.

사람의 생각은 모두 같았나보다 🫢

배포 자동화 기술을 따라 학습하면서 대부분은 잘 됐지만, 마지막 부분에서 또 고생을 많이 했다 ^^,, 이것저것 바꿔보고, 페어님께서도 도움을 주셔서 다행히 잘 해결할 수 있었다! 오늘 느낀 점도 error handling 느낌으로 회고하겠다.

처음 만난 오류는 CORS 오류였다.

어제 수동 배포를 공부할 때 페어분께서 마주친 오류라서 쉽게 원인을 알고 수정할 수 있었다.

프로퍼티 파일의 오타 문제였다고 하셨다!
따라서 프로퍼티 파일을 눈빠지게 확인한 결과...
dependencies
implementation 'org.springframework.cloud:spring-cloud-starter-aws-parameter-store-config'implementation 'org.springframework.cloud.spring-cloud-starter-aws-parameter-store-config' 으로 작성하였다,, (:.로 작성했다 🥲)
수정 후 진행해보니 CORS 오류는 해결했다❗️

두번 째로 만난 오류는 AWS Pipeline을 통한 배포 자동화를 학습할 때는 잘 되던 배포 자동화가 환경 변수 설정파트 학습 후 배포가 자동으로 실행이 안됐다.

(S3 엔드포인트로 접속해서 로그인했을 때 개발자 도구(F12)를 통해 확인한 발생 오류)

프로퍼티 내용이 있기에 다시 프로퍼티 파일을 확인했다.
해당 학습 내용에 server: 80으로 설정하는 내용이 있었는데 작성해도 안해도 무관한 내용이라 기재되어 있어 나는 작성을 했다. 아마 이 부분 때문에 EC2 주소의 포트번호가 달라져 서버에 연결이 안된 것이라 생각되어 해당 부분을 삭제하였다.

추가적으로, 페어님을 통해 알게 된 사실로
Parameter Store 대시 보드를 통해 파라미터 생성 할 때 /spring-boot-aws/be-35-nacseo/spring.datasource.url의 값이 properties{AWS RDS Endpoint}로 되어 있어서 엔드포인트 주소만 입력했었는데,
RDS에 설정한 포트 번호도 뒤에 :를 이용해 추가해줘야 데이터베이스와 연결된다고 도움을 주셨다.

또한, 어제 학습한 .nav example파일도 어제와 동일하게 주소 값을 추가하고 npm을 install하고 npm을 build, 다시 커밋해 푸시, 파이프라인에 액세스를 재시동 해주었다. 이를 통해 올바르게 로그인될 수 있도록 하였다.

수많은 노력을 한 결과 ...

해냈따!!!!!!!! 🥹🥹🥹
개발자에게 가장 행복한 순간이 아닌가 싶다 😊

오늘 학습 내용을 진행하면서 많은 오류 메세지와 마주했지만, 포기하지 않는 노력과 페어분의 도움으로 잘 해결해서 마칠 수 있었다. 오늘의 기억을 잊지 않고 프로젝트 때도 꺾이지 않는 마음으로 오류 핸들링을 해내나가겠다!!!

◉ 내일의 키워드

・ Github Actions
profile
백엔드 개발자 김창하입니다 🙇‍♂️

0개의 댓글