Storage > Object Storage > Amazon S3 호환 API 가이드

NHN Cloud 오브젝트 스토리지는 AWS의 오브젝트 스토리지 S3 API와 호환되는 API를 제공합니다. 따라서 Amazon S3 API를 사용하도록 개발된 애플리케이션을 설정만 변경하여 그대로 사용할 수 있습니다.

제공하는 Amazon S3 호환 API는 다음과 같습니다.

S3 API 메서드 용도
PUT Bucket 버킷 생성
HEAD Bucket 버킷 정보 조회
DELETE Bucket 버킷 삭제
PUT Bucket Object Lock 잠금 버킷 생성
PUT Object Lock Configuration 잠금 버킷 보관 기간 설정
GET Object Lock Configuration 잠금 버킷 보관 기간 조회
PUT Bucket ACL 버킷 ACL 설정
GET Bucket ACL 버킷 ACL 조회
GET Bucket Location 버킷이 있는 리전 조회
GET Bucket List Objects 버킷의 오브젝트 목록 조회
GET Object 오브젝트 다운로드
HEAD Object 오브젝트 정보 조회
PUT Object 오브젝트 업로드
PUT Object Copy 오브젝트 복사
DELETE Object 오브젝트 삭제
Initiate Multipart Upload 멀티파트 업로드 초기화
Upload Part 파트 업로드
Upload Part Copy 파트 복사
Complete Multipart Upload 멀티파트 업로드 완료
Abort Multipart Upload 멀티파트 업로드 중단
List Parts 멀티파트 오브젝트의 파트 오브젝트 리스트
List Multipart Uploads 업로드 진행 중인 멀티파트 오브젝트의 파트 오브젝트 리스트
DELETE Multiple Objects 2개 이상의 오브젝트 삭제

이 문서는 기본적인 API 사용 방법만 설명합니다. 고급 기능을 사용하려면 Amazon S3 API 가이드를 참고하거나, AWS SDK 사용을 권장합니다.

S3 API 자격 증명(S3 API Credential)

오브젝트 스토리지는 Amazon S3 호환 API 호출 시 인증/인가에 S3 API 자격 증명을 사용합니다. S3 API 자격 증명은 NHN Cloud에서 Amazon S3 호환 API를 지원하는 서비스 API를 사용하기 위한 AWS EC2 형식의 인증 키입니다. S3 API 자격 증명에 관한 자세한 내용은 S3 API 자격 증명을 참고합니다.

버킷(Bucket)

버킷 생성

버킷을 생성합니다. 버킷 이름은 다음과 같은 Amazon S3의 명명 규칙을 따라야 합니다.

  • 버킷 이름은 3자에서 63자 사이여야 합니다.
  • 버킷 이름은 소문자, 숫자, 점(.) 및 하이픈(-)으로만 구성될 수 있습니다.
  • 버킷 이름은 문자 또는 숫자로 시작하고 끝나야 합니다.
  • 버킷 이름은 IP 주소 형식(예: 192.168.5.4)을 사용하지 않습니다.
  • 버킷 이름은 xn--으로 시작할 수 없습니다.

자세한 내용은 Bucket restrictions and limitations 문서를 참고합니다.

PUT /{bucket}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

알아두기

콘솔 또는 오브젝트 스토리지 API로 생성한 컨테이너의 이름이 버킷 명명 규칙에 위배되면 S3 호환 API로는 접근할 수 없습니다.

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 200을 반환합니다.

이름 종류 형식 설명
Location Header String 생성한 버킷 경로

버킷 목록 조회

버킷 목록을 조회합니다.

GET /

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

요청이 올바르면 상태 코드 200과 XML 형식으로 구성된 버킷 목록을 반환합니다.

예시
<?xml version='1.0' encoding='UTF-8'?>
<ListAllMyBucketsResult
    xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Owner>
        <ID>user:panther</ID>
        <DisplayName>user:panther</DisplayName>
    </Owner>
    <Buckets>
        <Bucket>
            <Name>log</Name>
            <CreationDate>2009-02-03T16:45:09.000Z</CreationDate>
        </Bucket>
        <Bucket>
            <Name>snapshot</Name>
            <CreationDate>2009-02-03T16:45:09.000Z</CreationDate>
        </Bucket>
    </Buckets>
</ListAllMyBucketsResult>

버킷 조회

지정한 버킷의 정보와 내부에 저장된 오브젝트 목록을 조회합니다.

GET /{bucket}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

알아두기

콘솔 또는 오브젝트 스토리지 API를 사용하여 생성한 컨테이너의 이름이 버킷 명명 규칙에 위배되면 S3 호환 API로는 접근할 수 없습니다.

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

요청이 올바르면 상태 코드 200과 XML 형식으로 구성된 오브젝트 목록을 반환합니다.

