개발하고 싶은 초심자
220330 D+70 Client & Server Deployment Pipeline, 환경 변수 설정 본문
220330 D+70 Client & Server Deployment Pipeline, 환경 변수 설정
정새얀 2022. 3. 29. 20:441. Client Deployment Pipeline
① 소스 코드를 클론해온 뒤, buildspec.yml 파일을 생성하고 파일 내용을 채운다.
version: 0.2
phases:
pre_build:
commands:
- cd client
- npm install
build:
commands:
- npm run build
artifacts:
files:
- '**/*'
base-directory: client/build
저장하고 commit, push한다.
② AWS에 접속하여 CodePipeline을 검색하여 메인 콘솔에 들어간 후 파이프라인 생성 클릭.
파이프라인 이름 설정 - 다음 - 소스 공급자는 Github(버전 2)
- 다음 - Github에 연결 - 연결 이름 설정 - Github에 연결
- 새 앱 설치 - 본인 Github 계정 클릭 - Only select repositories 체크 - Select repositories 토클 클릭
- 레포지토리 검색, 선택 - Install 클릭 - 연결 클릭 - 레포지토리 이름, 브랜치 이름 선택 - 다음
- 빌드 공급자 AWS CodeBuild 선택
(소스 단계를 통해 전달받은 코드를 테스트 / 빌드하여 배포 단계로 전달하는 역할)
- 다음 - 프로젝트 생성 - 프로젝트 이름 설정 - 운영체제 Ubuntu - 런타임 Standard
- 이미지는 aws/codebuild/standared 5.0 - 환경유형 Linux
- CloudWatch 체크
(s3는 정적 웹 호스팅을 위한 버킷이 이미 생성되어 있어, 버킷의 수가 많아지면 과금 가능성이 커짐
빌드 출력 로그 저장을 위한 서비스로 CloudWatch를 선택하여 리소스를 분산시킴)
- CodePipeline으로 계속 클릭 - 다음
- 배포 스테이지 추가(빌드 과정 후 최종적으로 만들어진 결과물 전달 및 반영) 배포 공급자는 Amazon S3
- 버킷 선택 - 배포하기 전에 압축 풀기 옵션 체크(안하면 결과물 정상 전달 안됨) - 다음
- 파이프라인 생성 클릭 - S3에 들어가면 codepipeline으로 시작된 버킷 생성 확인(무시해도 됨)
- S3 버킷의 엔드포인트 주소로 접속하여 정상적으로 페이지가 보이는 지 테스트하기
✷ 만약 빌드 과정에서 실패 메시지가 보일 때는
빌드 출력 로그를 확인하여 문제점을 찾아볼 수 있다.
① CodeBuild 메인 콘솔로 들어가서
생성한 빌드 프로젝트 - 실패한 빌드 실행 기록 클릭 - 로그 확인 후 해결 방안 찾기
(빌드 로그를 보면, buildspec.yml에 작성된 명령어가 실제로 정상적으로 작동하는지,
빌드 과정의 라이프 사이클이 어떻게 흘러가는지, 정확히 어떤 오류가 발생했는지 확인 가능)
테일 로그 버튼을 클릭하면 빌드 로그의 끝부분에 해당하는 로그 기록을 보여준다.
오류나 핵심적인 내용은 로그 파일의 끝부분에 위치하는 경우가 많기 때문에
테일 로그를 이용하면 원하는 정보를 빨리 찾을 수 있다.
② CloudWatch 메인 콘솔로 들어가서
사이드바에 있는 로드 그룹 - /aws/codebuild/빌드 프로젝트 이름 으로 구성된 로그 그룹을 찾는다
- 가장 최신 버전의 로그 스트림 클릭
2. Server Deployment Pipeline
(프리티어에서는 파이프라인이 2개 이상 되면 개수에 따른 금액이 부여된다)
① EC2 인스턴스에 태그 / 역할 부여하기
✷ 태그를 추가하는 이유는 파이프라인 구축 단계에서 인스턴스를 잘 식별하기 위해서다.
‣ 태그 추가하는 과정
EC2 - 사이드바에 있는 인스턴스 - 인스턴스 선택 - 작업 - 인스턴스 설정 - 태그 관리 - 태그 추가
- 키 / 값 설정(나는 EC2 Tag로 설정해줌) - 저장 - 태그 생성 끝.
‣ IAM 서비스를 이용하여 EC2 인스턴스에 역할을 부여하는 과정
✷ 역할(Role)
: AWS의 개체(서비스, 사용자 등)가 다른 서비스에 접근하게 할 수 있도록 해주는 방법.
→ EC2 인스턴스에 역할을 부여함으로써 다른 AWS 서비스를 호출할 수 있는 권한을 가진다.
✷ 신뢰 관계
: 해당 역할을 취할 수 있는 서비스 / 사용자를 명시하는 부분
(access 정책 부여를 통해 역할을 생성해 주었지만,
access 할 수 있는 서비스를 신뢰 관계에서 명시함으로써 역할이 확실히 완성된다)
인스턴스 선택 - 작업 - 보안 - IAM 역할 수정 - 새 IAM 역할 생성
- 역할 만들기 - AWS 서비스, EC2 선택
- 다음 - s3 검색, AmazonS3FullAccess 선택
- SSM 검색, AmazonSSMFullAccess 선택
- CodeDeploy 검색, AWSCodeDeployRole 선택
- 다음 - 다음 - 역할 이름 설정 - 역할 만들기 클릭
- 메인화면으로 돌아와 생성한 역할 클릭 - 신뢰 관계 편집
- "Service": ["ec2.amazonaws.com", "codedeploy.ap-northeast-2.amazonaws.com"]으로 수정.
- 신뢰 정책 업데이트 - EC2 수정 페이지로 돌아오기 - 생성한 IAM 역할 선택 - 저장
- EC2 보안 그룹 - 보안 - 보안 그룹 클릭 - 인바운드 규칙에 80과 443 포트 추가 - 규칙 저장
✷ 80번 포트는 서버 배포를 위해 필요하고,
443 포트는 후에 나올 CodeDeploy-Agent의 정상적인 작동을 위해 필요하다.
② EC2를 활용한 파이프라인 구축하기
클론해온 리포지토리 최상위에 appspec.yml 파일 추가
(배포 자동화를 도와주는 CodeDeploy-Agent가 인식하는 파일임)
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/im-sprint-practice-deploy
hooks:
ApplicationStop:
- location: scripts/stop.sh
runas: root
AfterInstall:
- location: scripts/initialize.sh
runas: root
ApplicationStart:
- location: scripts/start.sh
runas: root
- 최상위에 scripts 디렉토리 생성 - initialize.sh, start.sh, stop.sh 파일 3개 생성.
initialize.sh
#!/bin/bash
cd /home/ubuntu/im-sprint-practice-deploy/server
sudo npm install -g n
sudo n 17.5.0
sudo npm install pm2@latest -g
sudo apt-get update
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown ubuntu /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
start.sh
#!/bin/bash
cd /home/ubuntu/im-sprint-practice-deploy/server
authbind --deep pm2 start app.js
stop.sh
#!/bin/bash
cd /home/ubuntu/im-sprint-practice-deploy/server
pm2 stop app.js 2> /dev/null || true
pm2 delete app.js 2> /dev/null || true
- 변경 사항 저장 - git add . - git commit -m "커밋 메시지 내용" - git push(master로 push했음)
- AWS CodeDeploy로 이동 - 애플리케이션 - 애플리케이션 생성 - 애플리케이션 이름 설정
- 컴퓨팅 플랫폼은 EC2/온프레미스로 설정 - 애플리케이션 생성 - 배포 그룹 - 배포 그룹 생성
- 배포 그룹 설정 - 서비스 역할 입력에 아까 생성했던 역할 선택
- 환경 구성에서 Amazon EC2 인스턴스 체크 - 태그 그룹에는 아까 설정했던 태그 키 / 값 선택
- 로드 밸런싱 활성화 체크 해제(많은 트래픽이 없기 때문에 일부러 해제함, 많은 트래픽이 예상될 땐 체크)
- 배포 그룹 생성 클릭
✷ 실습에서 이용하는 서버 코드(애플리케이션)가 코드의 컴파일 / 빌드 과정이 필요없고
테스트 코드가 따로 없기 때문에 빌드 단계를 생략했다.
- CodePipeline 대시보드로 이동 - 파이프라인 생성 클릭
- 파이프라인 이름 설정 - 다음 - 소스 스테이지 추가에 소스 공급자는 Github(버전 2) - 다음
- Github에서 연결 - 연결 이름 설정 - Github에 연결 - 새 앱 설치 - 본인 Github 계정 클릭
- Only select repositories - 소스 코드로 이용할 레포지토리 선택 - Save 클릭 - 연결
- 레포지토리 이름은 조금 전 연결한 레포지토리명과 같이 지정 - 브랜치 이름은 master
- 출력 아티팩트 형식은 CodePipeline 기본값 으로 지정 - 다음
- (여기서는 빌드 스테이지 건너뛰기) - 건너뛰기
- 배포 공급자는 AWS CodeDeploy 선택 - 리전은 아시아 태평양(서울)
- 애플리케이션 이름은 생성해둔 이름 선택 - 배포 그룹도 생성해 둔 배포 그룹 선택 - 파이프라인 생성
(에러가 나서 파일을 수정하면 반드시 변경 사항 릴리스 한 뒤에 배포 재시도 할 것)
✷ deploy 스테이지에서 실패하는 경우 로그 확인
터미널에 명령어 입력
cd /opt/codedeploy-agent/deployment-root/deployment-logs
ls
nano codedeploy-agent-deployments.log
- 서버 파이프라인 생성하고 deploy 단계에서 직면한 에러
[2022-03-30 05:29:53.543] [d-P0H8RGTUF][stderr]npm ERR! typeerror at resolveWithNewModule (/usr/share/npm/lib/install/deps.js:456$
[2022-03-30 05:29:53.543] [d-P0H8RGTUF][stderr]npm ERR! typeerror at /usr/share/npm/lib/install/deps.js:457:7
[2022-03-30 05:29:53.544] [d-P0H8RGTUF][stderr]npm ERR! typeerror at /usr/share/npm/node_modules/iferr/index.js:13:50
[2022-03-30 05:29:53.545] [d-P0H8RGTUF][stderr]npm ERR! typeerror at /usr/share/npm/lib/fetch-package-metadata.js:37:12
[2022-03-30 05:29:53.545] [d-P0H8RGTUF][stderr]npm ERR! typeerror at addRequestedAndFinish (/usr/share/npm/lib/fetch-package-meta$
[2022-03-30 05:29:53.545] [d-P0H8RGTUF][stderr]npm ERR! typeerror at returnAndAddMetadata (/usr/share/npm/lib/fetch-package-metad$
[2022-03-30 05:29:53.546] [d-P0H8RGTUF][stderr]npm ERR! typeerror at pickVersionFromRegistryDocument (/usr/share/npm/lib/fetch-pa$
[2022-03-30 05:29:53.546] [d-P0H8RGTUF][stderr]npm ERR! typeerror at /usr/share/npm/node_modules/iferr/index.js:13:50
[2022-03-30 05:29:53.546] [d-P0H8RGTUF][stderr]npm ERR! typeerror This is an error with npm itself. Please report this error at:
[2022-03-30 05:29:53.546] [d-P0H8RGTUF][stderr]npm ERR! typeerror http://github.com/npm/npm/issues
[2022-03-30 05:29:53.614] [d-P0H8RGTUF][stderr]WARN engine pidusage@3.0.0: wanted: {"node":">=10"} (current: {"node":"8.10.0","npm":"$
[2022-03-30 05:29:54.012] [d-P0H8RGTUF][stderr]
[2022-03-30 05:29:54.013] [d-P0H8RGTUF][stderr]npm ERR! Please include the following file with any support request:
[2022-03-30 05:29:54.013] [d-P0H8RGTUF][stderr]npm ERR! /home/ubuntu/im-sprint-practice-deploy/server/npm-debug.log
[2022-03-30 05:29:54.131] [d-P0H8RGTUF][stdout]Hit:1 http://ap-northeast-2.ec2.archive.ubuntu.com/ubuntu bionic InRelease
[2022-03-30 05:29:54.132] [d-P0H8RGTUF][stdout]Get:2 http://ap-northeast-2.ec2.archive.ubuntu.com/ubuntu bionic-updates InRelease [88$
[2022-03-30 05:29:54.135] [d-P0H8RGTUF][stdout]Get:3 http://ap-northeast-2.ec2.archive.ubuntu.com/ubuntu bionic-backports InRelease [$
[2022-03-30 05:29:54.622] [d-P0H8RGTUF][stdout]Hit:4 http://security.ubuntu.com/ubuntu bionic-security InRelease
[2022-03-30 05:29:54.810] [d-P0H8RGTUF][stdout]Fetched 163 kB in 1s (278 kB/s)
[2022-03-30 05:29:56.640] [d-P0H8RGTUF][stdout]Reading package lists...
[2022-03-30 05:29:56.775] [d-P0H8RGTUF][stdout]Reading package lists...
[2022-03-30 05:29:56.985] [d-P0H8RGTUF][stdout]Building dependency tree...
[2022-03-30 05:29:56.986] [d-P0H8RGTUF][stdout]Reading state information...
[2022-03-30 05:29:57.155] [d-P0H8RGTUF][stdout]authbind is already the newest version (2.1.2).
[2022-03-30 05:29:57.251] [d-P0H8RGTUF][stdout]0 upgraded, 0 newly installed, 0 to remove and 66 not upgraded.
[2022-03-30 05:29:57.561] [d-P0H8RGTUF]LifecycleEvent - ApplicationStart
[2022-03-30 05:29:57.561] [d-P0H8RGTUF]Script - scripts/start.sh
[2022-03-30 05:29:57.617] [d-P0H8RGTUF][stderr]pm2: No such file or directory
stderr: standard error
stdout: standard output
(환경 변수 설정 실습에는 RDS 인스턴스가 생성되어 있어야 함)
‣ AWS CLI 설치 방법
터미널을 통해 EC2 인스턴스 접속.
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 --version
명령어를 입력했을 때 이렇게 나오면 성공.
aws-cli/2.5.0 Python/3.9.11 Linux/5.4.0-1060-aws exe/x86_64.ubuntu.18 prompt/off
3. Client 환경 변수 설정
CodeBuild 서비스를 이용하여 환경 변수를 설정하는 방법
① CodeBuild - 생성되어있는 빌드 프로젝트 클릭 - 편집 토클에서 환경 클릭
- 추가 구성 토클 클릭
② 환경변수 이름을 REACT_APP_API_URL로 입력하고,
값에는 EC2 instance IP address를 입력한다.
IP 주소 앞에 http:// 를 필수로 붙여주어야 한다.
그 다음 환경 업데이트 클릭.
③ '빌드 프로젝트의 환경이 업데이트 되었습니다' 메시지가 보이면 환경 변수 설정 완료.
생성한 S3 버킷 엔드포인트 주소로 접속하여 로그인 테스트를 진행하고,
로그인 과정이 정상 진행된다면 클라이언트와 서버의 연결이 정상적으로 된 것이다.
4. Server 환경 변수 설정
비밀번호 같은 환경 변수는 외부 노출이 되면 안 되기 때문에 소스코드에 포함할 수 없다.
AWS Parameter Store 서비스를 이용하면 EC2 instance에 환경 변수를 전달할 수 있다.
① AWS에서 Parameter Store - 파라미터 생성 클릭.
② 이름과 환경 변수에 할당되어야 할 값을 입력한 후 파라미터 생성 버튼 클릭
③ 소스 코드의 start.sh 파일을 아래에 있는 소스코드로 변경한다.
#!/bin/bash
cd /home//im-sprint-practice-deploy/server
export DATABASE_USER=$(aws ssm get-parameters --region ap-northeast-2 --names DATABASE_USER --query Parameters[0].Value | sed 's/"//g')
export DATABASE_PASSWORD=$(aws ssm get-parameters --region ap-northeast-2 --names DATABASE_PASSWORD --query Parameters[0].Value | sed 's/"//g')
export DATABASE_PORT=$(aws ssm get-parameters --region ap-northeast-2 --names DATABASE_PORT --query Parameters[0].Value | sed 's/"//g')
export DATABASE_HOST=$(aws ssm get-parameters --region ap-northeast-2 --names DATABASE_HOST --query Parameters[0].Value | sed 's/"//g')
authbind --deep pm2 start app.js
④ 변경사항을 저장하고 commit, master로 push하여 파이프라인을 통해 변경 사항을 전달한다.
파이프라인을 통해 코드가 성공적으로 된 것을 확인한 후,
배포한 클라이언트 S3 버킷의 엔드포인트로 접속하여 환경 변수가 정상 전달되었는 지 확인한다.
이 때 RDS의 연결 여부도 확인한다.
'기술개념정리(in Javascript)' 카테고리의 다른 글
Git Cheat Sheet (0) | 2022.06.02 |
---|---|
220330 D+70 배포 자동화(Automated Deployment), IAM (0) | 2022.03.29 |
220329 D+69 Docker (0) | 2022.03.29 |
220328 D+68 도메인 주소를 이용한 HTTPS 인증 (0) | 2022.03.28 |
220325(28) D+67(68) 백엔드&프론트엔드 배포, 데이터베이스 연결 (0) | 2022.03.28 |