Travis CI(유료..-_-) + AWS(S3, CodeDeploy) 연동

2022. 2. 21. 17:48CM/aws

반응형
반응형

오늘은 저번 시간에 Travis CI 무료인줄 알았는데 유료인 친구를 셋팅 한 뒤 이제는 AWS와 연동을 해보려고 합니다.
우선적으로 AWS S3라는것이 있는데 이녀석은 "파일서버"라고 보시면 됩니다.
보통 이미지 업로그 구현 시 S3로 구현하는 경우가 많다고하네요
그리고 실제 Deploy는 CodeDeploy라는 서비스를 이용합니다.
그러나 이녀석은 저장기능이 없기때문에 우리는 S3에 우리가 만든 app jar파일(빌드 결과물)을 S3에 저장했다가 CodeDeploy가 가져가서 배포할 수 있도록 합니다.


정리하면 Travis CI(빌드) - S3(잠시 저장) - CodeDeply(저장된거 가져가다가 배포) 이렇게 되겠군요

시작해보겠습니다.

1. AWS Key 발급

AWS 서비스에 외부 서비스가 접근할 수 없습니다. 그러므로 접근 가능한 권한을 가진 Key를 생성해서 사용 합니다.
AWS는 이러한 인증관련된 기능을 제공하는 서비스로 IAM(Identity and Aceess Management)이 있습니다.

위처럼 AWS 웹콘솔에서 IAM을 검색하여 클릭 해줍니다.
그런 뒤 사용자 > 사용자 추가를 클릭 합니다.

사용자 > 사용자 추가 클릭

사용자 이름을 넣고 AWS 액세스 유형은 프로그래밍 방식 액세스를 골라 줍니다.

권한 설정은 기존 정책 직접연결을 선택하고 아래와 같이 S3, CodeDeploy를 선택하고 넘어갑니다.
(단, S3, CodeDeploy 각자 정책을 줄수도 있습니다.)

 

다음으로 태그는 Name값을 지정하는데, 본인이 인지 가능한 정도의 이름으로 만듭니다.

검토 - 지금까지 생성한 권한 설정 항목들을 확인 합니다.

마지막으로 access key와 secret key가 생성 됩니다.
이 2개의 키는 Travis CI에서 사용될 키 입니다.

2. Travis CI에 키 등록

Travis CI로 가서 More options > Settings를 클릭 합니다.

 

셋팅스를 누르면 아래와 같은 페이지가 나옵니다.
우리는 Environment Variables에 AWS_ACCESS_KEY, AWS_SECRET_KEY를 변수로 해서 IAM에서 발급받은 키를 등록 합니다.

AWS_ACCESS_KEY :  엑세스 키 ID
AWS_SECRET_KEY : 비밀 엑세스 키

참고 : 등록 시 DISPLAY VALUE IN BUILD LOG 를 활성화 시키지 않았습니다. 비활성 시 * 로 보이게 됩니다.

3. S3 버킷 생성

이제는 S3(Simple Storage Service)에 관한 설정을 해보도록 하겠습니다.
위에서 말한것과 같이 이녀석은 파일서버로 보시면 됩니다.
파일들을 저장하고 접근 권한을 관리, 검색 등을 지원하는 파일 서버의 역할을 합니다.

여기에서는 Travis CI에서 생선 된 Build파일을 저장하도록 구성 합니다.
또한 S3에서 저장된 파일은 이후 AWS CodeDeploy에서 배포할 파일로 가져가도록 구성하게 됩니다.
우선 S3를 셋팅해보로독 하겠습니다.

역시나 AWS 콘솔에서 s3를 검색 합니다.

버킷을 만들어 봅시다. 버킷 만들기를 클릭 합니다.
(버킷은 S3에 저장되는 데이터의 컨테이너 입니다.)

버킷명은 버킷에 배포할 Zip파일이 모여있는 장소임을 의미하도록 지어보겠습니다.
버킷명을 지을때 룰은 아래의 링크를 참조 하시면 됩니다.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html

 

Bucket naming rules - Amazon Simple Storage Service

Before March 1, 2018, buckets created in the US East (N. Virginia) Region could have names that were up to 255 characters long and included uppercase letters and underscores. Beginning March 1, 2018, new buckets in US East (N. Virginia) must conform to the

docs.aws.amazon.com

버킷명을 의미있게 잘 지어보자~

퍼블릭 액세스는 모든 차단을 해줍니다.
실서비스의 경우 jar 파일이 퍼블릭일 경우 누구나 내려받을수 있어 코드나 설정값, 주요 키값들이 탈취될수 있으니
우리는 IAM에서 발급받은 키로 접근하여 사용 합니다. 

버킷 버전관리는 하면 좋겠지만..용량이 늘어나고 용량이 늘어나면 돈으로 직결되니 여기서는 비활성화를 해줍니다 ㅋㅋ

나머지 설정은 pass~버킷 생성을 해줍니다.
아래와 같이 버킷이 잘 생성됨을 알수 있습니다.

버킷 생성 완료!

