본문으로 바로가기

게임 : http://s3game-level1.s3-website.us-east-2.amazonaws.com/

풀이 : https://dev.to/rrampage/level-up-your-s3-skills-by-playing-this-game-23a8

aws cli 세팅 : darrengwon.tistory.com/83

 

s3 관련 aws cli command는 다음과 같은 것들이 있습니다.

 

* 요약

 

[s3 관련 지식]

- http://<bucket-name>.s3-website.<Region>.amazonaws.com/<object-id>

- s3 object는 데이터, 키 값(이름), 메타데이터로 구성되어 있다.

- 버킷 정책을 통해 접근 권한을 세팅할 수 있다.

- 메타데이터는 immutable하다. 메타데이터를 수정하는 것은 실은 객체를 덮어쓰는 것이다. 반면 tag는 별도로 관리된다.

- 메타데이터와 http 헤더를 구분하기 위해서 메타데이터에는 x-amz-meta- 접두사가 붙는다.

- 버저닝이 가능하며, 과거 버전의 객체를 가져올 수도 있습니다. 이를 위해서 버저닝 기능을 활성화해야 합니다.

- 기본적으로 객체는 비공개화되어 있다. 아예 퍼블릭으로 열어버릴 수도 있지만 presigned URL을 생성하여 제한된 시간 내에 공개하자.

- 보통 S3에 저장한 내용은 CloudFront로 캐싱되어 배포됩니다. 유저들은 S3 URL에 직접 접근해서는 안됩니다. 따라서 public access를 막아놓고, 대신 CloudFront URL을 통해 접근할 수 있도록 해야 합니다.

- 보안을 위해 특정 referer만 접근을 허용하게 만들 수 있습니다.

 

 

[명령어 요약]

# 해당 프로파일의 모든 버킷명을 출력합니다.

- aws s3 ls

 

# 버킷의 특정 객체를 로컬에 복사합니다. 로컬, 객체 간의 저장도 언제든지 가능합니다.

- aws s3 cp s3://<bucket>/<fileName> [저장하고 싶은 로컬 경로]

 

# 버킷의 객체를 모두 불러옵니다.

- aws s3api list-objects-v2 --bucket [name]

 

# 객체의 메타데이터를 불러옵니다.

- aws s3api head-object  --bucket [name] -key [fileName]

 

# 객체의 태그를 불러옵니다.

- aws s3api get-object-tagging --bucket [name] --key [fileName]

 

# 해당 버킷이 버저닝을 사용하는지 체크합니다.

- aws s3api get-bucket-versioning --bucket [name]

 

# 버킷의 버저닝된 객체 리스트를 출력합니다.

- aws s3api list-object-versions --bucket [name]

 

# 특정 객체를 가져옵니다.

- aws s3api get-object --bucket [name] --key [fileName] --version-id [version id] [outfileName]

 

# sql문을 이용하여 특정 조건을 만족하는 객체를 가져옵니다.

- aws s3api select-object-content [생략... 너무 깁니다. 여튼 sql 구문으로 객체 filter 가능]

 

# 특정 객체에 대한 Presigned URL을 생성합니다.
- aws s3 presign s3://<bucket>/<fileName> --expires-in <원하는 시간 ms>

 

 

 

 

* S3가 서비스하는 정적 웹 페이지의 주소를 통해 버켓의 이름, 리전을 알아낼 수 있습니다.

Website endpoint format is:

http://<bucket-name>.s3-website.<Region>.amazonaws.com/<object-id>

 

* aws s3 ls

https://docs.aws.amazon.com/cli/latest/reference/s3/ls.html

버킷을 조회합니다. 특정 버켓만 조회할 수도 있고, 버켓을 특정하지 않으면 전체 버킷 리스트를 불러옵니다.

  ls
<S3Uri> or NONE
[--recursive]
[--page-size <value>]
[--human-readable]
[--summarize]
[--request-payer <value>]
aws s3 ls // 해당 계정 내의 s3 버킷 리스트 조회
aws s3 ls s3://mybucket // 특정 버킷만 조회
aws s3 ls s3://mybucket --recursive // 폴더 내 파일도 출력함
aws s3 ls s3://mybucket --recursive --human-readable --summarize

 

