티스토리 뷰

AWS

S3(Simple Storage Service)의 부가 기능

RyanGomdoriPooh 2016. 9. 1. 18:29

앞에 글에서는 AWS S3의 핵심 기능과 어떤 방식으로 돌아가고 있는지에 대한 핵심기능에 대해서 이야기해보았습니다.


이번 글에서는 그 핵심기능을 뒷받침하는 기능을 설명하려고 합니다. 그 종류에 대해서는 접근제한, S3관리, 암호화 같은 것이 있습니다.



11.3.4 HTTP Referer로 S3 접근 제한하기


S3에 올리진 그림 파일을 원하는 도메인에서만 보여줄 수 있도록 설정해보겠습니다.


S3는 서비스를 요청해서 응답하는 것에 대한 데이터 전송량에 대해서 과금을 하는 구조이기 때문에 원치 않는 곳에서 접근하는 요청 트래픽을 막으면 그만큼 비용을 절감할 수 있습니다.


HTTP Referer는 HTTP 헤더값으로서 웹 브라우저에서 생성하는 데이터입니다.

즉, 웹 브라우저에서 요청을 보내거나 할때 해당하는 헤더값에 정보를 담아서 보내는 형태입니다.


예를 들면, http://applebanana.info 에 현재 페이지를 보고 있는 사용자가 현재 페이지 내에서 보여지는 링크주소 http://hello.com을 클릭해서 접속하거나, 페이지 내에 보여지는 이미지를 보여줄때, http://hello.com으로 보내는 HTTP 헤더의 Referer 값은 http://applebanana.info가 됩니다.

즉, 어디서 링크를 클릭했는지 그림파일을 어디서 제공하는 지에 대해서 알 수 있습니다.


S3에서는 이 Referer 값을 판단해서 파일을 보여줄지 말지 결정할 수 있습니다.


이번에는 버킷을 두개를 만들어서 1) 이미지를 제공하는 저장전용버킷 2) 정적웹사이트호스팅 설정을 한 버킷


두 개를 만들어서 정적웹사이트호스팅 설정 버킷에 이미지가 있는 곳에 대한 링크를 만들어서 테스트를 해보겠습니다.


|정적 웹사이트 호스팅 버킷| ===> |링크 및 이미지 저장용 버킷|


제가 보일 예시에서는


정적웹사이트호스팅버킷명 : staticwebsitehosting1

링크 및 이미지 저장용 버킷명 : seouls3bucket


으로 하겠습니다. 이제부터 예시를 들어보겠습니다.


seouls3bucket 클릭=>Properties=>Permission=>Edit bucket policy또는 Add bucket policy=> 모든 유저에게 접근허용하지만 Referer를 설정해서 해당 링크에서만 접근할 수 있도록 설정=> Save



바로 위의 설정 소스를 텍스트로 가져온 것입니다. JSON형식으로 된 이 변수들에 대해서 설명하겠습니다.


"Effect": 해당 버킷으로 들어오는 트래픽에 대한 정책을 결정할 때, 허용하여 트래픽을 관리하는 정책이면 Allow, 어떤 트래픽에 대해서 거부하는 정책이면 Deny를 해줍니다.


"Principal": 정책을 적용할 대상입니다. 언터넷에 웹으로 접근하는 모든 사용자들에게 허용할 것이기 때문에 대상은 와일드카드인 "*"를 사용합니다.


"Action": 어떤 Action에 대해서 허용할 것인지 정하는 부분입니다. 여기서는 S3에게 Object들을 가져올 수 있는 Get 함수를 허용할 것이기 때문에 해당하는 ACtion을 써준 것입니다.