3. S3로 배포 파일 전달

S3가 생성 되었으니 이제 이 S3로 배포 파일을 전달해 보겠습니다.
InteliJ에 .travis.yml에 다음 코드를 추가 합니다.

# deploy 명령어가 실행되기 전에 수행
# codeDeploy는 jar파일을 인식하지 못하므로 jar+기타 설정 파일들을 모아 압축(zip) 합니다.
before_deploy:
  - zip -r momistock *
  - mkdir -p deploy  # deploy라는 디렉토리를 Travis CI가 실행 중인 위치에 생성 합니다.
  - mv momistock.zip deploy/momistock.zip
deploy:
  - provider: s3
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: acet-springboot-build # S3 버킷
    region: ap-northeast-2
    skip_cleanup: true
    acl: private # zip 파일 접근을 private으로
    local_dir: deploy # before_deploy에서 생성한 디렉토리
    wait-until-deployed: true

.travis.yml에 설정 후 commit&push를 한 뒤 Travis CI에서 아래와 같이 pass한 것을 확인

aws S3에 가서 업로드가 잘 되었는지 확인 합니다.

3. CodeDeploy 연동(Deploy)

이제는 Travis CI로 빌드를 하고 빌드된 파일을 S3에 저장이 잘되었으니 이 파일들을 가져가 배포하는 CodeDeploy를
연동해 보겠습니다.

우선 배포대상인 EC2가 CodeDeploy를 연동 받을 수 있게 IAM 역할을 하나 생성하겠습니다.
IAM을 검색하여 역할 > 역할 만들기를 클릭 합니다.

앞서 만들었던 사용자와 역할의 차이점은 무엇일까요?

역할은?
- AWS 서비스에만 할당하는 권한
- EC2, CodeDeploy, SQS 등등

사용자는?
- AWS 서비스 외에 사용할 수 있는 권한
- local PC, Travis CI, IDC 서버 등등

아래와 같이 AWS 서비스, EC2를 선택 하고 다음을 클릭 합니다.

권한 추가는 EC2RoleForA로 검색하여 아래와 같이 AmazonEC2RoleforAWSCodeDeploy를 선택 하고 다음을 누릅니다.


다음으로 역할 세부정보의 이름을 지정하고

태그명을 넣고 역할을 생성합니다.

아래와 같이 Role이 생성되었음을 알수 있습니다.

이렇게 만든 Role을 EC2 서비스에 등록합니다.
EC2 인스턴스 목록으로 이동하여 보안 > IAM 역할 수정을 클릭 합니다.

위에서 만든 역할을 선택 후 저장 합니다.

인스턴스를 재부팅 해줍니다.

4. CodeDeploy Agent 설치

재부팅이 완료되면 CodeDeploy의 요청을 받을수 있게 에이전트를 설치 합니다.
EC2 서버에 접속하여 아래의 명령어를 수행 합니다.

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

>> aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2

download가 성공했다면 위와같은 문구가 뜹니다.

이제 install에 실행권한을 주고 install 파일로 설치를 진행 합니다.

실행권한 주기 : chmod +x ./install
[ec2-user@acet-springboot-webservice ~]$ sudo ./install auto
/usr/bin/env: ruby: No such file or directory

위와 같은 오류는 ruby 관련 내용이 없어서 나는 오류 입니다.
그래서 ruby를 install 해줍니다.

[ec2-user@acet-springboot-webservice ~]$ sudo yum install ruby
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                        | 3.7 kB  00:00:00
Resolving Dependencies
--> Running transaction check
---> Package ruby.x86_64 0:2.0.0.648-36.amzn2.0.2 will be installed
....
....

그런 뒤 다시 codedeploy agent를 설치 해줍니다.