예시
<?xml version='1.0' encoding='UTF-8'?>
<ListBucketResult
    xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>snapshot</Name>
    <Prefix/>
    <Marker/>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>false</IsTruncated>
    <Contents>
        <Key>cheetah</Key>
        <LastModified>2023-02-01T04:49:52.995Z</LastModified>
        <ETag>"7d793037a0760186574b0282f2f435e7"</ETag>
        <Size>5</Size>
        <Owner>
            <ID>user:panther</ID>
            <DisplayName>user:panther</DisplayName>
        </Owner>
        <StorageClass>STANDARD</StorageClass>
    </Contents>
    <Contents>
        <Key>leopard</Key>
        <LastModified>2023-02-01T04:49:52.685Z</LastModified>
        <ETag>"5d41402abc4b2a76b9719d911017c592"</ETag>
        <Size>5</Size>
        <Owner>
            <ID>user:panther</ID>
            <DisplayName>user:panther</DisplayName>
        </Owner>
        <StorageClass>STANDARD</StorageClass>
    </Contents>
</ListBucketResult>

버킷 삭제

지정한 버킷을 삭제합니다. 삭제할 버킷은 비어 있어야 합니다.

DELETE /{bucket}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 204를 반환합니다.

잠금 버킷 생성

오브젝트 잠금이 활성화된 버킷을 생성합니다. 버킷을 생성할 때 x-amz-bucket-object-lock-enabled 헤더를 true로 설정합니다. 기본 보관 기간은 0일로 설정됩니다.

PUT /{bucket}

x-amz-bucket-object-lock-enabled: true
Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
x-amz-bucket-object-lock-enabled Header Boolean Y 오브젝트 잠금 활성화 여부(true)
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 200을 반환합니다.

이름 종류 형식 설명
Location Header String 생성한 버킷 경로

잠금 버킷 보관 기간 설정

잠금 버킷의 기본 보관 기간을 설정합니다.

PUT /{bucket}?object-lock

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

요청 본문에 JSON 형식의 오브젝트 잠금 설정을 포함해야 합니다.

이름 종류 형식 필수 설명
ObjectLockEnabled Body String Y 오브젝트 잠금 활성화 상태. Enabled만 허용
Rule Body Object N 기본 보관 규칙
Rule.DefaultRetention Body Object Conditional 기본 보관 기간 설정. Rule 설정 시 필수
Rule.DefaultRetention.Mode Body String Conditional 보관 모드. COMPLIANCE만 허용
Rule.DefaultRetention.Days Body Integer Conditional 보관 기간(일). 양의 정수. Days 또는 Years 중 하나 필수
Rule.DefaultRetention.Years Body Integer Conditional 보관 기간(년). 양의 정수. Days 또는 Years 중 하나 필수

알아두기

Rule을 생략하면 기본 보관 기간이 0일로 설정됩니다. Years로 설정하더라도 조회 시에는 항상 Days로 변환하여 반환합니다.

예시
{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
        "DefaultRetention": {
            "Mode": "COMPLIANCE",
            "Days": 1
        }
    }
}

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 200을 반환합니다.

잠금 버킷 보관 기간 조회

잠금 버킷의 오브젝트 잠금 설정을 조회합니다.

GET /{bucket}?object-lock

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

요청이 올바르면 상태 코드 200과 JSON 형식의 오브젝트 잠금 설정을 반환합니다.

이름 종류 형식 설명
ObjectLockEnabled Body String 오브젝트 잠금 활성화 상태
Rule Body Object 기본 보관 규칙
Rule.DefaultRetention Body Object 기본 보관 기간 설정
Rule.DefaultRetention.Mode Body String 보관 모드
Rule.DefaultRetention.Days Body Integer 보관 기간(일)

알아두기

Years로 설정한 보관 기간도 조회 시에는 Days로 변환하여 반환합니다.

예시
{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
        "DefaultRetention": {
            "Mode": "COMPLIANCE",
            "Days": 1
        }
    }
}

오브젝트

오브젝트 업로드

지정한 버킷에 오브젝트를 업로드합니다.

PUT /{bucket}/{obj}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
obj URL String Y 오브젝트 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 200을 반환합니다.

이름 종류 형식 설명
ETag Header String 오브젝트의 MD5 해시 값
Last-Modified Header String 오브젝트의 마지막 수정 일시(e.g. Wed, 01 Mar 2006 12:00:00 GMT)

오브젝트 다운로드

오브젝트를 다운로드합니다.

GET /{bucket}/{obj}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
obj URL String Y 오브젝트 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

요청이 올바르면 상태 코드 200을 반환합니다.

이름 종류 형식 설명
Last-Modified Header String 오브젝트의 마지막 수정 일시(e.g. Wed, 01 Mar 2006 12:00:00 GMT)
ETag Header String 오브젝트의 MD5 해시 값

오브젝트 삭제

지정한 오브젝트를 삭제합니다.

DELETE /{bucket}/{obj}