"Resource": 버킷과 같은 리소스들이 들어있는 곳의 경로를 입력합니다. 여기서는 seouls3bucket에 대해서 모두 접근을 허용할 것이기 때문에 arn:aws:s3:::seouls3bucket/* 와 같이 표현을 입력했습니다.


"Condition": 조건절로 해당하는 정책이 이 조건에 맞아야 Allow 또는 Deny를 하게됩니다.


"StringLike": 조건절 안에 사용하는 조건문입니다. 뜻은 해당 문자열을 포함하고 있을때 라는 뜻입니다.


"awsReferer": Referer 값을 지정합니다. 보통 도메인을 설정하고 맨뒤에 /*를 붙여주어서 도메인 이하 모든 경로에 대해서 허용한다는 뜻으로 입력하게됩니다. http://staticwebsitehosting1.s3-website-ap-northeast-2.amazonaws.com/* 이 URI를 보면 해당하는 도메인에서 접근하는 모든 HTTP 헤더 안에 Referer이 맞으면 모두 접근을 허용합니다.

혹시 여러도메인을 접근 허용하는 조건으로 넣으려면 ,(콤마)로 구분하면 됩니다. 또한 *를 사용해서 와일드카드를 사용할 필요없이 해당 파일의 경로를 직접 설정해도 됩니다.


{

"Version": "2012-10-17",

"Id": "Policy1472714638777",

"Statement": [

{

"Sid": "Stmt1472714635225",

"Effect": "Allow",

"Principal": "*",

"Action": "s3:GetObject",

"Resource": "arn:aws:s3:::seouls3bucket/*",

"Condition": {

"StringLike": {

"aws:Referer": "http://staticwebsitehosting1.s3-website.ap-northeast-2.amazonaws.com/*"

}

}

}

]

}


이제 접근을 할 이미지 저장 역할을 하는 버킷의 설정은 마무리가 되었기 때문에 정적 웹 사이트 호스팅 버킷에서 접근이 가능한지 테스팅을 해보겠습니다.


해당 이미지 저장용 버킷에 들어가서 해당하는 리소스 object(여기서는 이미지파일)을 선택한 후, Permissions 탭을 클릭하고 들어가 Grantee가 Everything으로 설정된 것이 없는지 확인합니다.

왜냐하면 Grantee가 Everyting으로 설정된 권한이 설정되어 있으면 Referer 설정을 모두 무시하게되므로 주의해야합니다.


따라서 Everything으로 권한 설정이 추가되어 있지 않은 이미지파일을 선택한 뒤, Properties=>Permission 으로 접근을 합니다.

그리고 Grantee가 Everything으로 되어있지 않은 것을 선택한 후, Link에 있는 파란색으로 되어있는 링크URI를 눌러봅니다.



링크를 누르게 되면 다음과 같은 화면이 나타납니다. 아까 설정해놓은 Referer 때문에 접근이 거부당하는 것입니다.


그럼 이제 해결해야하는 부분은 어떻게 저 이미지 파일로 접근을 할 수 있는 가에 대해서 고민해봐야합니다.

답은 과정 속에 있었습니다.


두가지 버킷이 있었는 데, 하나는 다른 웹사이트 링크에서 요청이 오면 이미지를 전달해서 보내주는 역할이고,

다른 하나는 링크가 담긴 페이지 자체를 보여주는 웹사이트 호스팅을 하는 역할을 합니다.


그런데 Referer로 전달해줘야하는 이미지에 정책을 적용해놨는데 그 정책은 웹사이트 호스팅을 하는 링크가 담긴 페이지에서 요청을 해야 이미지를 보여주게끔 설정을 해놨기 때문에 해당 웹사이트 호스팅 링크가 담긴 html 파일을 통해 구성이 되는 웹사이트에서 접근을 해야한다라고 생각하시면 됩니다.


그러면 이제 index.html이라는 파일을 정적 웹사이트 호스팅을 하는 버킷에 올려서 Referer에서 허용한 URI로 이미지에 접근을 해보겠습니다.


index.html 안의 소스는 다음과 같습니다.

<html>

<head>

<title>S3 Example Website Hosting</title>

</head>

<body>

<p>Example HTTP Referer</p>

<!--img 테그를 추가해서 이미지 링크를 추가해줍니다.-->

<img src="https://s3.ap-northeast-2.amazonaws.com/seouls3bucket/gallery0_2016-03-10-10-58-53.png" 

width="320" height="240">

</body>

</html>


해당 index.html이 실행이 되면, 정적 웹사이트 호스팅 버킷 안에 index.html이 있기 때문에, 위에서 이미지 저장용 버킷에 정책으로 설정했던, Referer의 값인 정적 웹사이트 호스팅 버킷의 URI로 헤더의 값을 전달하기 때문에 접근이 가능해집니다.

그리고 여기서 정적 웹사이트 호스팅의 URI인 staticwebsitehosting1.s3-website.ap-northeast-2.amazonaws.com 를 접속하게 되면 index.html을 실행시키게 되고,
index.html은 HTTP 헤더의 Referer 값을 staticwebsitehosting1.s3-website.ap-northeast-2.amazonaws.com 로 전달해서 이미지 저장용 버킷의 정책으로 설정한 Referer 도메인이 일치하게 되어서 접근 권한을 갖게되어 정상적으로 이미지가 출력이 됩니다.



11.3.5 S3 객체 스토리지 클래스, 암호화 설정하기


S3 Object를 1) 어떤 스토리지에 저장할지 2)저장할 때의 암호화 여부 를 설정할 수 있습니다.


S3 버킷에 들어가서 object(파일) 클릭=>Properties=>Details 으로 들어갑니다.


위의 그림을 설명 해보겠습니다.

- Storage Class : 여기에 들어오면 스토리지의 특징에 따라서 다른 서비스입니다.

1) Standard 는 데이터 손실 가능성이 거의 없는 스토리지입니다. 내구성이 높다라고 표현합니다. 내구성-99.999999999%

2) Standard - Infrequent Access 는 Standard인데 접근이 자주있지 않은 경우에 사용하는 옵션입니다.

3) Reduced Redundancy 는 적은 양의 일부 데이터 손실 가능성이 있어도 상관이 없는 경우 대신 비용을 저렴하게 해주는 스토리지입니다. 내구성-99.99%


- Server Side Encryption : None과 AES-256를 선택할 수 있습니다. S3에 데이터를 암호화해서 저장하는 옵션입니다.

중요한 데이터를 보다 암호화해서 안전하게 저장하고 싶을 때 사용합니다.

또한 저장할때 암호화되는 데이터의 복호화는 데이터를 가져올 때 이루어집니다.



11.3.6 S3 Object(객체) 메타데이터 설정하기


S3 Object는 실제 파일과 파일에 대한 메타데이터로 구성되어있습니다.


S3 객체에 다양한 기능을 하는 메타데이터를 설정할 수 있습니다.


메타데이터는 1) HTTP 1.1 표준에 정의된 메타데이터 2) S3 전용 메타데이터 로 구성됩니다.


S3 객체 목록=>파일을 선택=>Properities=>Metadata

빨간색 영역 표시 중에서 Metadata 안에 들어가 있는 Key-Value의 종류에 대해서 설정하겠습니다.


S3 객체에 HTTP Header를 설정할 수 있습니다.


지금부터 설명할 6가지 Key-Value에 대한 설명은 HTTP 1.1에 의해 정의된 헤더 값에 대한 설명입니다.


1) Cache-Control : 브라우저 캐시 정책을 설정할 수 있습니다. Value에 max-age=3600과 같은 식으로 데이터의 만기 시간을 초 단위로 지정할 수 있습니다.

만기 시간이 지나기 전에 다시 요청하는 경우에 브라우저에서는 서버에서 데이터를 가져오지 않고 이미 요청해서 받았던 데이터를 사용합니다.

이 설정은 나중에 CDN(Content Delivery Network) 서비스인 CloudFront와도 연계됩니다.

Cache-Control에 대한 내용은 내용이 많아서 인터넷을 참고로 하는 것이 좋습니다.


2) Content-Disposition : Value에 Attachment로 설정을 하면 JPG 파일 같은 경우, 웹브라우저에서 그림 파일을 보여주지 않고 바로 다운로드 합니다.

그림 파일뿐만 아니라 다른 형식의 파일에도 지정해서 보여주지않고 바로 다운로드되게 만들 수 있습니다.


3) Content-Type : 웹 브라우저에서 파일을 어떻게 처리해야하는 지 알려주는 메타데이터입니다.

보통 확장자에 따라서 S3에서 자동으로 설정합니다. 확장자가 없는 파일은 이 메타데이터를 통해서 강제로 형식을 지정해줄 수 있습니다.

예를 들면, HTML 내용을 담고 있지만 확장자가 없는 apple이라는 파일을 올리고, 웹 브라우저에서 열면 내용이 보이지 않고 바로 다운로드가 됩니다.

그래서 apple이라는 파일의 Content-Type을 text/html로 설정해주면 웹브라우저에서 HTML 파일로 인식해서 보여주게됩니다.


4) Content-Language : 텍스트로 된 파일(HTML과 같은 등등)의 언어가 무엇인지 지정할 수 잇습니다. en, ko, jp 또는 en-us, ko-kr, ja-jp 처럼 지정할 수 있습니다.


5) Expires : Cache-Control과 같은 동작을 하지만, 초 단위가 아니고 특정한 날짜와 시간을 지정해서 만기 시간을 설정합니다.

Tue, 22 Apr 2014 20:00:00 GMT 와 같은 형식으로 지정해야 합니다.


6) Content-Encoding : 데이터 인코딩 방식입니다. Value에 gzip을 지정하면, 데이터를 압축해서 전송하고, 웹브라우저에서 다시 압축을 해제해서 데이터를 사용합니다.

데이터가 크고 용량이 큰 경우 이 메타데이터로 설정을 하면 데이터 전송비용을 절약할 수 있습니다.

데이터의 특성에 따라 압축이 이미된 포맷을 가지고 있는 JPG, PNG와 같은 그림파일들은 압축이 되어있기 때문에 용량이 많이 줄어들지 않습니다.

그래서 그림파일에는 압축을 설정하지 않는 것이 좋습니다.

gzip을 가장 많이 사용하고 deflate도 지정할 수 있습니다.


이렇게 HTTP 1.1에 의해 정의된 헤더 값에 대한 설명은 끝이고 이어서 S3 전용 메타데이터에 대해서 설명하겠습니다.


지금부터 설명할 3가지 Key-Value에 대한 설명은 S3에서 전용으로 정의한 메타데이터입니다.


1) Website Redirect Location : 웹 브라우저로 해당 파일에 접속했을 때 다른 파일이나 URL로 리다이렉션이 가능한 기능입니다.

예를 들어, 처음 정적 웹 사이트 호스팅 설정을 한 버킷의 URI로 접속을 했을때, 처음 index.html로 접속이되어서, value값으로 예를 들면 /hello.html로 경로를 설정해두면 해당 파일로 리다이렉션을 시켜주고,

만약 다른 링크를 http://ww.applebanana.info 로 해두면 다른 외부 도메인으로 연결이 되기도 합니다.

이 설정은 버킷을 정적 웹사이트 호스팅으로 설정하고 S3 Website Endpoint로 접속해야 동작을 합니다.


2) 사용자 정의 메타데이터 : 사용자가 마음대로 추가적인 설명을 넣어서 사용할 수 있는 부분입니다.

key값으로 x-amz-meta- 가 나오는데 key 뒤에 원하는 내용을 넣어서 사용하면 됩니다. 

예를 들면, x-amz-meta-user-id로 붙여서 사용해도되고 value 값에는 아무 내용을 넣어도 됩니다.

여기서는 영문으로 넣으셔야합니다. 웹에서 다른 설정없이 한글을 쓰시는 경우에는 오류가 발생한 여지가 많습니다.


3) S3 시스템 정의 메타데이터 : 일부 S3 세부 설정들을 이 메타데이터로 대신할 수 있습니다. 그리고 S3 콘솔에서 설정한 세부 설정들은 HTTP Response Header에 아래 키로 표현됩니다.

여기서는 S3에서 설정한 값들을 알아서 자동으로 메타데이터를 만들어서 보냅니다. S3에서 설정한 값들을 HTTP Response Header를 통해서 확인할 수 있습니다.


여기서 S3에서 설정을 하면 자동으로 메타데이터에 반영시켜 사용하는 메타데이터를 HTTP Response Header에서 몇가지 보이겠습니다.


3-1) x-amz-server-side-encryption : 데이터 암호화 옵션 값입니다. Properties의 Detail에서 Server Side Encryption 설정에서 할 수 있고 설정을 하면 AES256을 값으로 가집니다. 제가 쓴 S3 글 중에서 몇번 나온적이 있는 설정입니다.


3-2) x-amz-version-id : S3 버킷에 버저닝 기능을 켰을때, 파일의 버전을 표시하는 값입니다. (사용자가 편집할 수 없는 메타데이터에 속합니다.)


3-3) x-amz-delete-marker : S3 버킷에 버저닝 기능을 켜고, 파일을 삭제하면 파일이 완전히 삭제되지 않고 삭제 표시 설정이 됩니다. 그 삭제 표시 여부에 대한 값입니다. true 값을 가지게 됩니다. (사용자가 편집할 수 없는 메타데이터에 속합니다.)


3-4) x-amz-storage-class : 스토리지 클래스 옵션입니다. Properities의 Details에서 스토리지 클래스(Storage Class) 설정을 대신할 수 있으며 STANDARD와 REDUCED_REDUNDANCY 라는 두가지 스토리지 옵션 값을 가집니다.


다음표는 S3용 메타데이터입니다.

그리고 다음 링크에 가시면 더 많은 메타데이터에 관련한 내용을 보실 수 있습니다.

https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/dev/UsingMetadata.html



11.3.7 S3 버킷 로그 설정하기


S3에 저장된 객체의 접속한 기록에 대한 로그를 텍스트 파일 형태로 저장할 수 있습니다.

이제 버킷의 Properities를 설정하는 것에 익숙해졌을 것입니다.


로그 설정하는 순서에 대해서 설명하겠습니다.

버킷 클릭=>Properities=>Logging=>Enabled 체크=>Target Bucket 설정=>Target Prefix는 S3내에 로그를 저장할 폴더를 설정=>Save


이렇게 S3 log설정을 끝마쳤습니다.


이제 log파일이 정상적으로 생성이 되는지에 대해서 확인해보아야합니다.

해당 버킷으로 파일을 URI로 접근하여서 로그가 쌓이게끔 시도를 해줍니다. 그리고 10~20분 정도 기다리면 log라는 폴더안에 접근했던 log에 대한 내용들이 text 문서로 저장되어있는 것을 볼 수 있습니다.




11.3.8 S3 Bucket Versioning 설정하기

S3는 자체적으로 파일 버전 관리(Version Control) 기능을 내장하고 있습니다. 이 Versioning 기능을 활용하면 파일을 이전 내용으로 되돌릴 수도 있고, 삭제한 파일도 복원할 수 있습니다.

단, 그 앞뒤 파일의 내용을 저장해두기 때문에 저장 용량이 더 늘어나서 사용 요금이 늘어나긴 합니다.

따라서 용량이 작은 파일이 대부분일 때 사용하는 것을 추천합니다.


설정하는 순서는 다음과 같습니다.

해당 Versioning 기능을 사용할 Bucket 클릭=>Properities=>Versioning=>Enable Versioning클릭


그런데 여기서 Versioning을 사용하는 데에 있어서 주의할 점이 필요합니다.


Versioning 기능을 한 번 사용하게 되면 다시는 이 기능을 끌 수 없습니다. 


Versioning 기능을 활성화한 뒤 S3 객체 목록에서 위쪽에 보시면 Version: Hide Show 라는 버튼이 생긴 것을 볼 수 있는데 Show를 누르면 버전별로 관리되어지는 파일 목록을 볼 수 있습니다.


한번 사용을 시작하는 Enable Versioning 을 누르게 되면 Suspend Versioning인 일시 중지만 가능하지 취소를 하는 방법은 Bucket을 없애는 방법밖에 없다.


또한, Versioning 기능을 사용하고 있으면 S3 bucket의 Lifecycle 기능을 사용할 수 없게 됩니다.


Versioning 기능을 활성화한 뒤 S3 Object 목록dptj Versions의 Show 버튼을 클릭하면 파일들을 버전이 표시됩니다. 단, 파일이 수정되어서 버전이 바뀌었을 때 표시되는 것입니다.


이 Versioning 정보들은 여기서는 test.txt 파일 밑에 최신 버전이 바로 밑에 표시됩니다.


그렇게 구버젼이 밑으로 밀려내려가게되고 최신버전의 Versioning 파일을 선택해서 오른쪽 클릭을 해서 Delete하게되면 그 바로 밑에 있던 최신파일 바로 전 파일 버전으로 바뀌게 됩니다.

쉽게 이야기하면 파일이 바뀔때마다 그 파일의 버전을 관리해서 복원시킬 수 있게 저장해놓는 것이 Versioning 입니다.



11.3.9 S3 bucket lifecycle 설정하기


S3는 버킷에 저장된 객체들의 수명 주기를 설정해서 관리할 수 있는 기능이 있습니다.


이 기능은 일정 시간이 지났을 때 사용되지 않는 파일들을 삭제하거나 다른 곳에 백업하여 S3 저장 공간을 절약하고 확보하기 위한 것입니다.


S3 bucket 목록에서 설정할 버킷 클릭=>Properities=>Lifecycle=>Add rule 클릭



그리고 버킷 안에 저장될 모든 Object에 대해서 rule을 설정합니다.


총 Step 1~3으로 나뉘는데


- Step 1 Choose Rule Target : 일단 해당 버킷 전체에 이 Rule을 작동하게 할지, 아니면 어떤 폴더만 그렇게 적용할 지에 대해서 정하는 부분입니다.

정하였으면 Configure Rule을 눌러서 넘어갑니다.


- Step 2 Configure Rule : 이 부분에서는 진짜 룰을 설정하는 부분입니다. 간단하게 설명하자면 1) 몇일동안 Object 데이터를 보관할 것인지 2) 이전 버전은 몇일동안 보관할 것인지 3) 완전하지 않은 업로그 파일을 지우는 기간

이렇게 3가지 정도로 말할 수 있습니다. 룰을 하나라도 설정하지 않으면 다음으로 진행되지 않습니다.

룰을 정했으면 우측 하단에 Review라는 버튼을 클릭합니다.


- Step 3 Review and Name : 이제 그동안 정리한 룰의 Target과 룰의 설정을 끝내고 룰을 어떻게 부를 것인지에 대한 이름만 설정하면 됩니다. 굳이 설정을 하지 않아도 되지만 룰을 구별하기 위해서 설정해줍니다.

그리고 마지막으로 우측하단에 있는 Create and Activate Rule 을 클릭해줍니다.


다음과 같이 룰이 만들어진 것을 볼 수 있습니다.

룰의 수정이나 삭제를 원하시는 경우, 해당 룰에 오른쪽 끝편에 펜표시와 X표시를 눌러서 수정 및 삭제를 하시면 됩니다.

여기서 가장 중요한 이야기를 제가 빼고 했습니다. 여기서 가장 중요한 것은 앞서 설명 드렸던 Versioning 기능을 사용하면서는 이 Lifecycle 기능을 사용할 수 없다는 것입니다.

Versioning 기능을 사용하려면 모든 Lifecycle 룰을 삭제한 후에 사용하실 수 있습니다.


왜냐하면 Versioning이라는 기능 자체가 이전 버전들을 백업한 상태에서 그 백업한 파일들을 가지고 버전별로 나눠서 제공해주는 기능인데,

Lifecycle이라는 기능은 그 백업파일을 지우는 주기를 설정하는 기능이기 때문에 서로 상충되는 기능이기 때문입니다.



* 추가로 설정할 수 있는 기능 중에서 Tags라는 기능이 있습니다.

Tags라는 기능은 버킷에 태그를 설정해서 AWS의 Cost Allocation Reports에서 S3의 비용내역을 볼 수 있는데 이 보고서에서 여기서 설정한 태그별로 집계된 사용 내역과 비용을 표시해줍니다. 즉, Tag에서 설정된 이름이 기준이 되어서 버킷을 나타내어 준다고 보면 됩니다.


* 추가로 설정할 수 있는 기능 중에서 Requester Pays 라는 기능이 있습니다.

기본적으로 S3 버킷 소유자는 2가지로 과금을 받습니다. 하나는 1) 버킷 공간을 얼마나 쓰고 있는지 2) 데이터 전송량이 얼마나 되는지 에 따라서 과금을 받는데 이 설정을 통해서 버킷 소유자는 사용 공간에 대해서만 요금을 지불하고, 데이터 전송량에 따른 요금은 데이터를 다운로드한 사용자가 지불하는 형태입니다.

이 설정을 사용하면 버킷에 대한 익명 접근은 모두 차단되고, 서로 계약적인 관계에 있는 상방에게 과금을 하는 설정입니다.

보통 앱서비스에서는 일방적으로 제공을 해주는 것이기 때문에 사용하지 않습니다.



지금까지 S3의 부가기능을 살펴봤습니다.


다음 시간부터는 전 세계에 콘텐츠를 빠르고 효율적으로 배포하고 관리하기 위한 CDN 서비스인 CloudFront를 사용하는 방법에 대해서 설명하겠습니다.


*Reference

1. 아마존 웹 서비스를 다루는 기술 - 이재홍 - 이분의 책은 AWS의 바이블이라고 생각됩니다. 구매해서 보시는 것을 추천합니다.


댓글
댓글쓰기 폼
공지사항
Total
533,954
Today
42
Yesterday
176
링크
TAG
more
«   2022/05   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
글 보관함