* aws s3 cp

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/cp.html

aws s3 cp [다운로드 대상 경로] [저장하고 싶은 경로]

 

로컬에서 버킷, 버킷에서 로컬, 버킷에서 버킷 모두 가능합니다. (물론 s3의 정책이 이를 허락해야 합니다)

aws s3 cp test.txt s3://mybucket/test2.txt # 로컬 파일을 버켓에 복사합니다.
aws s3 cp test.txt s3://mybucket/test2.txt --expires 2014-10-01T20:30:00Z # 만료일 설정
aws s3 cp s3://mybucket . --recursive # 디렉토리 내부 파일까지 통째로 복사합니다.

 

* 버킷 정책 (bucket policy)

 

s3 버킷은 각 객체 혹은 버킷 전체에 대한 정책을 설정할 수 있습니다. list 명령을 막아 놓은 버켓에 접근하려는 경우 아래와 같은 경고문구를 확인할 수 있습니다.

 

S3의 권한을 설정하는 방법은 S3 ACL버킷 정책이 있습니다.

ACL은 레거시 시스템이고, bucket policy(버킷 정책) 사용할 것을 권장하고 있습니다.

 

ACL 레거시 시스템은 다음과 같은 꼴로 이루어져 있습니다.

"Grants": [
    {
        "Grantee": {
            "Type": "Group",
            "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
        },
        "Permission": "READ"
    }
]

 

버킷 정책은 console 환경에서는 다음과 같이 접근할 수 있습니다.

 

 

 

* S3의 메타데이터는 무엇인가

 

각 Amazon S3 객체는 데이터, 메타데이터로 구성됩니다. 

 

데이터는 말 그대로 객체가 가지고 있는 내용입니다.

객체 키(또는 키 이름)는 버킷 내 객체를 고유하게 식별합니다. 쉽게 말해 '이름'이라는 것이죠.

객체 메타데이터이름-값 페어의 집합입니다. 객체를 업로드할 때 객체 메타데이터를 설정할 수 있습니다. 객체를 업로드한 후에는 객체 메타데이터를 변경할 수 없습니다.

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

 

공식 문서의 설명에 따르자면 이러한 메타 데이터에는 유저가 정의한 메타데이터도 넣을 수 있는데 다른 http 헤더와 구분하기 위해서 반드시 'x-amz-meta'로 시작해야 한다네요.

Uploading a new object, you can specify user-defined metadata. This optional information is a key-value pair.
To distinguish metadata from other HTTP headers, it must begin with "x-amz-meta-".

 

key-value pair인 정보에서 헤더가 x-amz-meta- 로 시작하면 S3 고유의 메타데이터라는 말이기도 합니다.

공식 문서를 살펴보니 메타데이터에는 다음과 같은 값이 들어간다고 합니다.

과연 S3의 속성에 들어가서 메타데이터 부분을 살펴보니 추가하는 부분에서 이를 확인할 수 있었습니다.

(https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/user-guide/add-object-metadata.html)

 

 

 

* s3api, s3control, s3outposts

 

aws s3와 s3api 등의 차이는 s3가 s3api의 명령어를 좀 더 추상화하여 쉽게 사용할 수 있게끔 만든 것 정도로 알아두면 될 것 같습니다.

즉, s3api의 복잡한 명령어를 s3로 단순화한 것입니다.

 

자세한 설명은 다음과 같습니다.