Date: Sat, 22 Feb 2020 22:22:22 +0000
Authorization: AWS {access}:{signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
obj URL String Y 오브젝트 이름
Date Header String Y 요청 시각
Authorization Header String Y S3 API 자격 증명 접근 키와 서명으로 구성

응답

이 API는 응답 본문을 반환하지 않습니다. 요청이 올바르면 상태 코드 204를 반환합니다.

서명된 URL 생성

AWS Signature Version 4(SigV4) 서명을 쿼리 파라미터에 담아, 인증 토큰(Authorization 헤더) 없이 일정 시간 동안 오브젝트에 접근할 수 있는 URL입니다. 다운로드는 GET, 업로드는 PUT으로 요청합니다.

서명된 URL 형식

GET /{bucket}/{obj}
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential={access}%2F{date}%2F{region}%2Fs3%2Faws4_request
&X-Amz-Date={date}
&X-Amz-Expires={seconds}
&X-Amz-SignedHeaders=host
&X-Amz-Signature={signature}

요청

이 API는 요청 본문을 요구하지 않습니다.

이름 종류 형식 필수 설명
bucket URL String Y 버킷 이름
obj URL String Y 오브젝트 이름
X-Amz-Algorithm Query String Y 서명 알고리즘. AWS4-HMAC-SHA256으로 설정
X-Amz-Credential Query String Y 접근 키와 서명 scope. {access}/{date}/{region}/s3/aws4_request 형식(/는 %2F로 인코딩)
X-Amz-Date Query String Y 서명 시각. ISO 8601 yyyyMMddTHHmmssZ(UTC)
X-Amz-Expires Query String Y 유효 기간(초). 최소 1, 최대 604800(7일)
X-Amz-SignedHeaders Query String Y 서명에 포함한 헤더 목록. 최소 host 포함
X-Amz-Signature Query String Y 요청을 인증하는 HMAC 서명 값

응답

요청이 올바르면 상태 코드 200을 반환합니다.

알아두기

Swift TempURL 방식과 언어별 직접 서명 예시 등 자세한 내용은 서명된 URL 가이드를 참고합니다.

AWS 명령줄 인터페이스(CLI)

S3 호환 API를 사용하여 AWS 명령줄 인터페이스로 NHN Cloud 오브젝트 스토리지를 사용할 수 있습니다.

설치

Installing past releases of the AWS CLI version 2 문서를 참조해 AWS 명령줄 인터페이스를 설치합니다.

알아두기

NHN Cloud 오브젝트 스토리지는 AWS CLI 버전 2.34.38까지 지원합니다.

설정

AWS 명령줄 인터페이스를 사용하려면 먼저 S3 API 자격 증명과 환경을 설정해야 합니다.

$ aws configure
AWS Access Key ID [None]: {access}
AWS Secret Access Key [None]: {secret}
Default region name [None]: {region name}
Default output format [None]: json
이름 설명
access S3 API 자격 증명 접근 키
secret S3 API 자격 증명 비밀 키
region name KR1 - 한국(판교) 리전
KR2 - 한국(평촌) 리전

S3 명령 사용 방법

aws --endpoint-url={endpoint} s3 {command} s3://{bucket}
이름 설명
endpoint https://kr1-api-object-storage.gov-nhncloudservice.com - 한국(판교) 리전
https://kr2-api-object-storage.gov-nhncloudservice.com - 한국(평촌) 리전
command AWS 명령줄 인터페이스 명령
bucket 버킷 이름

알아두기

AWS 명령줄 인터페이스는 기본적으로 AWS 도메인을 사용하도록 설정된 도구입니다. 따라서 NHN Cloud 오브젝트 스토리지를 사용하려면 반드시 매 명령마다 엔드포인트를 지정해야 합니다. AWS 명령줄 인터페이스 명령은 AWS CLI에서 상위 수준(s3) 명령 사용 문서를 참고합니다.

버킷 생성
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 mb s3://example-bucket
make_bucket: example-bucket
버킷 목록 조회
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 ls
2020-07-13 10:07:13 example-bucket
버킷 조회
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 ls s3://example-bucket
2020-07-13 10:08:49     104389 0428b9e3e419d4fb7aedffde984ba5b3.jpg
2020-07-13 10:09:09      74448 6dd6d48eef889a5dab5495267944bdc6.jpg
버킷 삭제
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 rb s3://example-bucket
remove_bucket: example-bucket
잠금 버킷 잠금 버킷은 aws s3api 하위 명령으로 관리합니다.
create-bucket 명령에 --object-lock-enabled-for-bucket 옵션을 사용하면 오브젝트 잠금이 활성화된 버킷을 생성합니다. 기본 보관 기간은 0일로 설정됩니다.
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3api create-bucket \
  --bucket example-bucket \
  --object-lock-enabled-for-bucket
기본 보관 기간을 설정하려면 put-object-lock-configuration 명령을 사용합니다.
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3api put-object-lock-configuration \
    --bucket example-bucket \
    --object-lock-configuration '{
        "ObjectLockEnabled": "Enabled",
        "Rule": {
            "DefaultRetention": {
                "Mode": "COMPLIANCE",
                "Days": 1
            }
        }
    }'