[ec2-user@acet-springboot-webservice ~]$ sudo ./install auto
I, [2022-02-22T14:07:27.569659 #8146]  INFO -- : Starting Ruby version check.
I, [2022-02-22T14:07:27.569916 #8146]  INFO -- : Starting update check.
I, [2022-02-22T14:07:27.570035 #8146]  INFO -- : Attempting to automatically detect supported package manager type for system...
I, [2022-02-22T14:07:27.579937 #8146]  INFO -- : Checking AWS_REGION environment variable for region information...
I, [2022-02-22T14:07:27.580014 #8146]  INFO -- : Checking EC2 metadata service for region information...
I, [2022-02-22T14:07:27.594486 #8146]  INFO -- : Checking AWS_DOMAIN environment variable for domain information...
I, [2022-02-22T14:07:27.594556 #8146]  INFO -- : Checking EC2 metadata service for domain information...
I, [2022-02-22T14:07:27.599999 #8146]  INFO -- : Downloading version file from bucket aws-codedeploy-ap-northeast-2 and key latest/LATEST_VERSION...
I, [2022-02-22T14:07:27.600402 #8146]  INFO -- : Endpoint: https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/LATEST_VERSION
I, [2022-02-22T14:07:27.666750 #8146]  INFO -- : Downloading package from bucket aws-codedeploy-ap-northeast-2 and key releases/codedeploy-agent-1.3.2-1902.noarch.rpm...
I, [2022-02-22T14:07:27.666982 #8146]  INFO -- : Endpoint: https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/releases/codedeploy-agent-1.3.2-1902.noarch.rpm
I, [2022-02-22T14:07:27.738532 #8146]  INFO -- : Executing `/usr/bin/yum -y localinstall /tmp/codedeploy-agent-1.3.2-1902.noarch.tmp-20220222-8146-x29nms.rpm`...
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Examining /tmp/codedeploy-agent-1.3.2-1902.noarch.tmp-20220222-8146-x29nms.rpm: codedeploy-agent-1.3.2-1902.noarch
Marking /tmp/codedeploy-agent-1.3.2-1902.noarch.tmp-20220222-8146-x29nms.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package codedeploy-agent.noarch 0:1.3.2-1902 will be installed
....
....

agent 설치가 잘되었다면 정상적으로 실행되고 있는지 확인 합니다.

[ec2-user@acet-springboot-webservice ~]$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 8227

5. CodeDeploy를 위한 권한 생성(feat. IAM)

CodeDeploy에서 EC2를 접근하려면 마찬가지로 권한이 필요 합니다.
IAM에서 역할을 하나 더 만들어 줍니다.

CodeDeploy를 선택

권한 정책은 특별한것 없이 넘어 갑니다.

마지막으로 이름과 태그를 추가 한 뒤 역할을 생성합니다.

아래와 같이 codeploy-role이라는것이 생성 되었습니다. codedeploy to ec2

6. AWS CodeDeploy 배포 생성

지금까지 코드 커밋은 깃허브가 코드 빌드는 Travis CI가 하였습니다.
이제는 CodeDeploy로 배포를 해보겠습니다.

CodeDeploy로 검색을 합니다.

그리고나서 애플리케이션을 선택하시면 아래와 같이 애플리케이션 생성이라는것이 보입니다. 클릭 해줍니다.

애플리케이션 이름과 플랫폼을 선택 한 후 애플리케이션을 생성 합니다.

다음으로 배포그룹을 만듭니다. 배포그룹 생성을 클릭 합니다.

배포 그룹 이름과 서비스 역할을 선택해 줍니다.

배포유형은 배포할 서비스가 2대 이상이면 블루/그린을 선택하고 현재는 1대의 EC2에만 배포하기 때문에 현재 위치를 선택 합니다.

환경구성에서는 Amazon EC2 인스턴스를 선택하고 태그는 기존 만들었던 acet-springboot-webservice를 선택 합니다.

AWS CodeDeploy 에이전트는 이미 설치하였는데 더 효율적으로 관리를 해준다는 문구가 있어서 업데이트를 위해 지금 업데이트 및 업데이트 일정 예약을 선택 합니다.
배포설정에 배포구성은 한번 배포할때 몇 대의 서버에 배포할지를 결정하는데 2대 이상이라면 1대씩 배포할지, 30% 혹은 50%로 나눠서 배포할지 등등 여러 옵션을 선택하는게 있는데 여기서는 1대이기때문에 전체배포 옵션(CodeDeployDefault.AllAtOnce)을 선택 합니다.
로드밸런서 역시 체크하지 않습니다.

배포그룹을 생성하면 아래와 같은 내용들을 확인할 수 있습니다.

7.  Travis CI - S3 - CodeDeploy 연동

이제 빌드&배포를 수행하기 위해 Travis CI, S3, CodeDeploy를 연동해보도록 하겠습니다.
우선 S3에서 넘겨줄 zip파일을 저장할 디렉토리를 하나 생성하겠습니다.
mkdir ~/service/s3 && mkdir ~/service/s3/zip

이제 Travis CI의 빌드가 끝나면 s3에 zip파일이 전송되고, 이 zip파일은 /home/ec2-user/service/s3/zip로 복사되어 압출을 풀 예정 입니다.

Travis CI의 설정은 .travis.yml로 진행
AWS CodeDeploy의 설정은 deployspec.yml로 진행

deployspec.yml

version: 0.0
os : linux
files:
  - source: /
    destination: /home/ec2-user/service/s3/zip/
    overwrite: yes

.travis.yml

....
  - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: acet-springboot-build # S3 버킷
    key: momistock.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip
    application: acet-springboot-webservice # 웹 콘솔에서 등록한 CodeDeploy 어플리케이션
    deployment_group: acet-springboot-webservice-deploy-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹
    region: ap-northeast-2
    wait-until-deployed: true
....

deployspec.yml과 .travis.yml을 설정 후 commit&push 합니다.
오류 발생
codedeploy에서 deployspec.yml이 아니라 약속된 appspec.yml로 만들어줘야 합니다.

파일명 변경 후 commit&push

Travis CI build pass!

CodeDeploy deploy pass!

마지막으로 EC2서버에 접속하여 파일들이 잘 배포되었는지 확인 합니다.

Travis CI + S3 + CodeDeploy 연동 끝!

 

반응형