You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AmazonS3를 생성할 때 Region과 Credentials 를 설정해둔 것을 볼 수 있습니다.
여기서 Credentials는 암호화된 버킷에 접근하기 위한 accessKey, secretKey 등을 의미합니다. 그런데 accessKey, secretKey 등을 직접 전달하지 않고, new EC2ContainerCredentialsProviderWrapper()를 건네주었습니다.
이는 EC2에 credentials 를 저장해놓고 사용하는 방식입니다. Application이 EC2에서 구동될 때 EC2에 저장된 credentials 정보를 찾아서 로드합니다.
CloudFront 는 OAI(Origin Access Identity) 기능을 지원합니다.
OAI란 CloudFront 가 Private 한 S3에 접근할 수 있도록 하는 특별한 식별자입니다. OAI 설정을 통해 CloudFront가 버킷에 접근할 수 있다고 이해하시면 됩니다.
CloudFront가 OAI 설정으로 버킷에 접근할 수 있다면 저희는 CloudFront를 통해 객체에 접근할 수 있게 됩니다.
CloudFront 생성
AWS CloudFront 에서 배포 생성으로 CloudFront 를 생성할 수 있습니다.
CloudFront 생성 시 Origin 을 설정합니다.
원본(Origin) 도메인이 S3 도메인이 됩니다.
그리고 OAI 설정을 합니다. 버킷 정책 업데이트도 설정합니다.
참고
현재 OAI는 Legacy 라고 합니다. OAC가 새로 나왔고, AWS 에서 이를 권장한다고 합니다.
OAC 가 더 광범위한 기능을 제공하기 때문입니다.
You can limit the access to your origin to only authenticated requests from CloudFront. We recommend using origin access control (OAC) in favor of origin access identity (OAI) for its wider range of features, including support of S3 buckets in all AWS Regions.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
S3를 어떻게 적용했는지 하나씩 설명드리겠습니다.
들어가기
용어 정리
객체(Object) : 파일과 파일정보로 구성된 저장단위입니다. 간단하게 파일이라고 생각하면 됩니다.
버킷(Bucket) : 객체를 관리하는 컨테이너입니다. 이곳에 객체를 저장합니다.
S3에 이미지 파일을 저장한다는 것은 “버킷에 객체를 저장한다”와 같은 말입니다.
S3 서비스를 사용하기 위해서는 우선 버킷을 만들어야 합니다.
버킷 만들기
버킷은 Amazon S3에 접속해서
버킷 만들기
버튼을 클릭해서 생성할 수 있습니다.버킷을 만들면서 다양한 설정을 할 수 있습니다.
우선 버킷 이름과 AWS 리전을 설정할 수 있습니다.
버킷 이름은 중복이 허용되지 않습니다.
객체에 대한 소유권을 제어할 수 있습니다. 이 설정은 저희 팀프로젝트에서는 사용할 일이 없으므로 깊게 알지 않아도 괜찮습니다.
버킷의 퍼블릭 액세스 차단에 대한 설정을 할 수 있습니다. 버킷을 퍼블릭하게 열어두면 누구나 버킷 및 객체에 접근할 수 있게 됩니다. 따라서 보안을 위해
모든 퍼블릭 액세스 차단
을 설정하는 것이 일반적입니다.저희 프로젝트에서는
모든 퍼블릭 액세스 차단
한 버킷을 사용하게 됩니다.버킷에 암호를 설정할 수 있습니다.
버킷을 직접 생성해보는 실습을 하고 싶으시다면 아래의 블로그 글을 추천드립니다.
https://gaeggu.tistory.com/33
버킷 사용하기
저희는 우아한테크코스 측에서 제공 받은 버킷을 사용하게 됩니다. 따라서 버킷을 직접 생성할 필요없이 바로 사용하면 됩니다.
다만, 버킷에 객체를 업로드하려면 credentials 정보가 필요합니다.
또한 위에서 잠깐 언급한대로 버킷의 권한을 살펴보면
퍼블릭 액세스 차단
설정이 활성화 된 것을 확인할 수 있습니다.따라서 버킷에 있는 객체에 접근하기 위해서는 추가적인 처리가 필요합니다.
어떻게 하면 버킷에 객체를 업로드하고, 객체를 조회할 수 있을지 하나씩 살펴보겠습니다.
객체 업로드
애플리케이션에서 S3 버킷에 객체를 업로드 하기 위해 코드를 작성하겠습니다.
AWS 는 Java 에서 사용할 수 있는 SDK 를 제공합니다.
의존성 추가
우선 spring-cloud-starter-aws 에 대한 의존성을 추가해주어야 합니다.
build.gradle에 코드를 추가했습니다.
implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4'
참고
여러 블로그 자료를 살펴보면 의존성 추가 코드가 위와 다릅니다.
대부분 아래와 같이 org.springframework.cloud 에서 제공하는 spring-cloud-starter-aws 을 사용합니다.
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
하지만 org.springframework.cloud 이 제공하는 spring-cloud-starter-aws 는 최신 버전의 배포 날짜가 2021년 2월입니다.
기록을 보면 한 해에도 여러 번에 걸쳐 업데이트 하던 기간이 있었으나, 더이상 새로운 버전을 출시하지 않는 것으로 보입니다.
업데이트가 이뤄지지 않는 의존성을 사용하는 것이 꺼림칙했습니다. 인텔리제이도 경고를 합니다.
찾아보니, io.awspring.cloud 도 동일하게 spring-cloud-starter-aws 를 제공했고,
꾸준히 버전을 업데이트 하고 있었습니다.
두 spring-cloud-starter-aws 를 모두 사용해보았을 때 동일한 동작을 하는 것을 확인할 수 있었습니다.
둘 중 계속해서 업데이트가 이뤄지는 io.awspring.cloud 의 spring-cloud-starter-aws 를 사용하는 것이 낫다고 판단했습니다.
https://mvnrepository.com/search?q=spring-cloud-starter-aws
S3 config
AmazonS3 는 S3 API 를 위한 java SDK 입니다.
AmazonS3를 Bean 으로 등록해 사용할 것입니다.
AmazonS3를 생성할 때 Region과 Credentials 를 설정해둔 것을 볼 수 있습니다.
여기서 Credentials는 암호화된 버킷에 접근하기 위한 accessKey, secretKey 등을 의미합니다. 그런데 accessKey, secretKey 등을 직접 전달하지 않고,
new EC2ContainerCredentialsProviderWrapper()
를 건네주었습니다.이는 EC2에 credentials 를 저장해놓고 사용하는 방식입니다. Application이 EC2에서 구동될 때 EC2에 저장된 credentials 정보를 찾아서 로드합니다.
EC2에 어떻게 credentials 를 저장할 수 있을까요?
그것은 EC2에게 S3에 관한 IAM 역할을 부여함으로써 가능합니다.
구체적인 방법은 공식 문서에서 살펴보실 수 있습니다.
https://repost.aws/knowledge-center/ec2-instance-access-s3-bucket
한편, 저희는 AWS 내에서 IAM을 직접 생성하는 등의 작업 권한이 없습니다. 따라서 우아한테크코스 코치님께 문의를 해보았습니다.
ec2-aws-service 권한을 사용하면 된다고 하네요!
따라서 dev, prod 각각 IAM 역할을 수정해줍니다.
EC2 에 접속해 AWS configure 정보를 확인해보다면, access_key, secret_key 정보가 있는 것을 확인할 수 있습니다.
application.yml
추가적으로 application.yml 파일을 설정합니다.
cloud.aws.stack.auto : false
false
등록합니다.cloud.aws.credentials.instanceProfile: true
instanceProfile
를 사용한다는 의미입니다.AmazonS3로 객체 업로드하는 코드
업로드 코드는 매우 간단합니다.
AmazonS3 를 Bean 으로 등록해두었으니, 생성자에서 의존성을 주입 받아 사용할 수 있습니다.
application.yml 파일에 적어두었던 버킷 이름도 @value로 불러와 사용합니다.
putObject() 메서드로 객체를 업로드할 수 있습니다.
메서드의 인자로 버킷 이름, 파일 이름을 포함한 저장 경로, 파일 inputStream, 객체 메타데이터를 입력하면 됩니다.
getUrl() 메서드로 객체의 Url을 얻을 수 있습니다.
메서드의 인자로 버킷 이름과 파일 이름을 포함한 저장 경로를 입력하면 됩니다.
객체 조회
코드를 통해 객체를 업로드하고 URL 도 받아올 수 있으니, 모든 설정이 끝난 것 같지만 아닙니다.
getUrl() 메서드가 반환하는 값은 다음과 같은 형태를 띕니다.
이 Url 에 직접 접근하면 이미지를 볼 수 있을 것이라 기대하지만, 거부됩니다.
이유는 버킷이
퍼블릭 액세스 차단
상태이기 때문입니다. Public 환경에서 버킷 내부의 객체 URL에 직접 접근할 수 없습니다.객체에 접근하기 위해서는 특정 대상에게 접근 권한을 열어주고 그 대상을 통해 우회하는 방식을 사용해야 합니다.
이때 특정 대상이란 CloudFront 가 될 수 있습니다.
CloudFront 를 통한 우회
CloudFront 는 AWS의 CDN(Content Delivery Network or Content Distribution Network) 입니다.
자세한 내용은 다음 블로그에 잘 정리되어 있습니다.
[https://inpa.tistory.com/entry/AWS-📚-CloudFront-개념-원리-사용-세팅-💯-정리#cloudfront_삭제](https://inpa.tistory.com/entry/AWS-%F0%9F%93%9A-CloudFront-%EA%B0%9C%EB%85%90-%EC%9B%90%EB%A6%AC-%EC%82%AC%EC%9A%A9-%EC%84%B8%ED%8C%85-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC#cloudfront_%EC%82%AD%EC%A0%9C)
CloudFront 는 OAI(Origin Access Identity) 기능을 지원합니다.
OAI란 CloudFront 가 Private 한 S3에 접근할 수 있도록 하는 특별한 식별자입니다. OAI 설정을 통해 CloudFront가 버킷에 접근할 수 있다고 이해하시면 됩니다.
CloudFront가 OAI 설정으로 버킷에 접근할 수 있다면 저희는 CloudFront를 통해 객체에 접근할 수 있게 됩니다.
CloudFront 생성
AWS CloudFront 에서
배포 생성
으로 CloudFront 를 생성할 수 있습니다.CloudFront 생성 시 Origin 을 설정합니다.
원본(Origin) 도메인이 S3 도메인이 됩니다.
그리고 OAI 설정을 합니다. 버킷 정책 업데이트도 설정합니다.
참고
현재 OAI는 Legacy 라고 합니다. OAC가 새로 나왔고, AWS 에서 이를 권장한다고 합니다.
OAC 가 더 광범위한 기능을 제공하기 때문입니다.
Amazon CloudFront, 오리진 액세스 제어(OAC) 시작
OAI, OAC 어떤 것을 사용해도 상관없습니다. 다만 프로젝트 설정 시에는 OAI를 사용했으니 참고 바랍니다.
버킷 정책 업데이트
OAI 를 설정한 CloudFront 를 배포하게 되면, S3 정책을 업데이트 해야 합니다. 자동 업데이트를 설정해두면 AWS 가 바로 설정을 바꾸어 줍니다.
이전과 달리 버킷 정책에 내용이 추가된 것을 볼 수 있습니다.
앞으로 CloudFront를 통한 접근에는 S3 Resource 에 GetObject (객체 조회) 등의 Action 이 허용됩니다.
OAI에 읽기 액세스 권한을 부여하는 Amazon S3 버킷 정책 예시는 다음과 같습니다.
CloudFront 로 객체 접근
배포된 CloudFront 의 도메인으로 이제 객체에 접근할 수 있습니다.
기존에 AccessDenied 되었던 URL에서 Origin domain 을 CloudFront domain 으로 변경합니다.
이제 사진이 정상적으로 보입니다!
CloudFront CNAME(대체 도메인) 설정
CloudFront 를 통해 S3 객체에 접근이 가능하게 되었습니다.
그러나 CloudFront 의 도메인이 서비스에 바로 사용하기에는 적합하지 않습니다.
대체 도메인 이름(CNAME) 을 설정해두면 보다 서비스하기 좋은 도메인으로 CloudFront를 사용할 수 있습니다.
마무리
S3 인프라 설정과 사용 방법에 대해 간단하게 보았습니다.
그림으로 전체 구조를 살펴본다면 다음과 같습니다.
Beta Was this translation helpful? Give feedback.
All reactions