잠금 설정을 조회하려면 get-object-lock-configuration 명령을 사용합니다.
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3api get-object-lock-configuration --bucket example-bucket
{
    "ObjectLockConfiguration": {
        "ObjectLockEnabled": "Enabled",
        "Rule": {
            "DefaultRetention": {
                "Mode": "COMPLIANCE",
                "Days": 1
            }
        }
    }
}
오브젝트 업로드
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 cp ./3b5ab489edffdea7bf4d914e3e9b8240.jpg s3://example-bucket/3b5ab489edffdea7bf4d914e3e9b8240.jpg
upload: ./3b5ab489edffdea7bf4d914e3e9b8240.jpg to s3://example-bucket/3b5ab489edffdea7bf4d914e3e9b8240.jpg
!!! tip "알아두기" 오브젝트의 용량이 8MB 이상이면 AWS 명령줄 인터페이스는 오브젝트를 여러 개의 파트로 나누어 업로드합니다. 파트 오브젝트는 {bucket}+segments라는 버킷에 {object-name}/{upload-id}/{part-number} 형태의 이름으로 저장되고, 모든 파트 업로드가 끝나면 업로드 요청한 버킷에 파트 오브젝트를 연결한 오브젝트가 만들어집니다. 파트 오브젝트가 저장되는 {bucket}+segments 버킷은 S3 호환 API로는 접근할 수 없고, Object Storage API 또는 콘솔을 통해 접근할 수 있습니다. 멀티파트 오브젝트의 ETag는 각 파트 오브젝트의 ETag 값을 이진 데이터로 변환하고 순서대로 연결해(concatenate) MD5 해시한 값입니다. !!! danger "주의" 멀티파트로 업로드한 오브젝트의 일부 또는 전체 파트 오브젝트를 삭제하면 오브젝트에 접근할 수 없습니다.
오브젝트 다운로드
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 cp s3://example-bucket/3b5ab489edffdea7bf4d914e3e9b8240.jpg ./3b5ab489edffdea7bf4d914e3e9b8240.jpg
download: s3://example-bucket/0428b9e3e419d4fb7aedffde984ba5b3.jpg to ./0428b9e3e419d4fb7aedffde984ba5b3.jpg
오브젝트 삭제
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 rm s3://example-bucket/3b5ab489edffdea7bf4d914e3e9b8240.jpg
delete: s3://example-bucket/3b5ab489edffdea7bf4d914e3e9b8240.jpg
서명된 URL 생성
$ aws --endpoint-url=https://kr1-api-object-storage.gov-nhncloudservice.com s3 presign s3://example-bucket/0428b9e3e419d4fb7aedffde984ba5b3.jpg --expires-in 3600
https://kr1-api-object-storage.gov-nhncloudservice.com/example-bucket/0428b9e3e419d4fb7aedffde984ba5b3.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=...&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=...

도메인 스타일 엔드포인트 사용

S3 호환 API는 버킷 접근 방식으로 경로 스타일(Path-style)과 도메인 스타일(Virtual Hosted-style)을 모두 지원합니다. 도메인 스타일은 버킷 이름을 엔드포인트의 서브 도메인으로 사용합니다.

방식 형식
경로 스타일(Path-style) https://{endpoint}/{bucket}/{object}
도메인 스타일(Virtual Hosted-style) https://{bucket}.{endpoint}/{object}


AWS 명령줄 인터페이스에서 도메인 스타일 엔드포인트를 사용하려면 addressing_style 옵션을 virtual로 설정합니다. 이 설정을 적용하면 AWS 명령줄 인터페이스가 엔드포인트와 버킷 이름을 조합해 자동으로 도메인 스타일 URL로 요청을 보냅니다.

$ aws configure set default.s3.addressing_style virtual

또는 ~/.aws/config 파일에서 사용 중인 프로필 섹션에 다음 설정을 추가합니다.

[default]
s3 =
  addressing_style = virtual
이름 설명
addressing_style virtual - 도메인 스타일 사용
path - 경로 스타일 사용
auto - 자동 선택(기본값, NHN Cloud Object Storage처럼 커스텀 엔드포인트를 사용하면 경로 스타일로 동작)

주의

버킷 이름에 점(.)이 포함되어 있으면 도메인 스타일 사용 시 와일드카드 SSL 인증서의 유효 범위를 벗어나 인증서 검증에 실패할 수 있습니다. 이때는 경로 스타일을 사용하세요.

AWS SDK

AWS는 여러 가지 프로그래밍 언어를 위한 SDK를 제공하고 있습니다. S3 호환 API를 사용하여 AWS SDK로 NHN Cloud 오브젝트 스토리지를 사용할 수 있습니다.

알아두기

자세한 내용은 AWS SDK 문서를 참고합니다.

