AWS/Project

CodeSeries를 활용한 CI/CD - TroubleShooting

jih0ssang 2024. 7. 1. 17:25

 

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

참고 사이트: https://sarc.io/index.php/aws/1588-s3-bucket-sync

 

  • S3 Access 권한이 없어서 뜨는 문제이다.
  • AWS CodeBuild가 S3 Access 권한을 가지고 있어야 한다.

 

CORS ERROR

 

  • 프론트 버킷(website s3) : 정적 웹 호스팅
  • 파일 버킷 (content s3) : 프론트 웹에 담긴 파일들 보관용 
  • 현재 상황
    • 파일 버킷(content s3)의 CORS 설정: 프론트 버킷(website s3)에서 파일 버킷(content s3) 접근 가능
  • 필요한 상황
    • 백엔드 코드에서 API 호출을 통해 파일 버킷(content s3)에 접근시 CORS 설정이 되어있지 않음
  •  
    • 백엔드 코드에서 addCorsMappings.allowedOrigins("http://s3-website-prd.s3-website.ap-northeast-2.amazonaws.com") 추가 필요

 

 


The deployment failed because a specified file already exists at this location: /home/ec2-user/SNAPSHOT.jar

 

  • 하나의 인스턴스에 이미 한번 파이프라인 배포를 한 뒤라서 이미 파일이 존재하여 배포가 불가능했다.
  • 특정 인스턴스에 하나의 파이프라인만 배포하는 것을 권장한다. 기 존재하는 파일은 지우길 바란다.

여러 파이프라인 생성 시 동일한 IAM Role 을 사용 시 충돌

 

  • IAM Role은 공동으로 사용하면 안되고 파이프라인별 생성하여 관리해야 함

배포시 ssl 에러

 

퍼블릭 서브넷에 IGW 없었음


codepipeline 수동 배포

 

AWS CodePipeline에서 단계별 트리거를 CloudWatch는 Amazon EventBridge 규칙으로 구성되어있다.

CodePipeline 수동 진행을 하고자하면 해당 events의 규칙을 비활성화하고

AWS CodePipeline 콘솔상에서 파이프라인을 선택 후 변경 사항 릴리스를 선택하면

 


CodeDeploy에서 Shell Script 실행 불가

 

현재 백엔드 프로세스가 포트 80으로 돌고 있음

일반 OS 사용자는 1024 이하 포트 접근에 Action이 제한되어 있음

그래서 쉘 스크립트 실행이 불가함

 

포트 80에서 8080으로 변경하였음


헬스체크 경로

 

/api/v1

/api/v1/healthcheck


ec2-user 로 배포했으나 root로 배포됨

 

appspec.yml

version: 0.0
os: linux

files:
  - source:  /
    destination: /solution
    overwrite: yes
    owner: user01
hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 300
      runas: user01
  ValidateService:
    - location: healthcheck.sh
      timeout: 60
      runas: user01
  • runas: root 로 지정하였더니 폴더 소유자가 root가 되어서 향후 user01이  /solution 접근에 대한 Action이 제한됨

/etc/fstab 자동 마운트 후 시작 템플릿 떴더니 /solution 폴더의 소유자가 root

 

  • ec2 user data로 소유자 권한 변경하였음.
  • 참고로 Init Script는 #!/bin/bash 앞에 붙여서 스크립트를 실행할 인터프리터를 지정해야 함

소스 코드를 aws kms 키로 암호화

경로: src/main/resources/application.properties

 

AWS KMS의 AWS 관리형 키

관리형 키는 사용자가 접근할 수 없어서 암호화 및 복호화가 불가했다.

 

 

AWS KMS의 고객 관리형 키

AWS CMK 키를 생성한다.

application.properties는 애플리케이션 설정 파일이다.
설정 파일에는 데이터베이스 설정, 서버 설정(포트, 컨텍스트 경로), 로깅 등 소스 코드가 참조할 내용들이 적혀있다.

새로 발급 받은 키를 활용해 application.properties 내용들을 암호화하였다.

 

키 관리자에 EC2 서버의 인스턴스 프로파일 Role을 추가해주면 EC2 서버가 해당 키로 암호화된 파일들을 복호화하여 

내용을 알아볼 수 있다.

 


인스턴스가 KMS 복호화 못하는 문제

 

 

deploy.sh

#!bin/bash
REPOSITORY=/solution
cd $REPOSITORY

echo $PWD
RESULT=$(ls -al)
echo $RESULT

JAR_NAME=$(ls $REPOSITORY | grep '.jar' | grep -v 'plain')

CURRENT_PID=$(pgrep -f $JAR_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
  echo "> kill -9 $CURRENT_PID"
  kill -9 $CURRENT_PID
  sleep 3
fi


echo "> $JAR_NAME 배포"
nohup java -jar -Dspring.profiles.active=dev $JAR_NAME > /dev/null 2> /dev/null < /dev/null &

 

옵션

-Dcom.amazonaws.sdk.disableEc2Metadata=true
AWS SDK의 EC2 인스턴스 메타데이터 서비스 접근 비활성화

현재 EC2 메타데이터를 끌고와 복호화를 진행


-Dspring.profiles.active=dev
Spring Boot 애플리케이션의 프로파일을 'dev' 로 설정
개발 환경에 맞는 설정이 적용됨

 

 


codepipeline 첫 배포시 6060 포트 돌고 있어야 함

 

수동으로 첫 CI/CD 배포 전에 블루 환경에 6060 포트로 프로세스가 실행되고 있어야 함.

그린 환경 구성 후 마지막으로 블루 환경 삭제하므로 기존 블루 환경은 임의로 지우지 말고 유지해야 함


일반 OS 사용자 권한으로 sudo 명령어 입력시 비밀번호 입력받아 실패시 스크립트 작동안함 문제

 

#!bin/bash
REPOSITORY=/solution
cd $REPOSITORY

echo $PWD
RESULT=$(ls -al)
echo $RESULT

JAR_NAME=$(ls $REPOSITORY | grep '.jar' | grep -v 'plain')

CURRENT_PID=$(pgrep -f $JAR_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
  echo "> kill -9 $CURRENT_PID"
  kill -9 $CURRENT_PID
  sleep 3
fi


echo "> $JAR_NAME 배포"
nohup java -jar -Dspring.profiles.active=dev $JAR_NAME > /dev/null 2> /dev/null < /dev/null &

echo "> sudo kill -9 $CURRENT_PID" 문제로 인해 sudo 명령어 실행시 비밀번호를 입력받아 스크립트가 제대로 작동되지 않았다.

sudo 명령어를 뺐더니 정상적으로 작동 되었음


 

S3에서 라우팅 못 하는 현상  (404 Not Found)


Frontend 개발중에는 vue-router를 통해 어떤 비즈니스 로직 api로 보낼지 라우팅이 되어있음

그리고 빌드 후에는 컴퓨터만 알아보는 index-123123.js 파일로 변환되어 뱉고, 이걸 통해서 프론트를 운영.

 

그런데 S3에서 라우팅할 때 기본적으로 모든 요청을 index.html으로 리다이렉트하지 않기 때문에

새로 고침시, vue-router가 알아보는 경로로 다이렉트로 요청하므로 경로를 알 수 없어 에러가 발생하였음

 

SPA 특성상 발생하는 문제로, 이 문제를 해결하려면 CloudFront를 통해 모든 요청을 index.html로 리다이렉트하도록 해야 함

CloudFront
S3
Redirect HTTP to HTTPS

Lambda@Edge
- CloudFront에서 요청을 가로채서 index.html로 리다이렉트하는 데 설정