(https://aws.amazon.com/ko/blogs/developer/leveraging-the-s3-and-s3api-commands/#:~:text=The%20main%20difference%20between%20the,provided%20by%20the%20s3api%20commands.)

 

* aws s3api list-objects --bucket [name]

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-objects.html

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-objects-v2.html

 

Returns some or all (up to 1,000) of the objects in a bucket.

특정 버킷의 모든 객체들을 출력하는, 단순 출력문입니다. 로직에 대한 개선이 이루어졌는지 v2 사용을 권장하네요.

// 예전 버전
aws s3api list-objects --bucket [name]

// 최근 버전
aws s3api list-objects-v2 --bucket [name]

 

 

 

* aws s3api head-object  --bucket [name] -key [fileName]

https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html

S3 객체의 메타데이터는 어떻게 얻어볼 수 있을까요. s3api의 head-object 명령어를 통해 가능 합니다.

aws s3api head-object --bucket [버킷 이름] --key [파일]

 

출력된 메타데이타는 다음과 같이 생겼습니다.

출력된 값에 대한 설명은 위에 첨부한 문서에 자세히 설명되어 있습니다!

 

 

 

aws s3api get-object-tagging --bucket [name] --key [filename]

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object-tagging.html

 

 

각 객체에 붙어 있는 메타데이터는 생성될 때 붙일 수 있지만 수정할 수는 없습니다. (immutable) 객체의 메타데이터를 수정한다는 것은 사실상 해당 객체를 덮어쓰는 작업을 하는 것입니다. 반면에 tags는 별도의 리소스로 객체 그 자체를 덮어쓰거나 수정하지 않은채 관리할 수 있습니다.

Object in S3, including its metadata, is immutable. When you edit object's metadata, you are actually overwriting the object with a copy of itself, with its metadata modified. In contrast, tags are subresources. They are managed separately and can be modified without modifying the object itself.

 

s3api get-object-tagging 명령어를 통해 출력한 태그는 다음과 같은 값을 가집니다.

 

 

 

* aws s3api get-bucket-versioning --bucket [name], aws s3api list-object-versions --bucket [name]

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-bucket-versioning.html

awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/list-object-versions.html

 

같은 버킷 내에 같은 객체라도 여러 버전이 존재할 수 있습니다. git 처럼 버저닝이 가능하다는 것입니다. 버킷에 버저닝을 기능을 활성화하면 s3는 자동으로 각 객체에 유니크한 version ID를 생성합니다. 즉, 한 버킷 내에 같은 이름(key)를 가진 객체는 존재할 수 있어도 version ID가 같을 수는 없습니다.

S3 versioning keeps multiple variants of an object in the same bucket. If you enable versioning for a bucket, S3 automatically generates a unique version ID for the object being stored. In one bucket you can have two objects with the same key, but different version IDs.

 

// Returns metadata about all versions of the objects in a bucket. 
aws s3api list-object-versions --bucket [name]
aws s3api get-bucket-versioning --bucket [name] // 해당 버킷이 버저닝을 사용합니까?

 

list-object-versions 명령어는 다음과 같은 꼴의 출력물을 냅니다.

 

{
    "DeleteMarkers": [
        {
            "IsLatest": true,
            "VersionId": "EtCsdZVg383Pj4qEB9XzjPKwMWMMd_d8",
            "Key": "treasure5_is_deleted",
            "LastModified": "2020-05-02T08:20:38.000Z"
        }
    ],
    "Versions": [
        {
            "LastModified": "2020-05-02T08:35:32.000Z",
            "VersionId": "4mtBa02BZXl0VmlqgATEHowXt8tZXG0U",
            "ETag": "\"e3545f5babf2f5ca5a9d20f7475f80ab\"",
            "StorageClass": "STANDARD",
            "Key": "level5-hint2.html",
            "IsLatest": true,
            "Size": 2005
        },
        {
            "LastModified": "2020-05-02T08:35:32.000Z",
            "VersionId": "L_ItpNnJP4JdD6Un1PgnN0xh0FRMlMlo",
            "ETag": "\"065243c07c0def3a89cd4cecbfc541be\"",
            "StorageClass": "STANDARD",
            "Key": "level5-hint3.html",
            "IsLatest": true,
            "Size": 2802
        },
        {
            "LastModified": "2020-04-20T11:08:44.000Z",
            "VersionId": "IUn.kO1XCAfz12qPwiRG54US2pnAIddI",
            "ETag": "\"d1c7352e9fd72245033351307a9f9600\"",
            "StorageClass": "STANDARD",
            "Key": "level5-hint4.html",
            "IsLatest": true,
            "Size": 1698
        },
        {
            "LastModified": "2020-04-20T11:04:58.000Z",
            "VersionId": "ArJDlk1MizLIM0r4f6_EjOUaJkN.6HtN",
            "ETag": "\"4b546131739176fef59000341bf03b37\"",
            "StorageClass": "STANDARD",
            "Key": "level5.html",
            "IsLatest": true,
            "Size": 1648
        },
        {
            "LastModified": "2020-05-02T08:20:06.000Z",
            "VersionId": "344PQOyFqocF0TI66MbLynNNdQqHfBz3",
            "ETag": "\"9693f24274d7ec88a8563d662c34be99\"",
            "StorageClass": "STANDARD",
            "Key": "treasure5_is_deleted",
            "IsLatest": false,
            "Size": 126
        }
    ]
}

 

treasure5에 DeletedMark가 찍힌 걸로 봐서 우리가 조회한 버전에서는 지워졌군요 (아직 완전히 지워진 건 아닙니다)

 

 

* aws s3api get-object --bucket [name] --key [filename] --version-id [version id] [outfileName]

(https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/get-object.html)

 

Retrieves objects from Amazon S3. 쉽게 말해 객체를 가져옵니다.

 

특정한 버전의 객체를 보기 위해서는 get-object에서 --version-id 옵션을 이용하면 됩니다.

version ID는 앞서 list-object-versions 명령어를 통해 가져온 바 있습니다.

outfileName은, 받은 객체를 어떤 이름으로 저장할 것인지를 말합니다.

 

긴 명령어를 통해 객체는 저장되고, 객체의 메타데이터를 출력합니다.

 

 

* aws s3api select-object-content [생략... 너무 깁니다. 여튼 sql 구문으로 객체 filter 가능]

 

버킷이 커지면 모든 객체를 불러오는 등의 작업을 하는데 소요되는 시간과 비용이 늘어나게 됩니다.

큰 버킷에 list-objects-v2 명령어를 실행하면 최대 1000개까지의 객체만 출력합니다.

Returns some or all (up to 1,000) of the objects in a bucket.

 

때문에 원하는 내용만 가져오는 방법이 필요합니다. S3 Select는 SQL 문을 기반으로 Amazon S3 객체의 콘텐츠를 필터링합니다. 

이 S3 Select 요청에는 받기 원하는 데이터 포맷(JSON, CSV, or Apache Parquet)을 지정해야 합니다. 

 

aws s3api select-object-content
  --bucket [name]
  --key [fileName]
  --expression <value>
  --expression-type <value>
  --input-serialization <value>
  --output-serialization <value>
  [outfileName]
aws s3api select-object-content
  --bucket [name]
  --key s3select.csv.gz
  --expression "SELECT s.Answer FROM s3object s WHERE Category = 'TREASURE'"
  --expression-type sql
  --input-serialization '{"CSV": {"FileHeaderInfo": "USE", "FieldDelimiter": ";"}, "CompressionType": "GZIP"}'
  --output-serialization '{"CSV": {}}'
  [outfileName]

 

 

* aws s3 presign s3://<bucket>/<fileName> --expires-in 604800

 

docs.aws.amazon.com/cli/latest/reference/s3/presign.html

 

기본적으로 모든 객체는 비공개(private) 입니다. 해당 객체의 주인만이 액세스할 수 있습니다. 그러나 presigned URL(서명된 URL)을 통해 일정 시간 동안 객체를 다른 사람에게 공개하여 다운로드하게 할 수 있습니다. presigned URL을 가진 모든 사람이 접근할 수 있게 됩니다.

All objects by default are private. Only the object owner has permission to access them. However, the object owner can optionally share objects with others by creating a presigned URL to grant time-limited permission to download the objects. Anyone who receives the presigned URL can then access the object.

* Presigned URLs are valid only for the specified duration.
aws s3 presign s3://<BUCKET>/<OBJECT> --expires-in 3600

 

명령의 결과로 서명된 URL이 반환됩니다.

presigned URL의 예시 누르면 다운로드 됩니다.

 

 

 

 

 

'AWS > ☁️ AWS CLI' 카테고리의 다른 글

[AWS CLI] 설치 및 profile configuration (Linux, Window)  (0) 2021.02.16

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체