AWS SDK를 사용하기 위해 필요한 주요 파라미터는 다음과 같습니다.

이름 설명
access S3 API 자격 증명 접근 키
secret S3 API 자격 증명 비밀 키
region name KR1 - 한국(판교) 리전
KR2 - 한국(평촌) 리전
endpoint https://kr1-api-object-storage.gov-nhncloudservice.com - 한국(판교) 리전
https://kr2-api-object-storage.gov-nhncloudservice.com - 한국(평촌) 리전

Boto3 - Python SDK

알아두기

자세한 내용은 AWS SDK for Python(Boto3) 설명서 문서를 참고합니다.

Context

Boto3 클라이언트 클래스
# boto3example.py
from boto3 import client
from boto3.s3.transfer import TransferConfig
from botocore.exceptions import ClientError


class Boto3Example(object):
    _REGION = '{region name}'
    _ENDPOINT = '{endpoint}'
    _ACCESS = '{access}'
    _SECRET = '{secret}'

    def __init__(self):
        self.s3 = client(service_name='s3',
                         region_name=self._REGION,
                         endpoint_url=self._ENDPOINT,
                         aws_access_key_id=self._ACCESS,
                         aws_secret_access_key=self._SECRET)
버킷 생성
def create_bucket(self, bucket_name):
    try:
        return self.s3.create_bucket(Bucket=bucket_name)
    except ClientError as e:
        raise RuntimeError(e)
버킷 목록 조회
def list_buckets(self):
    try:
        return self.s3.list_buckets().get('Buckets')
    except ClientError as e:
        raise RuntimeError(e)
버킷 조회(오브젝트 목록 조회)
def list_objs(self, bucket_name):
    try:
        return self.s3.list_objects_v2(Bucket=bucket_name).get('Contents')
    except ClientError as e:
        raise RuntimeError(e)
버킷 삭제
def delete_bucket(self, bucket_name):
    try:
        return self.s3.delete_bucket(Bucket=bucket_name)
    except ClientError as e:
        raise RuntimeError(e)
잠금 버킷 create_bucket 메서드에 ObjectLockEnabledForBucket=True를 설정하면 잠금 버킷을 생성합니다. 기본 보관 기간은 0일로 설정됩니다.
def create_bucket_with_lock(self, bucket_name):
    try:
        return self.s3.create_bucket(
            Bucket=bucket_name,
            ObjectLockEnabledForBucket=True
        )
    except ClientError as e:
        raise RuntimeError(e)
기본 보관 기간을 설정하려면 put_object_lock_configuration 메서드를 사용합니다.
def put_object_lock_configuration(self, bucket_name, days):
    lock_configuration = {
        'ObjectLockEnabled': 'Enabled',
        'Rule': {
            'DefaultRetention': {
                'Mode': 'COMPLIANCE',
                'Days': days
            }
        }
    }
    try:
        return self.s3.put_object_lock_configuration(
            Bucket=bucket_name,
            ObjectLockConfiguration=lock_configuration
        )
    except ClientError as e:
        raise RuntimeError(e)
잠금 설정을 조회하려면 get_object_lock_configuration 메서드를 사용합니다.
def get_object_lock_configuration(self, bucket_name):
    try:
        return self.s3.get_object_lock_configuration(
            Bucket=bucket_name
        )
    except ClientError as e:
        raise RuntimeError(e)
오브젝트 업로드 !!! tip "알아두기" 파트 오브젝트의 개수는 업로드할 오브젝트의 용량과 설정한 파트 크기에 따라 결정됩니다. 기본 파트 크기는 8MiB이고, 최소 5MiB부터 지정할 수 있습니다. 파트 오브젝트의 최대 개수는 10,000개입니다.
def upload(self, bucket_name, key, filename, part_size):
    config = TransferConfig(multipart_chunksize=part_size)
    try:
        self.s3.upload_file(Filename=filename,
                            Bucket=bucket_name,
                            Key=key,
                            Config=config)
    except ClientError as e:
        raise RuntimeError(e)
오브젝트 다운로드
def download(self, bucket_name, key, filename):
    try:
        response = self.s3.get_object(Bucket=bucket_name, Key=key)

        with io.FileIO(filename, 'w') as fd:
            for chunk in response['Body']:
                fd.write(chunk)

        response.pop('Body')
    except ClientError as e:
        raise RuntimeError(e)
    except OSError as e:
        raise RuntimeError(e)

    return response
오브젝트 삭제
def delete(self, bucket_name, key):
    try:
        return self.s3.delete_object(Bucket=bucket_name, Key=key)
    except ClientError as e:
        raise RuntimeError(e)
서명된 URL 생성
def generate_presigned_url(self, bucket_name, key, expires_in):
    try:
        # 업로드용은 'put_object'
        return self.s3.generate_presigned_url(
            'get_object',
            Params={'Bucket': bucket_name, 'Key': key},
            ExpiresIn=expires_in)
    except ClientError as e:
        raise RuntimeError(e)

