해당 포스팅은 사이드 프로젝트 진행 중 겪은 크고 작은 이슈들에 대한 기록입니다.
이 때까지 개발 과정은 별다른 구분없이 로컬에서만 개발을 진행하였기에 문제가 없었으나, AWS에 배포 서버를 옮기게 되면서 yml 파일의 profile 설정에 대한 무지함이 발목을 잡았다.
spring의 profile 기능을 활용하여 로컬 개발 환경과 AWS의 배포 환경을 나누어 관리할 수 있다.
이 과정에서 SpringBoot 2.4.0 이전의 방법과 이후의 방법이 달라졌음을 알게 됐고, 구글에서 찾은 게시글이 이를 명확히 구분하여 사용하지 않고 있는 것을 깨달아 혼자 직접 헤딩하면서 profile 관리법을 익혔다.
SpringBoot 2.4.0 이전
spring:
profiles: local
include:
real_db, local_db
spring.profiles.[name] 형식처럼 사용할 프로필을 명시하고, include 키워드를 이용하여 명시한 프로필에 포함시킬 다른 프로필을 선언해줌
처음 이 방식을 사용했으나, deprecated 됐다는 경고를 보고 아래와 같이 변경
SpringBoot 2.4.0 이후
spring:
profiles:
active: local
group:
"local": "local_db, default, oauth"
"real": "real_db, default, oauth"
--- # (yml 구분선)
spring:
config:
activate:
on-profile: default
# 밑으로 yml 설정들 기재
---
spring:
config:
activate:
on-profile: local_db
---
spring:
config:
activate:
on-profile: real_db
spring.config.activate.on-profile.[name] 의 형식으로 프로필을 선언한다.
spring.profiles.group 기능을 활용하여 그룹을 부여, 그룹명을 이용하여 해당 그룹에 속한 모든 요소들을 한 번에 프로필로 사용할 수 있다.
spring.profiles.active.[name]으로 별다른 호출이 없는 경우 초기에 불러 사용할 프로필 값을 정해준다.
EC2의 스크립트 단에서 아래의 스크립트를 통해 profile 명을 호출하면 위에서 on-profile에 설정한 yml profile 설정들을 맞춰 사용할 수 있다.
2.4.0 이후 프로필 버젼 관리 방법을 터득한 후, EC2에서 서버를 구동시키면 아래에서 보는 것과 같이 원하는 profile 설정들이 등록된 것을 확인할 수 있었다.
배포까진 힘겹게 성공했지만, 이상하게 테스트 코드는 계속 실패로 뜬다 (로컬에선 성공)
gradle build를 --debug 옵션을 부여하여 debug 로그를 모두 보게 설정
위처럼 무수히 많은 로그가 찍히는 중... (구글링을 해봐도 이유를 파악하지 못 했음)
Test 코드에 Profile을 별도로 설정하여도 똑같이 에러 발생
임시 방편으로 gradle에서 아래 코드를 주석처리 함
//tasks.named('test') {
// useJUnitPlatform()
//}
이유를 아시는 분들은 댓글 달아주시면 너무 감사하겠습니다 ㅠㅠ...
Travis CI에서 gradlew의 실행 권한이 없어서 발생하는 에러
EC2에 실행 권한을 부여했으나, Travis CI 쪽에서의 접근은 별개로 취급하는 것 같다.
아래의 코드들로 해결할 수 있음
git update-index --chmod=+x gradlew
git commit -m "Travis CI Permission 등록"
<!-- 아래의 명령어로 권한 확인 가능 -->
git ls-tree HEAD
100755 가 나오면 허가가 부여된 것
2번에서 Test를 끄지 않으면 위 과정에서도 Test 실패로 인한 에러가 발생함
Travis CI가 작동하는 중, Github에서 PR을 완료해버리면 위의 에러가 발생한다.
사실, 작동을 모두 기다려도 어차피 S3과 CodeDeploy는 PR로 인식하여 작동하지 않는다.
따라서 그냥 무시하고 진행해도 상관없을 듯 하다.
Version 2 of the Ruby SDK will enter maintenance mode as of November 20, 2020. To continue receiving service updates and new features, please upgrade to Version 3. More information can be found here: https://aws.amazon.com/blogs/developer/deprecation-schedule-for-aws-sdk-for-ruby-v2/
Triggered deployment "d-P0UMRF7JJ".
위의 코드가 나오면서 deployment에 실패. (사실 위의 코드와는 별개로 발생한 문제)
해결법은 아래에서!!
S3의 퍼블릭 접근을 모두 다 차단하여서 발생한 문제.
S3에 이미지를 업로드 하는 과정에서
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, uploadFile)
.withCannedAcl(CannedAccessControlList.PublicRead);
위의 코드로 업로드 하는 각각의 이미지에 PublicRead 권한을 부여해준다.
이 경우에도 Access Denied 403 에러가 발생하였다.
결국 아래의 사진처럼 버킷에 대한 권한 제한을 어느 정도 풀고 나서야 문제를 해결하였다.
퍼블릭 액세스 권한을 해제하지 않고 접근하는 방법을 아직까지 찾지 못하여 넘어갔으나, Best Practice를 알게 되면 그 방법으로 접근 권한을 수정해야겠다ㅠㅠ
이미지 업로드 시, createFile로 새로운 File 객체를 생성한다. 하지만 이 과정에서 EC2 파일 생성 권한이 없어서 에러가 발생...
심지어 S3 쪽 권한 문제인줄 알고 한참을 헛돌았다...ㅠㅠ
private Optional<File> convert(MultipartFile file) throws IOException {
File convertFile = new File("/tmp/"+file.getOriginalFilename());
if(convertFile.createNewFile()) {
try (FileOutputStream fos = new FileOutputStream(convertFile)) {
fos.write(file.getBytes());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
파일을 생성하는 시점에 "/tmp/" 경로를 부여해주니 Permission이 통과됐다.
File convertFile = new File(file.getOriginalFilename()); 이렇게 이름만 부여하면 Tomcat 내부에 파일을 임시 생성하고, 그 과정에 파일을 생성하는 권한이 EC2 계정에 부여돼있지 않아 일어난 문제인 것 같다.
tmp 디렉토리는 권한이 모두 열려있으므로 파일 생성에 권한이 따로 필요없기에 경로로 선택했다.
Github에 application.yml이 올라가는 바람에 EC2 접근 및 IAM Access key 보안에 문제가 생겼다...!
AWS Health Dashboard에 경고가 날라와서 문제가 발생했다는 것을 한 눈에 파악이 가능했다.
노출이 되면 IAM 사용자 권한에 위의 AWSCompromisedKeyQuarantineV2라는 권한이 하나 추가된다.
위의 친구가 AWS의 정상적인 사용을 금지한다. (Access key 노출로 인한 보안을 위해서)
권한을 제거해주고, 기존의 Access Key는 폐기 후 재발급 받아서 사용하면 된다하여 그대로 진행했으나...
폐기까지 했는데도 Health에 경고가 떠있다. 또한 EC2는 여전히 정상 접근이 불가능했다.
AWS의 가이드라인을 보고 Access key를 콘솔로도 교체해보고 웹에서도 교체해봤으나 해결 자체가 되지 않아 결국 EC2 자체를 삭제하고 새로운 EC2를 만드는 무식한 방법으로 해결하였다.