현재 개발중인 서비스에서 이미지를 업로드하는 기능을 구현하기로 했고, 업로드된 파일은 AWS의 S3 버킷에 업로드하기로 결정했다.
아래 단계로 진행한다.
1. S3의 버킷을 생성하고 정책을 설정한 후
2. S3 버킷에 접근할 수 있는 IAM 사용자를 생성하고,
3. Spring Boot에서 S3 관련 의존성과 사용자 정보(access key, secret key)를 추가한다.
4. 업로드, 수정, 삭제하는 기능을 구현한다.
이번 글에서는 3번까지 진행하는 과정을 적어보려한다.
1. s3 버킷 생성
이 단계에서 주의하여 체크할 것은 세가지이다.
1. ACL (액세스 제어 목록) 을 활성화시켜준다.
2. 퍼블릭 엑세스 차단을 해제한다.
3. 권한 > 정책 설정
버킷을 생성하고 나면, 버킷의 권한에 들어가서 두가지를 바꿔준다.
1. 버킷의 정책을 설정한다. (JSON 형태로 아래 코드를 붙인다.)
이를 통해 해당 버킷의 객체에 접근할 수 있도록 한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::{버킷명}/*"
}
]
}
2. ACL을 편집하여 "모든 사람(퍼블릭 액세스)"이 접근할 수 있도록 한다.
해당 2번 작업을 해주지 않으면 추후에 Spring Boot에서 S3 버킷에 접근할 시, 아래와 같은 에러를 만날 것이다.
버킷 소유자 외의 사용자가 접근할 수 없다는 에러이다.
ERROR : The bucket does not allow ACLs
com.amazonaws.services.s3.model.AmazonS3Exception: The bucket does not allow ACLs
(Service: Amazon S3; Status Code: 400; Error Code: AccessControlListNotSupported;
2. AWS IAM 사용자 생성
위에서 언급했듯, S3에 접근하는 권한을 가지는 사용자를 생성해줘야 접근이 가능하다. 아래 순서로 진행된다.
1. 사용자 이름 생성
2. AWS 자격 증명 유형 - "액세스 키 – 프로그래밍 방식 액세스" 선택
3. 권한 설정 - "기존 정책 직접 연결" 선택 - "AmazonS3FullAccess" 조회 후 선택
생성 후에 access key와 secret key를 제공하는데, 해당 key는 application.yml 파일에 사용자 정보로 입력할 것이니 잘 적어놔야한다.
ERROR : The request signature we calculated does not match the signature you provided
해당 에러는 아래 3번 단계에서 생성한 사용자를 설정 정보에 넣은 후 서버를 구동하니 발생했다. 사용자의 키가 일치하지 않는다는 것이다.
아래 사이트 중 두번째 사이트를 보고 믿고싶지 않은 원인이라 생각하며 구글링을 계속 했지만 secret key 에 있는 /, %, + 문자와 같은 것이 escape 문자로 간주되면서 변형이 생기는 것이 원인이라는 의견이 대부분이었다.
결국 바보같지만 사용자를 생성하고, 또 생성하며 secret key에 위와 같은 문자가 없이 생성될 때까지 반복했다.
(그래도 희망을 가지고 아래 단계까지 실행한 후 에러가 발생하면 여기로 다시 오길 바란다..)
참고할 만한 사이트
- https://stackoverflow.com/questions/30518899/amazon-s3-how-to-fix-the-request-signature-we-calculated-does-not-match-the-s
- https://lynlab.co.kr/blog/52
- https://docs.aws.amazon.com/ko_kr/general/latest/gr/signature-v4-troubleshooting.html 중 <키 서명 오류 해결>
3. Spring Boot에서 S3 관련 의존성과 사용자 정보(access key, secret key) 추가
1. 의존성을 추가한다.
- spring-cloud-starter-aws
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
- aws-java-sdk-s3
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000') implementation 'com.amazonaws:aws-java-sdk-s3'
두가지 모두 가능하다. 본인은 결국 첫 번째 라이브러리를 추가했지만, 두번째 라이브러리 빌드 시 설치하는 갯수가 더 적어서 효율적일 것이다. (sdk의 s3 관련된 라이브러리만 추가하는 것이니)
2. application.yml (혹은 application.properties) 파일에 s3 버킷에 접근 가능한 사용자 정보와 s3 관련 설정을 추가한다.
cloud:
aws:
s3:
bucket: {버킷명}
region:
static: {버킷 리전}
stack:
auto: false
credentials:
accessKey: {자신의 accessKey}
secretKey: {자신의 secretKey}
cloud.aws.stack.auto를 false로 해주는 이유는
프로젝트 배포시 디폴트로 CloudFormation 구성을 시작하기 때문에 따로 설정한 CloudFormation이 없으면 프로젝트 실행이 되지 않는다. 그러므로 해당 기능을 사용하지 않도록 false로 설정해야 한다.
CloudFormation이 뭔가?
CloudFormation은 JSON 형식으로 작성된 템플릿 파일을 바탕으로 AWS 리소스(VPC, EC2 인스턴스 등)를 자동으로 구축하는 서비스이다. 이렇게 생성된 것을 stack이라 부른다.
본인은 stack 생성에 필요한 설정 정보(템플릿 작성, 정책 설정 등등)를 따로 설정하지 않았으므로 에러가 발생하는 것이다.
그러므로 자동으로 생성되는 것을 막기 위해서 cloud.aws.stack.auto를 false로 설정해야 한다.
이제 4번.업로드, 수정, 삭제하는 기능을 구현하기 시작하면 된다.
이후 시간이 된다면 게시글을 올릴 예정이다.
깨달은 점
- Spring Boot에서 AWS 서비스를 이용하기 위해 라이브러리를 설치하는 과정, 접근 사용자를 생성하는 과정 등 모두 어렵지 않게 진행할 수 있어 편리성을 느꼈다.
- IAM 사용자의 secret key 불일치 에러와 같은 문제는 좀더 자세한 에러 설명이 있으면 좋을 것 같다는 생각이 들었다.
'백엔드 개발하며 작성한 > Spring' 카테고리의 다른 글
Spring MVC Request Lifecycle (0) | 2022.02.16 |
---|---|
단위 테스트 코드 작성 (JUnit5) (1) | 2022.02.14 |
ResponseEntity 사용법 (0) | 2022.01.02 |
JAP Query로 특정 칼럼의 count 쿼리문 실행하기 (0) | 2021.11.12 |
[Spring Boot 프로젝트] AWS EC2로 Spring Boot 배포 (0) | 2021.10.16 |