Java SDK

알아두기

자세한 내용은 AWS SDK for Java 설명서 문서를 참고합니다.

Context

Java SDK 클라이언트 클래스
// AwsSdkExample.java
public class AwsSdkExample {
    private static final String access = "{access}";
    private static final String secret = "{secret}";
    private static final String region = "{region name}";
    private static final String endpoint = "{endpoint}";

    private AmazonS3 s3Client;

    public AwsSdkExample() {
        BasicAWSCredentials awsCredentials =
            new BasicAWSCredentials(access, secret);
        s3Client = AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(endpoint, region)
            )
            .withCredentials(
                new AWSStaticCredentialsProvider(awsCredentials)
            )
            .enablePathStyleAccess()
            .disableChunkedEncoding()
            .build();
    }
}
버킷 생성
public String createBucket(String bucketName) throws RuntimeException {
    try {
        return s3Client.createBucket(bucketName).toString();
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
버킷 목록 조회
public List<Bucket> listBuckets() throws RuntimeException {
    try {
        return s3Client.listBuckets();
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
버킷 조회(오브젝트 목록 조회)
public ListObjectsV2Result listObjects(
    String bucketName
) throws RuntimeException {
    try {
        return s3Client.listObjectsV2(bucketName);
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
버킷 삭제
public void deleteBucket(String bucketName) throws RuntimeException {
    try {
        s3Client.deleteBucket(bucketName);
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
잠금 버킷 CreateBucketRequest에 withObjectLockEnabledForBucket(true)를 설정하면 잠금 버킷을 생성합니다. 기본 보관 기간은 0일로 설정됩니다.
public String createBucketWithLock(String bucketName) throws RuntimeException {
    try {
        CreateBucketRequest request = new CreateBucketRequest(bucketName)
            .withObjectLockEnabledForBucket(true);
        return s3Client.createBucket(request).toString();
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
기본 보관 기간을 설정하려면 setObjectLockConfiguration 메서드를 사용합니다.
public void putObjectLockConfiguration(
    String bucketName, int days
) throws RuntimeException {
    try {
        DefaultRetention retention = new DefaultRetention()
            .withMode(ObjectLockRetentionMode.COMPLIANCE)
            .withDays(days);
        ObjectLockRule rule = new ObjectLockRule()
            .withDefaultRetention(retention);
        ObjectLockConfiguration configuration = new ObjectLockConfiguration()
            .withObjectLockEnabled(ObjectLockEnabled.ENABLED)
            .withRule(rule);
        SetObjectLockConfigurationRequest request =
            new SetObjectLockConfigurationRequest()
                .withBucketName(bucketName)
                .withObjectLockConfiguration(configuration);
        s3Client.setObjectLockConfiguration(request);
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
잠금 설정을 조회하려면 getObjectLockConfiguration 메서드를 사용합니다.
public ObjectLockConfiguration getObjectLockConfiguration(
    String bucketName
) throws RuntimeException {
    try {
        GetObjectLockConfigurationRequest request =
            new GetObjectLockConfigurationRequest()
                .withBucketName(bucketName);
        return s3Client.getObjectLockConfiguration(request)
            .getObjectLockConfiguration();
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
오브젝트 업로드 !!! tip "알아두기" 파트 오브젝트의 개수는 업로드할 오브젝트의 용량과 설정한 파트 크기에 따라 결정됩니다. 기본 파트 크기는 5MiB이고, 최소 5MiB부터 지정할 수 있습니다. 파트 오브젝트의 최대 개수는 10,000개입니다.
public void uploadObject(String bucketName, String objectKey, String filePath, long partSize) {
    TransferManager tm = TransferManagerBuilder.standard()
        .withS3Client(s3Client)
        .withMinimumUploadPartSize(partSize)
        .build();
    Upload upload = tm.upload(bucketName, objectKey, new File(filePath));

    try {
        upload.waitForCompletion();
    } catch (AmazonServiceException e) {
        upload.abort();
    } catch (AmazonClientException e) {
        upload.abort();
    } catch (InterruptedException e) {
        upload.abort();
    }
}
오브젝트 다운로드
public String downloadObject(
    String bucketName, String objKeyName, String filePath
) throws RuntimeException {
    try {
        return s3Client.getObject(
            new GetObjectRequest(bucketName, objKeyName),
            new File(filePath)
        ).getETag();
    } catch (NoSuchKeyException e) {
        throw new RuntimeException(e);
    } catch (InvalidObjectStateException e) {
        throw new RuntimeException(e);
    } catch (S3Exception e) {
        throw new RuntimeException(e);
    } catch (AwsServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
오브젝트 삭제
public void deleteObject(
    String bucketName, String objKeyName
) throws RuntimeException {
    try {
        s3Client.deleteObject(bucketName, objKeyName);
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}
서명된 URL 생성
public String generatePresignedUrl(
    String bucketName, String objKeyName, long expirationMillis
) throws RuntimeException {
    try {
        Date expiration = new Date(System.currentTimeMillis() + expirationMillis);
        GeneratePresignedUrlRequest request =
            new GeneratePresignedUrlRequest(bucketName, objKeyName)
                .withMethod(HttpMethod.GET)          // 업로드용은 HttpMethod.PUT
                .withExpiration(expiration);
        return s3Client.generatePresignedUrl(request).toString();
    } catch (AmazonServiceException e) {
        throw new RuntimeException(e);
    } catch (SdkClientException e) {
        throw new RuntimeException(e);
    }
}

.NET SDK

알아두기

자세한 내용은 AWS SDK for .NET 설명서 문서를 참고합니다.

Context

.NET SDK 클라이언트 클래스
class S3SDKExample
{
    private static string endpoint = "{endpoint}";
    private static string regionName = "{region name}";
    private static string accessKey = "{access}";
    private static string secretKey = "{secret}";

    private static AmazonS3Client GetS3Client()
    {
        var amazonS3Config =
            new AmazonS3Config
            {
                ServiceURL = endpoint,
                AuthenticationRegion = regionName,
                ForcePathStyle = true,
            };
        var basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);

        return new AmazonS3Client(basicAWSCredentials, amazonS3Config);
    }
}
버킷 생성
static async Task<PutBucketResponse> CreateBucketAsync(
    AmazonS3Client s3Client,
    string bucketName)
{
    try
    {
        if (!(await AmazonS3Util.DoesS3BucketExistAsync(s3Client, bucketName)))
        {
            var putBucketRequest =
                new PutBucketRequest
                {
                    BucketName = bucketName,
                    UseClientRegion = true
                };

            return await s3Client.PutBucketAsync(putBucketRequest);
        }
        throw new Exception("Bucket already exist.");
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
버킷 목록 조회
static async Task<ListBucketsResponse> ListBucketsAsync(AmazonS3Client s3Client)
{
    try
    {
        return await s3Client.ListBucketsAsync();
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
버킷 조회(오브젝트 목록 조회)
static async Task<List<ListObjectsV2Response>> ListBucketContentsAsync(
    AmazonS3Client s3Client,
    string bucketName)
{
    try
    {
        List<ListObjectsV2Response> responses =
            new List<ListObjectsV2Response>();
        var request =
            new ListObjectsV2Request
            {
                BucketName = bucketName,
                MaxKeys = 5,
            };
        var response = new ListObjectsV2Response();

        do
        {
            responses.Add(await s3Client.ListObjectsV2Async(request));
            request.ContinuationToken = response.NextContinuationToken;
        }
        while (response.IsTruncated);

        return responses;
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
버킷 삭제
static async Task<DeleteBucketResponse> DeleteBucketAsync(
    AmazonS3Client s3Client,
    string bucketName)
{
    try
    {
        return await s3Client.DeleteBucketAsync(
            new DeleteBucketRequest
            {
                BucketName = bucketName
            });
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
잠금 버킷 PutBucketRequest에 ObjectLockEnabledForBucket = true를 설정하면 잠금 버킷을 생성합니다. 기본 보관 기간은 0일로 설정됩니다.
static async Task<PutBucketResponse> CreateBucketWithLockAsync(
    AmazonS3Client s3Client,
    string bucketName)
{
    try
    {
        var putBucketRequest =
            new PutBucketRequest
            {
                BucketName = bucketName,
                UseClientRegion = true,
                ObjectLockEnabledForBucket = true
            };

        return await s3Client.PutBucketAsync(putBucketRequest);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
기본 보관 기간을 설정하려면 PutObjectLockConfigurationAsync 메서드를 사용합니다.
static async Task<PutObjectLockConfigurationResponse> PutObjectLockConfigurationAsync(
    AmazonS3Client s3Client,
    string bucketName,
    int days)
{
    try
    {
        var request =
            new PutObjectLockConfigurationRequest
            {
                BucketName = bucketName,
                ObjectLockConfiguration =
                    new ObjectLockConfiguration
                    {
                        ObjectLockEnabled = ObjectLockEnabled.Enabled,
                        Rule =
                            new ObjectLockRule
                            {
                                DefaultRetention =
                                    new DefaultRetention
                                    {
                                        Mode = ObjectLockRetentionMode.Compliance,
                                        Days = days
                                    }
                            }
                    }
            };

        return await s3Client.PutObjectLockConfigurationAsync(request);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
잠금 설정을 조회하려면 GetObjectLockConfigurationAsync 메서드를 사용합니다.
static async Task<GetObjectLockConfigurationResponse> GetObjectLockConfigurationAsync(
    AmazonS3Client s3Client,
    string bucketName)
{
    try
    {
        var request =
            new GetObjectLockConfigurationRequest
            {
                BucketName = bucketName
            };

        return await s3Client.GetObjectLockConfigurationAsync(request);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
오브젝트 업로드 !!! tip "알아두기" 파트 오브젝트의 개수는 업로드할 오브젝트의 용량과 설정한 파트 크기에 따라 결정됩니다. 기본 파트 크기는 5MiB이고, 최소 5MiB부터 지정할 수 있습니다. 파트 오브젝트의 최대 개수는 10,000개입니다.
private static async Task UploadObjectAsync(
    AmazonS3Client s3Client,
    string bucketName,
    string keyName,
    string filePath,
    int partSize)
{
    try
    {
        TransferUtility uploader = new TransferUtility(s3Client);
        TransferUtilityUploadRequest uploadRequest = new TransferUtilityUploadRequest()
        {
            FilePath = filePath,
            BucketName = bucketName,
            Key = keyName,
            PartSize = partSize
        };
        uploader.Upload(uploadRequest);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
오브젝트 다운로드
static async Task ReadObjectDataAsync(
    AmazonS3Client s3Client,
    string bucketName,
    string keyName,
    string filePath)
{
    try
    {
        GetObjectRequest request =
            new GetObjectRequest
            {
                BucketName = bucketName,
                Key = keyName
            };

        ResponseHeaderOverrides responseHeaders =
            new ResponseHeaderOverrides();
        responseHeaders.CacheControl = "No-cache";

        request.ResponseHeaderOverrides = responseHeaders;
        var appendToFile = false;

        using (var response = await s3Client.GetObjectAsync(request))
        await response.WriteResponseStreamToFileAsync(
            filePath, appendToFile, CancellationToken.None);
    }
    catch (AmazonS3Exception e)
    {
       throw e;
    }
}
오브젝트 삭제
static async Task<DeleteObjectResponse> DeleteObjectNonVersionedBucketAsync(
    AmazonS3Client s3Client,
    string bucketName,
    string keyName)
{
    try
    {
        var deleteObjectRequest =
            new DeleteObjectRequest
            {
                BucketName = bucketName,
                Key = keyName
            };

        return await s3Client.DeleteObjectAsync(deleteObjectRequest);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}
서명된 URL 생성
static string GeneratePresignedUrl(
    AmazonS3Client s3Client,
    string bucketName,
    string keyName,
    double durationHours)
{
    try
    {
        var request =
            new GetPreSignedUrlRequest
            {
                BucketName = bucketName,
                Key = keyName,
                Verb = HttpVerb.GET,                 // 업로드용은 HttpVerb.PUT
                Expires = DateTime.UtcNow.AddHours(durationHours)
            };

        return s3Client.GetPreSignedURL(request);
    }
    catch (AmazonS3Exception e)
    {
        throw e;
    }
}

도메인 스타일 엔드포인트 사용

AWS SDK에서 도메인 스타일 엔드포인트를 사용하려면 클라이언트 설정에서 경로 스타일 접근을 비활성화합니다. 엔드포인트 URL과 자격 증명은 기존과 동일하게 사용하며, SDK가 버킷 이름을 서브 도메인으로 조합해 요청을 보냅니다.

Boto3 - Python SDK botocore.client.Config의 s3.addressing_style 값을 virtual로 지정해 클라이언트를 생성합니다.
from boto3 import client
from botocore.client import Config


class Boto3Example(object):
    _REGION = '{region name}'
    _ENDPOINT = '{endpoint}'
    _ACCESS = '{access}'
    _SECRET = '{secret}'

    def __init__(self):
        config = Config(s3={'addressing_style': 'virtual'})
        self.s3 = client(service_name='s3',
                         region_name=self._REGION,
                         endpoint_url=self._ENDPOINT,
                         aws_access_key_id=self._ACCESS,
                         aws_secret_access_key=self._SECRET,
                         config=config)
Java SDK 클라이언트 빌더에서 enablePathStyleAccess() 호출을 제거합니다.
public AwsSdkExample() {
    BasicAWSCredentials awsCredentials =
        new BasicAWSCredentials(access, secret);
    s3Client = AmazonS3ClientBuilder.standard()
        .withEndpointConfiguration(
            new AwsClientBuilder.EndpointConfiguration(endpoint, region)
        )
        .withCredentials(
            new AWSStaticCredentialsProvider(awsCredentials)
        )
        .disableChunkedEncoding()
        .build();
}
.NET SDK AmazonS3Config에서 ForcePathStyle 속성 설정을 제거합니다.
private static AmazonS3Client GetS3Client()
{
    var amazonS3Config =
        new AmazonS3Config
        {
            ServiceURL = endpoint,
            AuthenticationRegion = regionName,
        };
    var basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);

    return new AmazonS3Client(basicAWSCredentials, amazonS3Config);
}

주의

버킷 이름에 점(.)이 포함되어 있으면 도메인 스타일 사용 시 와일드카드 SSL 인증서의 유효 범위를 벗어나 인증서 검증에 실패할 수 있습니다. 이때는 경로 스타일을 사용하세요.

TOP